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