2018-09-20 01:36:33 +00:00
|
|
|
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
2019-08-14 15:09:39 +00:00
|
|
|
#pragma clang diagnostic ignored "-Wmissing-braces"
|
|
|
|
#pragma clang diagnostic ignored "-Wunused-variable"
|
2018-09-20 01:36:33 +00:00
|
|
|
|
|
|
|
#include <metal_stdlib>
|
|
|
|
#include <simd/simd.h>
|
2019-08-14 15:09:39 +00:00
|
|
|
|
|
|
|
template <typename T, size_t Num>
|
|
|
|
struct unsafe_array
|
|
|
|
{
|
|
|
|
T __Elements[Num ? Num : 1];
|
|
|
|
|
|
|
|
constexpr size_t size() const thread { return Num; }
|
|
|
|
constexpr size_t max_size() const thread { return Num; }
|
|
|
|
constexpr bool empty() const thread { return Num == 0; }
|
|
|
|
|
|
|
|
constexpr size_t size() const device { return Num; }
|
|
|
|
constexpr size_t max_size() const device { return Num; }
|
|
|
|
constexpr bool empty() const device { return Num == 0; }
|
|
|
|
|
|
|
|
constexpr size_t size() const constant { return Num; }
|
|
|
|
constexpr size_t max_size() const constant { return Num; }
|
|
|
|
constexpr bool empty() const constant { return Num == 0; }
|
|
|
|
|
|
|
|
constexpr size_t size() const threadgroup { return Num; }
|
|
|
|
constexpr size_t max_size() const threadgroup { return Num; }
|
|
|
|
constexpr bool empty() const threadgroup { return Num == 0; }
|
|
|
|
|
|
|
|
thread T &operator[](size_t pos) thread
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
constexpr const thread T &operator[](size_t pos) const thread
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
|
|
|
|
device T &operator[](size_t pos) device
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
constexpr const device T &operator[](size_t pos) const device
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr const constant T &operator[](size_t pos) const constant
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
|
|
|
|
threadgroup T &operator[](size_t pos) threadgroup
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
constexpr const threadgroup T &operator[](size_t pos) const threadgroup
|
|
|
|
{
|
|
|
|
return __Elements[pos];
|
|
|
|
}
|
|
|
|
};
|
2018-09-20 01:36:33 +00:00
|
|
|
|
|
|
|
using namespace metal;
|
|
|
|
|
|
|
|
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
2019-08-14 15:09:39 +00:00
|
|
|
<<<<<<< HEAD
|
2019-08-29 21:39:06 +00:00
|
|
|
inline uint2 spvTexelBufferCoord(uint tc)
|
2019-08-14 15:09:39 +00:00
|
|
|
=======
|
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
uint2 spvTexelBufferCoord(uint tc)
|
|
|
|
>>>>>>> 22755a0c... Update the Metal shaders to account for changes in the shader compilation.
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
return uint2(tc % 4096, tc / 4096);
|
|
|
|
}
|
|
|
|
|
|
|
|
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; };
|
2019-08-14 15:09:39 +00:00
|
|
|
template<typename T> static inline __attribute__((always_inline)) constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type& x)
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
return static_cast<thread T&&>(x);
|
|
|
|
}
|
2019-08-14 15:09:39 +00:00
|
|
|
template<typename T> static inline __attribute__((always_inline)) constexpr thread T&& spvForward(thread typename spvRemoveReference<T>::type&& x)
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
return static_cast<thread T&&>(x);
|
|
|
|
}
|
|
|
|
|
MSL: Add support for sampler Y'CbCr conversion.
This change introduces functions and in one case, a class, to support
the `VK_KHR_sampler_ycbcr_conversion` extension. Except in the case of
GBGR8 and BGRG8 formats, for which Metal natively supports implicit
chroma reconstruction, we're on our own here. We have to do everything
ourselves. Much of the complexity comes from the need to support
multiple planes, which must now be passed to functions that use the
corresponding combined image-samplers. The rest is from the actual
Y'CbCr conversion itself, which requires additional post-processing of
the sample retrieved from the image.
Passing sampled images to a function was a particular problem. To
support this, I've added a new class which is emitted to MSL shaders
that pass sampled images with Y'CbCr conversions attached around. It
can handle sampled images with or without Y'CbCr conversion. This is an
awful abomination that should not exist, but I'm worried that there's
some shader out there which does this. This support requires Metal 2.0
to work properly, because it uses default-constructed texture objects,
which were only added in MSL 2. I'm not even going to get into arrays of
combined image-samplers--that's a whole other can of worms. They are
deliberately unsupported in this change.
I've taken the liberty of refactoring the support for texture swizzling
while I'm at it. It's now treated as a post-processing step similar to
Y'CbCr conversion. I'd like to think this is cleaner than having
everything in `to_function_name()`/`to_function_args()`. It still looks
really hairy, though. I did, however, get rid of the explicit type
arguments to `spvGatherSwizzle()`/`spvGatherCompareSwizzle()`.
Update the C API. In addition to supporting this new functionality, add
some compiler options that I added in previous changes, but for which I
neglected to update the C API.
2019-08-02 20:11:19 +00:00
|
|
|
enum class spvSwizzle : uint
|
|
|
|
{
|
|
|
|
none = 0,
|
|
|
|
zero,
|
|
|
|
one,
|
|
|
|
red,
|
|
|
|
green,
|
|
|
|
blue,
|
|
|
|
alpha
|
|
|
|
};
|
|
|
|
|
2018-09-20 01:36:33 +00:00
|
|
|
template<typename T>
|
2019-08-14 15:09:39 +00:00
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
switch (s)
|
|
|
|
{
|
2019-01-07 17:17:12 +00:00
|
|
|
case spvSwizzle::none:
|
|
|
|
return c;
|
2018-09-20 01:36:33 +00:00
|
|
|
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>
|
2019-08-14 15:09:39 +00:00
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s)
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
if (!s)
|
|
|
|
return x;
|
2019-01-07 17:17:12 +00:00
|
|
|
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)));
|
2018-09-20 01:36:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
2019-08-14 15:09:39 +00:00
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
T spvTextureSwizzle(T x, uint s)
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wrapper function that swizzles texture gathers.
|
2019-08-14 15:09:39 +00:00
|
|
|
<<<<<<< HEAD
|
MSL: Add support for sampler Y'CbCr conversion.
This change introduces functions and in one case, a class, to support
the `VK_KHR_sampler_ycbcr_conversion` extension. Except in the case of
GBGR8 and BGRG8 formats, for which Metal natively supports implicit
chroma reconstruction, we're on our own here. We have to do everything
ourselves. Much of the complexity comes from the need to support
multiple planes, which must now be passed to functions that use the
corresponding combined image-samplers. The rest is from the actual
Y'CbCr conversion itself, which requires additional post-processing of
the sample retrieved from the image.
Passing sampled images to a function was a particular problem. To
support this, I've added a new class which is emitted to MSL shaders
that pass sampled images with Y'CbCr conversions attached around. It
can handle sampled images with or without Y'CbCr conversion. This is an
awful abomination that should not exist, but I'm worried that there's
some shader out there which does this. This support requires Metal 2.0
to work properly, because it uses default-constructed texture objects,
which were only added in MSL 2. I'm not even going to get into arrays of
combined image-samplers--that's a whole other can of worms. They are
deliberately unsupported in this change.
I've taken the liberty of refactoring the support for texture swizzling
while I'm at it. It's now treated as a post-processing step similar to
Y'CbCr conversion. I'd like to think this is cleaner than having
everything in `to_function_name()`/`to_function_args()`. It still looks
really hairy, though. I did, however, get rid of the explicit type
arguments to `spvGatherSwizzle()`/`spvGatherCompareSwizzle()`.
Update the C API. In addition to supporting this new functionality, add
some compiler options that I added in previous changes, but for which I
neglected to update the C API.
2019-08-02 20:11:19 +00:00
|
|
|
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
|
|
|
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
2019-08-14 15:09:39 +00:00
|
|
|
=======
|
|
|
|
template<typename T, typename Tex, typename... Ts>
|
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
vec<T, 4> spvGatherSwizzle(sampler s, thread Tex const& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
|
|
|
>>>>>>> 22755a0c... Update the Metal shaders to account for changes in the shader compilation.
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
if (sw)
|
|
|
|
{
|
2018-09-22 03:50:29 +00:00
|
|
|
switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
|
|
|
case spvSwizzle::none:
|
|
|
|
break;
|
|
|
|
case spvSwizzle::zero:
|
|
|
|
return vec<T, 4>(0, 0, 0, 0);
|
|
|
|
case spvSwizzle::one:
|
|
|
|
return vec<T, 4>(1, 1, 1, 1);
|
|
|
|
case spvSwizzle::red:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::x);
|
|
|
|
case spvSwizzle::green:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::y);
|
|
|
|
case spvSwizzle::blue:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::z);
|
|
|
|
case spvSwizzle::alpha:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (c)
|
|
|
|
{
|
|
|
|
case component::x:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::x);
|
|
|
|
case component::y:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::y);
|
|
|
|
case component::z:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::z);
|
|
|
|
case component::w:
|
|
|
|
return t.gather(s, spvForward<Ts>(params)..., component::w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 14:52:26 +00:00
|
|
|
// Wrapper function that swizzles depth texture gathers.
|
2019-08-14 15:09:39 +00:00
|
|
|
<<<<<<< HEAD
|
MSL: Add support for sampler Y'CbCr conversion.
This change introduces functions and in one case, a class, to support
the `VK_KHR_sampler_ycbcr_conversion` extension. Except in the case of
GBGR8 and BGRG8 formats, for which Metal natively supports implicit
chroma reconstruction, we're on our own here. We have to do everything
ourselves. Much of the complexity comes from the need to support
multiple planes, which must now be passed to functions that use the
corresponding combined image-samplers. The rest is from the actual
Y'CbCr conversion itself, which requires additional post-processing of
the sample retrieved from the image.
Passing sampled images to a function was a particular problem. To
support this, I've added a new class which is emitted to MSL shaders
that pass sampled images with Y'CbCr conversions attached around. It
can handle sampled images with or without Y'CbCr conversion. This is an
awful abomination that should not exist, but I'm worried that there's
some shader out there which does this. This support requires Metal 2.0
to work properly, because it uses default-constructed texture objects,
which were only added in MSL 2. I'm not even going to get into arrays of
combined image-samplers--that's a whole other can of worms. They are
deliberately unsupported in this change.
I've taken the liberty of refactoring the support for texture swizzling
while I'm at it. It's now treated as a post-processing step similar to
Y'CbCr conversion. I'd like to think this is cleaner than having
everything in `to_function_name()`/`to_function_args()`. It still looks
really hairy, though. I did, however, get rid of the explicit type
arguments to `spvGatherSwizzle()`/`spvGatherCompareSwizzle()`.
Update the C API. In addition to supporting this new functionality, add
some compiler options that I added in previous changes, but for which I
neglected to update the C API.
2019-08-02 20:11:19 +00:00
|
|
|
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
|
|
|
inline vec<T, 4> spvGatherCompareSwizzle(const thread Tex<T>& t, sampler s, uint sw, Ts... params)
|
2019-08-14 15:09:39 +00:00
|
|
|
=======
|
|
|
|
template<typename T, typename Tex, typename... Ts>
|
|
|
|
static inline __attribute__((always_inline))
|
|
|
|
vec<T, 4> spvGatherCompareSwizzle(sampler s, thread Tex const& t, Ts... params, uint sw)
|
|
|
|
>>>>>>> 22755a0c... Update the Metal shaders to account for changes in the shader compilation.
|
2018-09-29 14:52:26 +00:00
|
|
|
{
|
|
|
|
if (sw)
|
|
|
|
{
|
|
|
|
switch (spvSwizzle(sw & 0xFF))
|
|
|
|
{
|
|
|
|
case spvSwizzle::none:
|
|
|
|
case spvSwizzle::red:
|
|
|
|
break;
|
|
|
|
case spvSwizzle::zero:
|
|
|
|
case spvSwizzle::green:
|
|
|
|
case spvSwizzle::blue:
|
|
|
|
case spvSwizzle::alpha:
|
|
|
|
return vec<T, 4>(0, 0, 0, 0);
|
|
|
|
case spvSwizzle::one:
|
|
|
|
return vec<T, 4>(1, 1, 1, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return t.gather_compare(s, spvForward<Ts>(params)...);
|
|
|
|
}
|
|
|
|
|
2019-06-21 10:44:33 +00:00
|
|
|
fragment void 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)]], depth2d<float> depth2d [[texture(6)]], depthcube<float> depthCube [[texture(7)]], depth2d_array<float> depth2dArray [[texture(8)]], depthcube_array<float> depthCubeArray [[texture(9)]], texture2d<float> texBuffer [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(6)]], sampler depthCubeSmplr [[sampler(7)]], sampler depth2dArraySmplr [[sampler(8)]], sampler depthCubeArraySmplr [[sampler(9)]])
|
2018-09-20 01:36:33 +00:00
|
|
|
{
|
2019-05-27 09:59:29 +00:00
|
|
|
constant uint& tex1dSwzl = spvSwizzleConstants[0];
|
|
|
|
constant uint& tex2dSwzl = spvSwizzleConstants[1];
|
|
|
|
constant uint& tex3dSwzl = spvSwizzleConstants[2];
|
|
|
|
constant uint& texCubeSwzl = spvSwizzleConstants[3];
|
|
|
|
constant uint& tex2dArraySwzl = spvSwizzleConstants[4];
|
|
|
|
constant uint& texCubeArraySwzl = spvSwizzleConstants[5];
|
2019-06-21 10:44:33 +00:00
|
|
|
constant uint& depth2dSwzl = spvSwizzleConstants[6];
|
|
|
|
constant uint& depthCubeSwzl = spvSwizzleConstants[7];
|
|
|
|
constant uint& depth2dArraySwzl = spvSwizzleConstants[8];
|
|
|
|
constant uint& depthCubeArraySwzl = spvSwizzleConstants[9];
|
2019-01-13 23:31:50 +00:00
|
|
|
float4 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl);
|
|
|
|
c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), texCubeSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), tex2dArraySwzl);
|
|
|
|
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), texCubeArraySwzl);
|
|
|
|
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), depth2dSwzl);
|
|
|
|
c.x = spvTextureSwizzle(depthCube.sample_compare(depthCubeSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz, float4(0.0, 0.0, 0.0, 1.0).w), depthCubeSwzl);
|
|
|
|
c.x = spvTextureSwizzle(depth2dArray.sample_compare(depth2dArraySmplr, 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), depth2dArraySwzl);
|
|
|
|
c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), depthCubeArraySwzl);
|
|
|
|
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), tex2dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), tex3dSwzl);
|
2018-09-20 01:36:33 +00:00
|
|
|
float4 _100 = float4(0.0, 0.0, 1.0, 1.0);
|
|
|
|
_100.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
2019-01-28 08:39:45 +00:00
|
|
|
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _100.xy / _100.z, float4(0.0, 0.0, 1.0, 1.0).z / _100.z), depth2dSwzl);
|
2019-01-13 23:31:50 +00:00
|
|
|
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), tex2dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), tex3dSwzl);
|
|
|
|
c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), texCubeSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), tex2dArraySwzl);
|
|
|
|
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), texCubeArraySwzl);
|
|
|
|
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z, level(0.0)), depth2dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), tex2dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w, level(0.0)), tex3dSwzl);
|
2018-09-20 01:36:33 +00:00
|
|
|
float4 _128 = float4(0.0, 0.0, 1.0, 1.0);
|
|
|
|
_128.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
2019-01-28 08:39:45 +00:00
|
|
|
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _128.xy / _128.z, float4(0.0, 0.0, 1.0, 1.0).z / _128.z, level(0.0)), depth2dSwzl);
|
2019-01-13 23:31:50 +00:00
|
|
|
c = spvTextureSwizzle(tex1d.read(uint(0)), tex1dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), tex2dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl);
|
|
|
|
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl);
|
2018-09-20 01:36:33 +00:00
|
|
|
c = texBuffer.read(spvTexelBufferCoord(0));
|
MSL: Add support for sampler Y'CbCr conversion.
This change introduces functions and in one case, a class, to support
the `VK_KHR_sampler_ycbcr_conversion` extension. Except in the case of
GBGR8 and BGRG8 formats, for which Metal natively supports implicit
chroma reconstruction, we're on our own here. We have to do everything
ourselves. Much of the complexity comes from the need to support
multiple planes, which must now be passed to functions that use the
corresponding combined image-samplers. The rest is from the actual
Y'CbCr conversion itself, which requires additional post-processing of
the sample retrieved from the image.
Passing sampled images to a function was a particular problem. To
support this, I've added a new class which is emitted to MSL shaders
that pass sampled images with Y'CbCr conversions attached around. It
can handle sampled images with or without Y'CbCr conversion. This is an
awful abomination that should not exist, but I'm worried that there's
some shader out there which does this. This support requires Metal 2.0
to work properly, because it uses default-constructed texture objects,
which were only added in MSL 2. I'm not even going to get into arrays of
combined image-samplers--that's a whole other can of worms. They are
deliberately unsupported in this change.
I've taken the liberty of refactoring the support for texture swizzling
while I'm at it. It's now treated as a post-processing step similar to
Y'CbCr conversion. I'd like to think this is cleaner than having
everything in `to_function_name()`/`to_function_args()`. It still looks
really hairy, though. I did, however, get rid of the explicit type
arguments to `spvGatherSwizzle()`/`spvGatherCompareSwizzle()`.
Update the C API. In addition to supporting this new functionality, add
some compiler options that I added in previous changes, but for which I
neglected to update the C API.
2019-08-02 20:11:19 +00:00
|
|
|
c = spvGatherSwizzle(tex2d, tex2dSmplr, tex2dSwzl, component::x, float2(0.0), int2(0));
|
|
|
|
c = spvGatherSwizzle(texCube, texCubeSmplr, texCubeSwzl, component::y, float3(0.0));
|
|
|
|
c = spvGatherSwizzle(tex2dArray, tex2dArraySmplr, tex2dArraySwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0));
|
|
|
|
c = spvGatherSwizzle(texCubeArray, texCubeArraySmplr, texCubeArraySwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w)));
|
|
|
|
c = spvGatherCompareSwizzle(depth2d, depth2dSmplr, depth2dSwzl, float2(0.0), 1.0);
|
|
|
|
c = spvGatherCompareSwizzle(depthCube, depthCubeSmplr, depthCubeSwzl, float3(0.0), 1.0);
|
|
|
|
c = spvGatherCompareSwizzle(depth2dArray, depth2dArraySmplr, depth2dArraySwzl, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
|
|
|
c = spvGatherCompareSwizzle(depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
2018-09-20 01:36:33 +00:00
|
|
|
}
|
|
|
|
|