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