1#pragma clang diagnostic ignored "-Wmissing-prototypes" 2 3#include <metal_stdlib> 4#include <simd/simd.h> 5 6using namespace metal; 7 8struct main0_out 9{ 10 float4 fragColor [[color(0)]]; 11}; 12 13// Returns 2D texture coords corresponding to 1D texel buffer coords 14static inline __attribute__((always_inline)) 15uint2 spvTexelBufferCoord(uint tc) 16{ 17 return uint2(tc % 4096, tc / 4096); 18} 19 20template<typename T> struct spvRemoveReference { typedef T type; }; 21template<typename T> struct spvRemoveReference<thread T&> { typedef T type; }; 22template<typename T> struct spvRemoveReference<thread T&&> { typedef T type; }; 23template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type& x) 24{ 25 return static_cast<thread T&&>(x); 26} 27template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type&& x) 28{ 29 return static_cast<thread T&&>(x); 30} 31 32enum class spvSwizzle : uint 33{ 34 none = 0, 35 zero, 36 one, 37 red, 38 green, 39 blue, 40 alpha 41}; 42 43template<typename T> 44inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s) 45{ 46 switch (s) 47 { 48 case spvSwizzle::none: 49 return c; 50 case spvSwizzle::zero: 51 return 0; 52 case spvSwizzle::one: 53 return 1; 54 case spvSwizzle::red: 55 return x.r; 56 case spvSwizzle::green: 57 return x.g; 58 case spvSwizzle::blue: 59 return x.b; 60 case spvSwizzle::alpha: 61 return x.a; 62 } 63} 64 65// Wrapper function that swizzles texture samples and fetches. 66template<typename T> 67inline vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s) 68{ 69 if (!s) 70 return x; 71 return vec<T, 4>(spvGetSwizzle(x, x.r, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, x.g, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, x.b, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, x.a, spvSwizzle((s >> 24) & 0xFF))); 72} 73 74template<typename T> 75inline T spvTextureSwizzle(T x, uint s) 76{ 77 return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x; 78} 79 80// Wrapper function that swizzles texture gathers. 81template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts> 82inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c) 83{ 84 if (sw) 85 { 86 switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF)) 87 { 88 case spvSwizzle::none: 89 break; 90 case spvSwizzle::zero: 91 return vec<T, 4>(0, 0, 0, 0); 92 case spvSwizzle::one: 93 return vec<T, 4>(1, 1, 1, 1); 94 case spvSwizzle::red: 95 return t.gather(s, spvForward<Ts>(params)..., component::x); 96 case spvSwizzle::green: 97 return t.gather(s, spvForward<Ts>(params)..., component::y); 98 case spvSwizzle::blue: 99 return t.gather(s, spvForward<Ts>(params)..., component::z); 100 case spvSwizzle::alpha: 101 return t.gather(s, spvForward<Ts>(params)..., component::w); 102 } 103 } 104 switch (c) 105 { 106 case component::x: 107 return t.gather(s, spvForward<Ts>(params)..., component::x); 108 case component::y: 109 return t.gather(s, spvForward<Ts>(params)..., component::y); 110 case component::z: 111 return t.gather(s, spvForward<Ts>(params)..., component::z); 112 case component::w: 113 return t.gather(s, spvForward<Ts>(params)..., component::w); 114 } 115} 116 117// Wrapper function that swizzles depth texture gathers. 118template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts> 119inline vec<T, 4> spvGatherCompareSwizzle(const thread Tex<T>& t, sampler s, uint sw, Ts... params) 120{ 121 if (sw) 122 { 123 switch (spvSwizzle(sw & 0xFF)) 124 { 125 case spvSwizzle::none: 126 case spvSwizzle::red: 127 break; 128 case spvSwizzle::zero: 129 case spvSwizzle::green: 130 case spvSwizzle::blue: 131 case spvSwizzle::alpha: 132 return vec<T, 4>(0, 0, 0, 0); 133 case spvSwizzle::one: 134 return vec<T, 4>(1, 1, 1, 1); 135 } 136 } 137 return t.gather_compare(s, spvForward<Ts>(params)...); 138} 139 140static inline __attribute__((always_inline)) 141float4 do_samples(thread const texture1d<float> t1, thread const sampler t1Smplr, constant uint& t1Swzl, thread const texture2d<float> t2, constant uint& t2Swzl, thread const texture3d<float> t3, thread const sampler t3Smplr, constant uint& t3Swzl, thread const texturecube<float> tc, constant uint& tcSwzl, thread const texture2d_array<float> t2a, thread const sampler t2aSmplr, constant uint& t2aSwzl, thread const texturecube_array<float> tca, thread const sampler tcaSmplr, constant uint& tcaSwzl, thread const texture2d<float> tb, thread const depth2d<float> d2, thread const sampler d2Smplr, constant uint& d2Swzl, thread const depthcube<float> dc, thread const sampler dcSmplr, constant uint& dcSwzl, thread const depth2d_array<float> d2a, constant uint& d2aSwzl, thread const depthcube_array<float> dca, thread const sampler dcaSmplr, constant uint& dcaSwzl, thread sampler defaultSampler, thread sampler shadowSampler) 142{ 143 float4 c = spvTextureSwizzle(t1.sample(t1Smplr, 0.0), t1Swzl); 144 c = spvTextureSwizzle(t2.sample(defaultSampler, float2(0.0)), t2Swzl); 145 c = spvTextureSwizzle(t3.sample(t3Smplr, float3(0.0)), t3Swzl); 146 c = spvTextureSwizzle(tc.sample(defaultSampler, float3(0.0)), tcSwzl); 147 c = spvTextureSwizzle(t2a.sample(t2aSmplr, float3(0.0).xy, uint(round(float3(0.0).z))), t2aSwzl); 148 c = spvTextureSwizzle(tca.sample(tcaSmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), tcaSwzl); 149 c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), d2Swzl); 150 c.x = spvTextureSwizzle(dc.sample_compare(dcSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz, float4(0.0, 0.0, 0.0, 1.0).w), dcSwzl); 151 c.x = spvTextureSwizzle(d2a.sample_compare(shadowSampler, float4(0.0, 0.0, 0.0, 1.0).xy, uint(round(float4(0.0, 0.0, 0.0, 1.0).z)), float4(0.0, 0.0, 0.0, 1.0).w), d2aSwzl); 152 c.x = spvTextureSwizzle(dca.sample_compare(dcaSmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), dcaSwzl); 153 c = spvTextureSwizzle(t1.sample(t1Smplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), t1Swzl); 154 c = spvTextureSwizzle(t2.sample(defaultSampler, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), t2Swzl); 155 c = spvTextureSwizzle(t3.sample(t3Smplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), t3Swzl); 156 float4 _119 = float4(0.0, 0.0, 1.0, 1.0); 157 _119.z = float4(0.0, 0.0, 1.0, 1.0).w; 158 c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, _119.xy / _119.z, float4(0.0, 0.0, 1.0, 1.0).z / _119.z), d2Swzl); 159 c = spvTextureSwizzle(t1.sample(t1Smplr, 0.0), t1Swzl); 160 c = spvTextureSwizzle(t2.sample(defaultSampler, float2(0.0), level(0.0)), t2Swzl); 161 c = spvTextureSwizzle(t3.sample(t3Smplr, float3(0.0), level(0.0)), t3Swzl); 162 c = spvTextureSwizzle(tc.sample(defaultSampler, float3(0.0), level(0.0)), tcSwzl); 163 c = spvTextureSwizzle(t2a.sample(t2aSmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), t2aSwzl); 164 c = spvTextureSwizzle(tca.sample(tcaSmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), tcaSwzl); 165 c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z, level(0.0)), d2Swzl); 166 c = spvTextureSwizzle(t1.sample(t1Smplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), t1Swzl); 167 c = spvTextureSwizzle(t2.sample(defaultSampler, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), t2Swzl); 168 c = spvTextureSwizzle(t3.sample(t3Smplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w, level(0.0)), t3Swzl); 169 float4 _153 = float4(0.0, 0.0, 1.0, 1.0); 170 _153.z = float4(0.0, 0.0, 1.0, 1.0).w; 171 c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, _153.xy / _153.z, float4(0.0, 0.0, 1.0, 1.0).z / _153.z, level(0.0)), d2Swzl); 172 c = spvTextureSwizzle(t1.read(uint(0)), t1Swzl); 173 c = spvTextureSwizzle(t2.read(uint2(int2(0)), 0), t2Swzl); 174 c = spvTextureSwizzle(t3.read(uint3(int3(0)), 0), t3Swzl); 175 c = spvTextureSwizzle(t2a.read(uint2(int3(0).xy), uint(int3(0).z), 0), t2aSwzl); 176 c = tb.read(spvTexelBufferCoord(0)); 177 c = spvGatherSwizzle(t2, defaultSampler, t2Swzl, component::x, float2(0.0), int2(0)); 178 c = spvGatherSwizzle(tc, defaultSampler, tcSwzl, component::y, float3(0.0)); 179 c = spvGatherSwizzle(t2a, t2aSmplr, t2aSwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0)); 180 c = spvGatherSwizzle(tca, tcaSmplr, tcaSwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w))); 181 c = spvGatherCompareSwizzle(d2, d2Smplr, d2Swzl, float2(0.0), 1.0); 182 c = spvGatherCompareSwizzle(dc, dcSmplr, dcSwzl, float3(0.0), 1.0); 183 c = spvGatherCompareSwizzle(d2a, shadowSampler, d2aSwzl, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0); 184 c = spvGatherCompareSwizzle(dca, dcaSmplr, dcaSwzl, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0); 185 return c; 186} 187 188fragment main0_out main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler defaultSampler [[sampler(0)]], sampler shadowSampler [[sampler(1)]], sampler tex1dSmplr [[sampler(2)]], sampler tex3dSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(6)]], sampler depthCubeSmplr [[sampler(7)]], sampler depthCubeArraySmplr [[sampler(8)]]) 189{ 190 main0_out out = {}; 191 constant uint& tex1dSwzl = spvSwizzleConstants[0]; 192 constant uint& tex2dSwzl = spvSwizzleConstants[1]; 193 constant uint& tex3dSwzl = spvSwizzleConstants[2]; 194 constant uint& texCubeSwzl = spvSwizzleConstants[3]; 195 constant uint& tex2dArraySwzl = spvSwizzleConstants[4]; 196 constant uint& texCubeArraySwzl = spvSwizzleConstants[5]; 197 constant uint& depth2dSwzl = spvSwizzleConstants[7]; 198 constant uint& depthCubeSwzl = spvSwizzleConstants[8]; 199 constant uint& depth2dArraySwzl = spvSwizzleConstants[9]; 200 constant uint& depthCubeArraySwzl = spvSwizzleConstants[10]; 201 out.fragColor = do_samples(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, texBuffer, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, defaultSampler, shadowSampler); 202 return out; 203} 204 205