75 lines
2.1 KiB
Plaintext
75 lines
2.1 KiB
Plaintext
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
|
|
|
#include <metal_stdlib>
|
|
#include <simd/simd.h>
|
|
|
|
using namespace metal;
|
|
|
|
template<typename T> struct spvRemoveReference { typedef T type; };
|
|
template<typename T> struct spvRemoveReference<thread T&> { typedef T type; };
|
|
template<typename T> struct spvRemoveReference<thread T&&> { typedef T type; };
|
|
template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type& x)
|
|
{
|
|
return static_cast<thread T&&>(x);
|
|
}
|
|
template<typename T> inline constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type&& x)
|
|
{
|
|
return static_cast<thread T&&>(x);
|
|
}
|
|
|
|
enum class spvSwizzle : uint
|
|
{
|
|
none = 0,
|
|
zero,
|
|
one,
|
|
red,
|
|
green,
|
|
blue,
|
|
alpha
|
|
};
|
|
|
|
template<typename T>
|
|
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
|
{
|
|
switch (s)
|
|
{
|
|
case spvSwizzle::none:
|
|
return c;
|
|
case spvSwizzle::zero:
|
|
return 0;
|
|
case spvSwizzle::one:
|
|
return 1;
|
|
case spvSwizzle::red:
|
|
return x.r;
|
|
case spvSwizzle::green:
|
|
return x.g;
|
|
case spvSwizzle::blue:
|
|
return x.b;
|
|
case spvSwizzle::alpha:
|
|
return x.a;
|
|
}
|
|
}
|
|
|
|
// Wrapper function that swizzles texture samples and fetches.
|
|
template<typename T>
|
|
inline vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s)
|
|
{
|
|
if (!s)
|
|
return x;
|
|
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)));
|
|
}
|
|
|
|
template<typename T>
|
|
inline T spvTextureSwizzle(T x, uint s)
|
|
{
|
|
return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x;
|
|
}
|
|
|
|
kernel void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
|
|
{
|
|
constant uint& fooSwzl = spvSwizzleConstants[0];
|
|
float4 a = spvTextureSwizzle(foo.sample(fooSmplr, float2(1.0), level(0.0)), fooSwzl);
|
|
bar.write(a, uint2(int2(0)));
|
|
}
|
|
|