• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#pragma clang diagnostic ignored "-Wmissing-prototypes"
2
3#include <metal_stdlib>
4#include <simd/simd.h>
5
6using namespace metal;
7
8template<typename T> struct spvRemoveReference { typedef T type; };
9template<typename T> struct spvRemoveReference<thread T&> { typedef T type; };
10template<typename T> struct spvRemoveReference<thread T&&> { typedef T type; };
11template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type& x)
12{
13    return static_cast<thread T&&>(x);
14}
15template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type&& x)
16{
17    return static_cast<thread T&&>(x);
18}
19
20enum class spvSwizzle : uint
21{
22    none = 0,
23    zero,
24    one,
25    red,
26    green,
27    blue,
28    alpha
29};
30
31template<typename T>
32inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
33{
34    switch (s)
35    {
36        case spvSwizzle::none:
37            return c;
38        case spvSwizzle::zero:
39            return 0;
40        case spvSwizzle::one:
41            return 1;
42        case spvSwizzle::red:
43            return x.r;
44        case spvSwizzle::green:
45            return x.g;
46        case spvSwizzle::blue:
47            return x.b;
48        case spvSwizzle::alpha:
49            return x.a;
50    }
51}
52
53// Wrapper function that swizzles texture samples and fetches.
54template<typename T>
55inline vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s)
56{
57    if (!s)
58        return x;
59    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)));
60}
61
62template<typename T>
63inline T spvTextureSwizzle(T x, uint s)
64{
65    return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x;
66}
67
68kernel void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
69{
70    constant uint& fooSwzl = spvSwizzleConstants[0];
71    float4 a = spvTextureSwizzle(foo.sample(fooSmplr, float2(1.0), level(0.0)), fooSwzl);
72    bar.write(a, uint2(int2(0)));
73}
74
75