mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-15 08:20:07 +00:00
Merge pull request #706 from cdavis5e/component-swizzle
MSL: Add an option to insert texture swizzles into generated shaders.
This commit is contained in:
commit
69b034f26e
3
main.cpp
3
main.cpp
@ -489,6 +489,7 @@ struct CLIArguments
|
||||
bool yflip = false;
|
||||
bool sso = false;
|
||||
bool support_nonzero_baseinstance = true;
|
||||
bool msl_swizzle_texture_samples = false;
|
||||
vector<PLSArg> pls_in;
|
||||
vector<PLSArg> pls_out;
|
||||
vector<Remap> remaps;
|
||||
@ -703,6 +704,7 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
|
||||
cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
|
||||
cbs.add("--no-420pack-extension", [&args](CLIParser &) { args.use_420pack_extension = false; });
|
||||
cbs.add("--msl-swizzle-texture-samples", [&args](CLIParser &) { args.msl_swizzle_texture_samples = true; });
|
||||
cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
|
||||
cbs.add("--rename-entry-point", [&args](CLIParser &parser) {
|
||||
auto old_name = parser.next_string();
|
||||
@ -822,6 +824,7 @@ static int main_inner(int argc, char *argv[])
|
||||
auto msl_opts = msl_comp->get_msl_options();
|
||||
if (args.set_msl_version)
|
||||
msl_opts.msl_version = args.msl_version;
|
||||
msl_opts.swizzle_texture_samples = args.msl_swizzle_texture_samples;
|
||||
msl_comp->set_msl_options(msl_opts);
|
||||
}
|
||||
else if (args.hlsl)
|
||||
|
@ -0,0 +1,162 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, spvSwizzle s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, 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;
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], 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 tex1dSamp [[sampler(0)]], sampler tex2dSamp [[sampler(1)]], sampler tex3dSamp [[sampler(2)]], sampler texCubeSamp [[sampler(3)]], sampler tex2dArraySamp [[sampler(4)]], sampler texCubeArraySamp [[sampler(5)]], sampler depth2dSamp [[sampler(7)]], sampler depthCubeSamp [[sampler(8)]], sampler depth2dArraySamp [[sampler(9)]], sampler depthCubeArraySamp [[sampler(10)]])
|
||||
{
|
||||
float4 c = spvTextureSwizzle(tex1d.sample(tex1dSamp, 0.0), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float2(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float3(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(texCube.sample(texCubeSamp, float3(0.0)), spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySamp, float3(0.0).xy, uint(round(float3(0.0).z))), spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w))), spvAuxBuffer.swizzleConst[5]);
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[7]);
|
||||
c.x = spvTextureSwizzle(depthCube.sample_compare(depthCubeSamp, float4(0.0, 0.0, 0.0, 1.0).xyz, float4(0.0, 0.0, 0.0, 1.0).w), spvAuxBuffer.swizzleConst[8]);
|
||||
c.x = spvTextureSwizzle(depth2dArray.sample_compare(depth2dArraySamp, 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), spvAuxBuffer.swizzleConst[9]);
|
||||
c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), spvAuxBuffer.swizzleConst[10]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSamp, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), spvAuxBuffer.swizzleConst[2]);
|
||||
float4 _152 = float4(0.0, 0.0, 1.0, 1.0);
|
||||
_152.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, _152.xy / _152.z, float4(0.0, 0.0, 1.0, 1.0).z), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSamp, 0.0), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float2(0.0), level(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(texCube.sample(texCubeSamp, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySamp, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), spvAuxBuffer.swizzleConst[5]);
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSamp, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w, level(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
float4 _202 = float4(0.0, 0.0, 1.0, 1.0);
|
||||
_202.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, _202.xy / _202.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.read(uint(0)), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), spvAuxBuffer.swizzleConst[4]);
|
||||
c = texBuffer.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, texture2d<float>, float2, int2>(tex2dSamp, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvGatherSwizzle<float, texturecube<float>, float3>(texCubeSamp, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvGatherSwizzle<float, texture2d_array<float>, float2, uint, int2>(tex2dArraySamp, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvGatherSwizzle<float, texturecube_array<float>, float3, uint>(texCubeArraySamp, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]);
|
||||
c = depth2d.gather_compare(depth2dSamp, float2(0.0), 1.0);
|
||||
c = depthCube.gather_compare(depthCubeSamp, float3(0.0), 1.0);
|
||||
c = depth2dArray.gather_compare(depth2dArraySamp, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = depthCubeArray.gather_compare(depthCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
}
|
||||
|
@ -0,0 +1,147 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, spvSwizzle s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, 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;
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<int> tex1d [[texture(0)]], texture2d<int> tex2d [[texture(1)]], texture3d<int> tex3d [[texture(2)]], texturecube<int> texCube [[texture(3)]], texture2d_array<int> tex2dArray [[texture(4)]], texturecube_array<int> texCubeArray [[texture(5)]], texture2d<int> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
|
||||
{
|
||||
float4 c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[3]));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), spvAuxBuffer.swizzleConst[5]));
|
||||
c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[3]));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), spvAuxBuffer.swizzleConst[5]));
|
||||
c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(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)), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(tex1d.read(uint(0)), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(texBuffer.read(spvTexelBufferCoord(0)));
|
||||
c = float4(spvGatherSwizzle<int, texture2d<int>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvGatherSwizzle<int, texturecube<int>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]));
|
||||
c = float4(spvGatherSwizzle<int, texture2d_array<int>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(spvGatherSwizzle<int, texturecube_array<int>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]));
|
||||
}
|
||||
|
@ -0,0 +1,168 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, spvSwizzle s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, 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;
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
float4 doSwizzle(thread texture1d<float> tex1d, thread const sampler tex1dSmplr, thread texture2d<float> tex2d, thread const sampler tex2dSmplr, thread texture3d<float> tex3d, thread const sampler tex3dSmplr, thread texturecube<float> texCube, thread const sampler texCubeSmplr, thread texture2d_array<float> tex2dArray, thread const sampler tex2dArraySmplr, thread texturecube_array<float> texCubeArray, thread const sampler texCubeArraySmplr, thread depth2d<float> depth2d, thread const sampler depth2dSmplr, thread depthcube<float> depthCube, thread const sampler depthCubeSmplr, thread depth2d_array<float> depth2dArray, thread const sampler depth2dArraySmplr, thread depthcube_array<float> depthCubeArray, thread const sampler depthCubeArraySmplr, thread texture2d<float> texBuffer, constant spvAux& spvAuxBuffer)
|
||||
{
|
||||
float4 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), spvAuxBuffer.swizzleConst[5]);
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[7]);
|
||||
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), spvAuxBuffer.swizzleConst[8]);
|
||||
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), spvAuxBuffer.swizzleConst[9]);
|
||||
c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), spvAuxBuffer.swizzleConst[10]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[1]);
|
||||
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), spvAuxBuffer.swizzleConst[2]);
|
||||
float4 _103 = float4(0.0, 0.0, 1.0, 1.0);
|
||||
_103.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _103.xy / _103.z, float4(0.0, 0.0, 1.0, 1.0).z), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), spvAuxBuffer.swizzleConst[5]);
|
||||
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)), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
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)), spvAuxBuffer.swizzleConst[2]);
|
||||
float4 _131 = float4(0.0, 0.0, 1.0, 1.0);
|
||||
_131.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _131.xy / _131.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.read(uint(0)), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), spvAuxBuffer.swizzleConst[4]);
|
||||
c = texBuffer.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, texture2d<float>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvGatherSwizzle<float, texturecube<float>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvGatherSwizzle<float, texture2d_array<float>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvGatherSwizzle<float, texturecube_array<float>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]);
|
||||
c = depth2d.gather_compare(depth2dSmplr, float2(0.0), 1.0);
|
||||
c = depthCube.gather_compare(depthCubeSmplr, float3(0.0), 1.0);
|
||||
c = depth2dArray.gather_compare(depth2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = depthCubeArray.gather_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
return c;
|
||||
}
|
||||
|
||||
fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], 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 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(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
|
||||
{
|
||||
float4 c = doSwizzle(tex1d, tex1dSmplr, tex2d, tex2dSmplr, tex3d, tex3dSmplr, texCube, texCubeSmplr, tex2dArray, tex2dArraySmplr, texCubeArray, texCubeArraySmplr, depth2d, depth2dSmplr, depthCube, depthCubeSmplr, depth2dArray, depth2dArraySmplr, depthCubeArray, depthCubeArraySmplr, texBuffer, spvAuxBuffer);
|
||||
}
|
||||
|
@ -0,0 +1,147 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, spvSwizzle s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, 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;
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<uint> tex1d [[texture(0)]], texture2d<uint> tex2d [[texture(1)]], texture3d<uint> tex3d [[texture(2)]], texturecube<uint> texCube [[texture(3)]], texture2d_array<uint> tex2dArray [[texture(4)]], texturecube_array<uint> texCubeArray [[texture(5)]], texture2d<uint> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
|
||||
{
|
||||
float4 c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[3]));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), spvAuxBuffer.swizzleConst[5]));
|
||||
c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[3]));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), spvAuxBuffer.swizzleConst[5]));
|
||||
c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(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)), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(tex1d.read(uint(0)), spvAuxBuffer.swizzleConst[0]));
|
||||
c = float4(spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), spvAuxBuffer.swizzleConst[2]));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(texBuffer.read(spvTexelBufferCoord(0)));
|
||||
c = float4(spvGatherSwizzle<uint, texture2d<uint>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]));
|
||||
c = float4(spvGatherSwizzle<uint, texturecube<uint>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]));
|
||||
c = float4(spvGatherSwizzle<uint, texture2d_array<uint>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]));
|
||||
c = float4(spvGatherSwizzle<uint, texturecube_array<uint>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]));
|
||||
}
|
||||
|
162
reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag
Normal file
162
reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag
Normal file
@ -0,0 +1,162 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, spvSwizzle s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, 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;
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], 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 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(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
|
||||
{
|
||||
float4 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), spvAuxBuffer.swizzleConst[5]);
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[7]);
|
||||
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), spvAuxBuffer.swizzleConst[8]);
|
||||
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), spvAuxBuffer.swizzleConst[9]);
|
||||
c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), spvAuxBuffer.swizzleConst[10]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), spvAuxBuffer.swizzleConst[1]);
|
||||
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), spvAuxBuffer.swizzleConst[2]);
|
||||
float4 _100 = float4(0.0, 0.0, 1.0, 1.0);
|
||||
_100.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _100.xy / _100.z, float4(0.0, 0.0, 1.0, 1.0).z), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), spvAuxBuffer.swizzleConst[5]);
|
||||
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)), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[1]);
|
||||
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)), spvAuxBuffer.swizzleConst[2]);
|
||||
float4 _128 = float4(0.0, 0.0, 1.0, 1.0);
|
||||
_128.z = float4(0.0, 0.0, 1.0, 1.0).w;
|
||||
c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _128.xy / _128.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), spvAuxBuffer.swizzleConst[7]);
|
||||
c = spvTextureSwizzle(tex1d.read(uint(0)), spvAuxBuffer.swizzleConst[0]);
|
||||
c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), spvAuxBuffer.swizzleConst[2]);
|
||||
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), spvAuxBuffer.swizzleConst[4]);
|
||||
c = texBuffer.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, texture2d<float>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]);
|
||||
c = spvGatherSwizzle<float, texturecube<float>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]);
|
||||
c = spvGatherSwizzle<float, texture2d_array<float>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]);
|
||||
c = spvGatherSwizzle<float, texturecube_array<float>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]);
|
||||
c = depth2d.gather_compare(depth2dSmplr, float2(0.0), 1.0);
|
||||
c = depthCube.gather_compare(depthCubeSmplr, float3(0.0), 1.0);
|
||||
c = depth2dArray.gather_compare(depth2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = depthCubeArray.gather_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
}
|
||||
|
364
shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag
Normal file
364
shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag
Normal file
@ -0,0 +1,364 @@
|
||||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 247
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpCapability Sampled1D
|
||||
OpCapability SampledCubeArray
|
||||
OpCapability SampledBuffer
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %c "c"
|
||||
OpName %tex1d "tex1d"
|
||||
OpName %tex2d "tex2d"
|
||||
OpName %tex3d "tex3d"
|
||||
OpName %texCube "texCube"
|
||||
OpName %tex2dArray "tex2dArray"
|
||||
OpName %texCubeArray "texCubeArray"
|
||||
OpName %depth2d "depth2d"
|
||||
OpName %depthCube "depthCube"
|
||||
OpName %depth2dArray "depth2dArray"
|
||||
OpName %depthCubeArray "depthCubeArray"
|
||||
OpName %texBuffer "texBuffer"
|
||||
OpName %tex1dSamp "tex1dSamp"
|
||||
OpName %tex2dSamp "tex2dSamp"
|
||||
OpName %tex3dSamp "tex3dSamp"
|
||||
OpName %texCubeSamp "texCubeSamp"
|
||||
OpName %tex2dArraySamp "tex2dArraySamp"
|
||||
OpName %texCubeArraySamp "texCubeArraySamp"
|
||||
OpName %depth2dSamp "depth2dSamp"
|
||||
OpName %depthCubeSamp "depthCubeSamp"
|
||||
OpName %depth2dArraySamp "depth2dArraySamp"
|
||||
OpName %depthCubeArraySamp "depthCubeArraySamp"
|
||||
OpDecorate %tex1d DescriptorSet 0
|
||||
OpDecorate %tex1d Binding 0
|
||||
OpDecorate %tex2d DescriptorSet 0
|
||||
OpDecorate %tex2d Binding 1
|
||||
OpDecorate %tex3d DescriptorSet 0
|
||||
OpDecorate %tex3d Binding 2
|
||||
OpDecorate %texCube DescriptorSet 0
|
||||
OpDecorate %texCube Binding 3
|
||||
OpDecorate %tex2dArray DescriptorSet 0
|
||||
OpDecorate %tex2dArray Binding 4
|
||||
OpDecorate %texCubeArray DescriptorSet 0
|
||||
OpDecorate %texCubeArray Binding 5
|
||||
OpDecorate %depth2d DescriptorSet 0
|
||||
OpDecorate %depth2d Binding 7
|
||||
OpDecorate %depthCube DescriptorSet 0
|
||||
OpDecorate %depthCube Binding 8
|
||||
OpDecorate %depth2dArray DescriptorSet 0
|
||||
OpDecorate %depth2dArray Binding 9
|
||||
OpDecorate %depthCubeArray DescriptorSet 0
|
||||
OpDecorate %depthCubeArray Binding 10
|
||||
OpDecorate %texBuffer DescriptorSet 0
|
||||
OpDecorate %texBuffer Binding 6
|
||||
OpDecorate %tex1dSamp DescriptorSet 1
|
||||
OpDecorate %tex1dSamp Binding 0
|
||||
OpDecorate %tex2dSamp DescriptorSet 1
|
||||
OpDecorate %tex2dSamp Binding 1
|
||||
OpDecorate %tex3dSamp DescriptorSet 1
|
||||
OpDecorate %tex3dSamp Binding 2
|
||||
OpDecorate %texCubeSamp DescriptorSet 1
|
||||
OpDecorate %texCubeSamp Binding 3
|
||||
OpDecorate %tex2dArraySamp DescriptorSet 1
|
||||
OpDecorate %tex2dArraySamp Binding 4
|
||||
OpDecorate %texCubeArraySamp DescriptorSet 1
|
||||
OpDecorate %texCubeArraySamp Binding 5
|
||||
OpDecorate %depth2dSamp DescriptorSet 1
|
||||
OpDecorate %depth2dSamp Binding 7
|
||||
OpDecorate %depthCubeSamp DescriptorSet 1
|
||||
OpDecorate %depthCubeSamp Binding 8
|
||||
OpDecorate %depth2dArraySamp DescriptorSet 1
|
||||
OpDecorate %depth2dArraySamp Binding 9
|
||||
OpDecorate %depthCubeArraySamp DescriptorSet 1
|
||||
OpDecorate %depthCubeArraySamp Binding 10
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%10 = OpTypeImage %float 1D 0 0 0 1 Unknown
|
||||
%11 = OpTypeSampledImage %10
|
||||
%12 = OpTypeSampler
|
||||
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
|
||||
%tex1d = OpVariable %_ptr_UniformConstant_10 UniformConstant
|
||||
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
|
||||
%tex1dSamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%float_0 = OpConstant %float 0
|
||||
%17 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%18 = OpTypeSampledImage %17
|
||||
%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
|
||||
%tex2d = OpVariable %_ptr_UniformConstant_17 UniformConstant
|
||||
%tex2dSamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%v2float = OpTypeVector %float 2
|
||||
%23 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%25 = OpTypeImage %float 3D 0 0 0 1 Unknown
|
||||
%26 = OpTypeSampledImage %25
|
||||
%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
|
||||
%tex3d = OpVariable %_ptr_UniformConstant_25 UniformConstant
|
||||
%tex3dSamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%v3float = OpTypeVector %float 3
|
||||
%31 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
||||
%33 = OpTypeImage %float Cube 0 0 0 1 Unknown
|
||||
%34 = OpTypeSampledImage %33
|
||||
%_ptr_UniformConstant_33 = OpTypePointer UniformConstant %33
|
||||
%texCube = OpVariable %_ptr_UniformConstant_33 UniformConstant
|
||||
%texCubeSamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%39 = OpTypeImage %float 2D 0 1 0 1 Unknown
|
||||
%40 = OpTypeSampledImage %39
|
||||
%_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39
|
||||
%tex2dArray = OpVariable %_ptr_UniformConstant_39 UniformConstant
|
||||
%tex2dArraySamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%45 = OpTypeImage %float Cube 0 1 0 1 Unknown
|
||||
%46 = OpTypeSampledImage %45
|
||||
%_ptr_UniformConstant_45 = OpTypePointer UniformConstant %45
|
||||
%texCubeArray = OpVariable %_ptr_UniformConstant_45 UniformConstant
|
||||
%texCubeArraySamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%50 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
|
||||
%52 = OpTypeImage %float 2D 1 0 0 1 Unknown
|
||||
%53 = OpTypeSampledImage %52
|
||||
%_ptr_UniformConstant_52 = OpTypePointer UniformConstant %52
|
||||
%depth2d = OpVariable %_ptr_UniformConstant_52 UniformConstant
|
||||
%depth2dSamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%float_1 = OpConstant %float 1
|
||||
%58 = OpConstantComposite %v3float %float_0 %float_0 %float_1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%65 = OpTypeImage %float Cube 1 0 0 1 Unknown
|
||||
%66 = OpTypeSampledImage %65
|
||||
%_ptr_UniformConstant_65 = OpTypePointer UniformConstant %65
|
||||
%depthCube = OpVariable %_ptr_UniformConstant_65 UniformConstant
|
||||
%depthCubeSamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%70 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
|
||||
%74 = OpTypeImage %float 2D 1 1 0 1 Unknown
|
||||
%75 = OpTypeSampledImage %74
|
||||
%_ptr_UniformConstant_74 = OpTypePointer UniformConstant %74
|
||||
%depth2dArray = OpVariable %_ptr_UniformConstant_74 UniformConstant
|
||||
%depth2dArraySamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%82 = OpTypeImage %float Cube 1 1 0 1 Unknown
|
||||
%83 = OpTypeSampledImage %82
|
||||
%_ptr_UniformConstant_82 = OpTypePointer UniformConstant %82
|
||||
%depthCubeArray = OpVariable %_ptr_UniformConstant_82 UniformConstant
|
||||
%depthCubeArraySamp = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%97 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%98 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%v2int = OpTypeVector %int 2
|
||||
%138 = OpConstantComposite %v2int %int_0 %int_0
|
||||
%v3int = OpTypeVector %int 3
|
||||
%143 = OpConstantComposite %v3int %int_0 %int_0 %int_0
|
||||
%149 = OpTypeImage %float Buffer 0 0 0 1 Unknown
|
||||
%_ptr_UniformConstant_149 = OpTypePointer UniformConstant %149
|
||||
%texBuffer = OpVariable %_ptr_UniformConstant_149 UniformConstant
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%int_3 = OpConstant %int 3
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%c = OpVariable %_ptr_Function_v4float Function
|
||||
%13 = OpLoad %10 %tex1d
|
||||
%14 = OpLoad %12 %tex1dSamp
|
||||
%15 = OpSampledImage %11 %13 %14
|
||||
%16 = OpImageSampleImplicitLod %v4float %15 %float_0
|
||||
OpStore %c %16
|
||||
%19 = OpLoad %17 %tex2d
|
||||
%20 = OpLoad %12 %tex2dSamp
|
||||
%21 = OpSampledImage %18 %19 %20
|
||||
%24 = OpImageSampleImplicitLod %v4float %21 %23
|
||||
OpStore %c %24
|
||||
%27 = OpLoad %25 %tex3d
|
||||
%28 = OpLoad %12 %tex3dSamp
|
||||
%29 = OpSampledImage %26 %27 %28
|
||||
%32 = OpImageSampleImplicitLod %v4float %29 %31
|
||||
OpStore %c %32
|
||||
%35 = OpLoad %33 %texCube
|
||||
%36 = OpLoad %12 %texCubeSamp
|
||||
%37 = OpSampledImage %34 %35 %36
|
||||
%38 = OpImageSampleImplicitLod %v4float %37 %31
|
||||
OpStore %c %38
|
||||
%41 = OpLoad %39 %tex2dArray
|
||||
%42 = OpLoad %12 %tex2dArraySamp
|
||||
%43 = OpSampledImage %40 %41 %42
|
||||
%44 = OpImageSampleImplicitLod %v4float %43 %31
|
||||
OpStore %c %44
|
||||
%47 = OpLoad %45 %texCubeArray
|
||||
%48 = OpLoad %12 %texCubeArraySamp
|
||||
%49 = OpSampledImage %46 %47 %48
|
||||
%51 = OpImageSampleImplicitLod %v4float %49 %50
|
||||
OpStore %c %51
|
||||
%54 = OpLoad %52 %depth2d
|
||||
%55 = OpLoad %12 %depth2dSamp
|
||||
%56 = OpSampledImage %53 %54 %55
|
||||
%59 = OpCompositeExtract %float %58 2
|
||||
%60 = OpImageSampleDrefImplicitLod %float %56 %58 %59
|
||||
%64 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %64 %60
|
||||
%67 = OpLoad %65 %depthCube
|
||||
%68 = OpLoad %12 %depthCubeSamp
|
||||
%69 = OpSampledImage %66 %67 %68
|
||||
%71 = OpCompositeExtract %float %70 3
|
||||
%72 = OpImageSampleDrefImplicitLod %float %69 %70 %71
|
||||
%73 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %73 %72
|
||||
%76 = OpLoad %74 %depth2dArray
|
||||
%77 = OpLoad %12 %depth2dArraySamp
|
||||
%78 = OpSampledImage %75 %76 %77
|
||||
%79 = OpCompositeExtract %float %70 3
|
||||
%80 = OpImageSampleDrefImplicitLod %float %78 %70 %79
|
||||
%81 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %81 %80
|
||||
%84 = OpLoad %82 %depthCubeArray
|
||||
%85 = OpLoad %12 %depthCubeArraySamp
|
||||
%86 = OpSampledImage %83 %84 %85
|
||||
%87 = OpImageSampleDrefImplicitLod %float %86 %50 %float_1
|
||||
%88 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %88 %87
|
||||
%89 = OpLoad %10 %tex1d
|
||||
%90 = OpLoad %12 %tex1dSamp
|
||||
%91 = OpSampledImage %11 %89 %90
|
||||
%92 = OpImageSampleProjImplicitLod %v4float %91 %97
|
||||
OpStore %c %92
|
||||
%93 = OpLoad %17 %tex2d
|
||||
%94 = OpLoad %12 %tex2dSamp
|
||||
%95 = OpSampledImage %18 %93 %94
|
||||
%96 = OpImageSampleProjImplicitLod %v4float %95 %58
|
||||
OpStore %c %96
|
||||
%99 = OpLoad %25 %tex3d
|
||||
%100 = OpLoad %12 %tex3dSamp
|
||||
%101 = OpSampledImage %26 %99 %100
|
||||
%102 = OpImageSampleProjImplicitLod %v4float %101 %70
|
||||
OpStore %c %102
|
||||
%103 = OpLoad %52 %depth2d
|
||||
%104 = OpLoad %12 %depth2dSamp
|
||||
%105 = OpSampledImage %53 %103 %104
|
||||
%106 = OpCompositeExtract %float %98 2
|
||||
%107 = OpCompositeExtract %float %98 3
|
||||
%108 = OpCompositeInsert %v4float %107 %98 2
|
||||
%109 = OpImageSampleProjDrefImplicitLod %float %105 %108 %106
|
||||
%110 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %110 %109
|
||||
%111 = OpLoad %10 %tex1d
|
||||
%112 = OpLoad %12 %tex1dSamp
|
||||
%113 = OpSampledImage %11 %111 %112
|
||||
%114 = OpImageSampleExplicitLod %v4float %113 %float_0 Lod %float_0
|
||||
OpStore %c %114
|
||||
%115 = OpLoad %17 %tex2d
|
||||
%116 = OpLoad %12 %tex2dSamp
|
||||
%117 = OpSampledImage %18 %115 %116
|
||||
%118 = OpImageSampleExplicitLod %v4float %117 %23 Lod %float_0
|
||||
OpStore %c %118
|
||||
%119 = OpLoad %25 %tex3d
|
||||
%120 = OpLoad %12 %tex3dSamp
|
||||
%121 = OpSampledImage %26 %119 %120
|
||||
%122 = OpImageSampleExplicitLod %v4float %121 %31 Lod %float_0
|
||||
OpStore %c %122
|
||||
%123 = OpLoad %33 %texCube
|
||||
%124 = OpLoad %12 %texCubeSamp
|
||||
%125 = OpSampledImage %34 %123 %124
|
||||
%126 = OpImageSampleExplicitLod %v4float %125 %31 Lod %float_0
|
||||
OpStore %c %126
|
||||
%127 = OpLoad %39 %tex2dArray
|
||||
%128 = OpLoad %12 %tex2dArraySamp
|
||||
%129 = OpSampledImage %40 %127 %128
|
||||
%130 = OpImageSampleExplicitLod %v4float %129 %31 Lod %float_0
|
||||
OpStore %c %130
|
||||
%131 = OpLoad %45 %texCubeArray
|
||||
%132 = OpLoad %12 %texCubeArraySamp
|
||||
%133 = OpSampledImage %46 %131 %132
|
||||
%134 = OpImageSampleExplicitLod %v4float %133 %50 Lod %float_0
|
||||
OpStore %c %134
|
||||
%135 = OpLoad %52 %depth2d
|
||||
%136 = OpLoad %12 %depth2dSamp
|
||||
%137 = OpSampledImage %53 %135 %136
|
||||
%139 = OpCompositeExtract %float %58 2
|
||||
%140 = OpImageSampleDrefExplicitLod %float %137 %58 %139 Lod %float_0
|
||||
%141 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %141 %140
|
||||
%142 = OpLoad %10 %tex1d
|
||||
%144 = OpLoad %12 %tex1dSamp
|
||||
%145 = OpSampledImage %11 %142 %144
|
||||
%146 = OpImageSampleProjExplicitLod %v4float %145 %97 Lod %float_0
|
||||
OpStore %c %146
|
||||
%147 = OpLoad %17 %tex2d
|
||||
%148 = OpLoad %12 %tex2dSamp
|
||||
%150 = OpSampledImage %18 %147 %148
|
||||
%151 = OpImageSampleProjExplicitLod %v4float %150 %58 Lod %float_0
|
||||
OpStore %c %151
|
||||
%152 = OpLoad %25 %tex3d
|
||||
%153 = OpLoad %12 %tex3dSamp
|
||||
%154 = OpSampledImage %26 %152 %153
|
||||
%155 = OpImageSampleProjExplicitLod %v4float %154 %70 Lod %float_0
|
||||
OpStore %c %155
|
||||
%156 = OpLoad %52 %depth2d
|
||||
%157 = OpLoad %12 %depth2dSamp
|
||||
%158 = OpSampledImage %53 %156 %157
|
||||
%159 = OpCompositeExtract %float %98 2
|
||||
%160 = OpCompositeExtract %float %98 3
|
||||
%161 = OpCompositeInsert %v4float %160 %98 2
|
||||
%162 = OpImageSampleProjDrefExplicitLod %float %158 %161 %159 Lod %float_0
|
||||
%163 = OpAccessChain %_ptr_Function_float %c %uint_0
|
||||
OpStore %163 %162
|
||||
%164 = OpLoad %10 %tex1d
|
||||
%165 = OpImageFetch %v4float %164 %int_0 Lod %int_0
|
||||
OpStore %c %165
|
||||
%166 = OpLoad %17 %tex2d
|
||||
%167 = OpImageFetch %v4float %166 %138 Lod %int_0
|
||||
OpStore %c %167
|
||||
%168 = OpLoad %25 %tex3d
|
||||
%169 = OpImageFetch %v4float %168 %143 Lod %int_0
|
||||
OpStore %c %169
|
||||
%170 = OpLoad %39 %tex2dArray
|
||||
%171 = OpImageFetch %v4float %170 %143 Lod %int_0
|
||||
OpStore %c %171
|
||||
%172 = OpLoad %149 %texBuffer
|
||||
%173 = OpImageFetch %v4float %172 %int_0
|
||||
OpStore %c %173
|
||||
%174 = OpLoad %17 %tex2d
|
||||
%175 = OpLoad %12 %tex2dSamp
|
||||
%176 = OpSampledImage %18 %174 %175
|
||||
%177 = OpImageGather %v4float %176 %23 %int_0
|
||||
OpStore %c %177
|
||||
%178 = OpLoad %33 %texCube
|
||||
%179 = OpLoad %12 %texCubeSamp
|
||||
%180 = OpSampledImage %34 %178 %179
|
||||
%181 = OpImageGather %v4float %180 %31 %int_1
|
||||
OpStore %c %181
|
||||
%182 = OpLoad %39 %tex2dArray
|
||||
%183 = OpLoad %12 %tex2dArraySamp
|
||||
%184 = OpSampledImage %40 %182 %183
|
||||
%185 = OpImageGather %v4float %184 %31 %int_2
|
||||
OpStore %c %185
|
||||
%186 = OpLoad %45 %texCubeArray
|
||||
%187 = OpLoad %12 %texCubeArraySamp
|
||||
%188 = OpSampledImage %46 %186 %187
|
||||
%189 = OpImageGather %v4float %188 %50 %int_3
|
||||
OpStore %c %189
|
||||
%190 = OpLoad %52 %depth2d
|
||||
%191 = OpLoad %12 %depth2dSamp
|
||||
%192 = OpSampledImage %53 %190 %191
|
||||
%193 = OpImageDrefGather %v4float %192 %23 %float_1
|
||||
OpStore %c %193
|
||||
%194 = OpLoad %65 %depthCube
|
||||
%195 = OpLoad %12 %depthCubeSamp
|
||||
%196 = OpSampledImage %66 %194 %195
|
||||
%197 = OpImageDrefGather %v4float %196 %31 %float_1
|
||||
OpStore %c %197
|
||||
%198 = OpLoad %74 %depth2dArray
|
||||
%199 = OpLoad %12 %depth2dArraySamp
|
||||
%200 = OpSampledImage %75 %198 %199
|
||||
%201 = OpImageDrefGather %v4float %200 %31 %float_1
|
||||
OpStore %c %201
|
||||
%202 = OpLoad %82 %depthCubeArray
|
||||
%203 = OpLoad %12 %depthCubeArraySamp
|
||||
%204 = OpSampledImage %83 %202 %203
|
||||
%205 = OpImageDrefGather %v4float %204 %50 %float_1
|
||||
OpStore %c %205
|
||||
OpReturn
|
||||
OpFunctionEnd
|
53
shaders-msl-no-opt/frag/texture-access-int.swizzle.frag
Normal file
53
shaders-msl-no-opt/frag/texture-access-int.swizzle.frag
Normal file
@ -0,0 +1,53 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform isampler1D tex1d;
|
||||
layout(binding = 1) uniform isampler2D tex2d;
|
||||
layout(binding = 2) uniform isampler3D tex3d;
|
||||
layout(binding = 3) uniform isamplerCube texCube;
|
||||
layout(binding = 4) uniform isampler2DArray tex2dArray;
|
||||
layout(binding = 5) uniform isamplerCubeArray texCubeArray;
|
||||
layout(binding = 6) uniform isamplerBuffer texBuffer;
|
||||
|
||||
void main()
|
||||
{
|
||||
// OpImageSampleImplicitLod
|
||||
vec4 c = texture(tex1d, 0.0);
|
||||
c = texture(tex2d, vec2(0.0, 0.0));
|
||||
c = texture(tex3d, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCube, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(tex2dArray, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0));
|
||||
|
||||
// OpImageSampleProjImplicitLod
|
||||
c = textureProj(tex1d, vec2(0.0, 1.0));
|
||||
c = textureProj(tex2d, vec3(0.0, 0.0, 1.0));
|
||||
c = textureProj(tex3d, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
// OpImageSampleExplicitLod
|
||||
c = textureLod(tex1d, 0.0, 0.0);
|
||||
c = textureLod(tex2d, vec2(0.0, 0.0), 0.0);
|
||||
c = textureLod(tex3d, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCube, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(tex2dArray, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 0.0);
|
||||
|
||||
// OpImageSampleProjExplicitLod
|
||||
c = textureProjLod(tex1d, vec2(0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex2d, vec3(0.0, 0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex3d, vec4(0.0, 0.0, 0.0, 1.0), 0.0);
|
||||
|
||||
// OpImageFetch
|
||||
c = texelFetch(tex1d, 0, 0);
|
||||
c = texelFetch(tex2d, ivec2(0, 0), 0);
|
||||
c = texelFetch(tex3d, ivec3(0, 0, 0), 0);
|
||||
c = texelFetch(tex2dArray, ivec3(0, 0, 0), 0);
|
||||
|
||||
// Show that this transformation doesn't apply to Buffer images.
|
||||
c = texelFetch(texBuffer, 0);
|
||||
|
||||
// OpImageGather
|
||||
c = textureGather(tex2d, vec2(0.0, 0.0), 0);
|
||||
c = textureGather(texCube, vec3(0.0, 0.0, 0.0), 1);
|
||||
c = textureGather(tex2dArray, vec3(0.0, 0.0, 0.0), 2);
|
||||
c = textureGather(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 3);
|
||||
}
|
86
shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag
Normal file
86
shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag
Normal file
@ -0,0 +1,86 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler1D tex1d;
|
||||
layout(binding = 1) uniform sampler2D tex2d;
|
||||
layout(binding = 2) uniform sampler3D tex3d;
|
||||
layout(binding = 3) uniform samplerCube texCube;
|
||||
layout(binding = 4) uniform sampler2DArray tex2dArray;
|
||||
layout(binding = 5) uniform samplerCubeArray texCubeArray;
|
||||
layout(binding = 6) uniform samplerBuffer texBuffer;
|
||||
|
||||
layout(binding = 7) uniform sampler2DShadow depth2d;
|
||||
layout(binding = 8) uniform samplerCubeShadow depthCube;
|
||||
layout(binding = 9) uniform sampler2DArrayShadow depth2dArray;
|
||||
layout(binding = 10) uniform samplerCubeArrayShadow depthCubeArray;
|
||||
|
||||
vec4 doSwizzle()
|
||||
{
|
||||
// OpImageSampleImplicitLod
|
||||
vec4 c = texture(tex1d, 0.0);
|
||||
c = texture(tex2d, vec2(0.0, 0.0));
|
||||
c = texture(tex3d, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCube, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(tex2dArray, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0));
|
||||
|
||||
// OpImageSampleDrefImplicitLod
|
||||
c.r = texture(depth2d, vec3(0.0, 0.0, 1.0));
|
||||
c.r = texture(depthCube, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
c.r = texture(depth2dArray, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
c.r = texture(depthCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 1.0);
|
||||
|
||||
// OpImageSampleProjImplicitLod
|
||||
c = textureProj(tex1d, vec2(0.0, 1.0));
|
||||
c = textureProj(tex2d, vec3(0.0, 0.0, 1.0));
|
||||
c = textureProj(tex3d, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
// OpImageSampleProjDrefImplicitLod
|
||||
c.r = textureProj(depth2d, vec4(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
// OpImageSampleExplicitLod
|
||||
c = textureLod(tex1d, 0.0, 0.0);
|
||||
c = textureLod(tex2d, vec2(0.0, 0.0), 0.0);
|
||||
c = textureLod(tex3d, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCube, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(tex2dArray, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 0.0);
|
||||
|
||||
// OpImageSampleDrefExplicitLod
|
||||
c.r = textureLod(depth2d, vec3(0.0, 0.0, 1.0), 0.0);
|
||||
|
||||
// OpImageSampleProjExplicitLod
|
||||
c = textureProjLod(tex1d, vec2(0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex2d, vec3(0.0, 0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex3d, vec4(0.0, 0.0, 0.0, 1.0), 0.0);
|
||||
|
||||
// OpImageSampleProjDrefExplicitLod
|
||||
c.r = textureProjLod(depth2d, vec4(0.0, 0.0, 1.0, 1.0), 0.0);
|
||||
|
||||
// OpImageFetch
|
||||
c = texelFetch(tex1d, 0, 0);
|
||||
c = texelFetch(tex2d, ivec2(0, 0), 0);
|
||||
c = texelFetch(tex3d, ivec3(0, 0, 0), 0);
|
||||
c = texelFetch(tex2dArray, ivec3(0, 0, 0), 0);
|
||||
|
||||
// Show that this transformation doesn't apply to Buffer images.
|
||||
c = texelFetch(texBuffer, 0);
|
||||
|
||||
// OpImageGather
|
||||
c = textureGather(tex2d, vec2(0.0, 0.0), 0);
|
||||
c = textureGather(texCube, vec3(0.0, 0.0, 0.0), 1);
|
||||
c = textureGather(tex2dArray, vec3(0.0, 0.0, 0.0), 2);
|
||||
c = textureGather(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 3);
|
||||
|
||||
// OpImageDrefGather
|
||||
c = textureGather(depth2d, vec2(0.0, 0.0), 1.0);
|
||||
c = textureGather(depthCube, vec3(0.0, 0.0, 0.0), 1.0);
|
||||
c = textureGather(depth2dArray, vec3(0.0, 0.0, 0.0), 1.0);
|
||||
c = textureGather(depthCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 1.0);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c = doSwizzle();
|
||||
}
|
53
shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag
Normal file
53
shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag
Normal file
@ -0,0 +1,53 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform usampler1D tex1d;
|
||||
layout(binding = 1) uniform usampler2D tex2d;
|
||||
layout(binding = 2) uniform usampler3D tex3d;
|
||||
layout(binding = 3) uniform usamplerCube texCube;
|
||||
layout(binding = 4) uniform usampler2DArray tex2dArray;
|
||||
layout(binding = 5) uniform usamplerCubeArray texCubeArray;
|
||||
layout(binding = 6) uniform usamplerBuffer texBuffer;
|
||||
|
||||
void main()
|
||||
{
|
||||
// OpImageSampleImplicitLod
|
||||
vec4 c = texture(tex1d, 0.0);
|
||||
c = texture(tex2d, vec2(0.0, 0.0));
|
||||
c = texture(tex3d, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCube, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(tex2dArray, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0));
|
||||
|
||||
// OpImageSampleProjImplicitLod
|
||||
c = textureProj(tex1d, vec2(0.0, 1.0));
|
||||
c = textureProj(tex2d, vec3(0.0, 0.0, 1.0));
|
||||
c = textureProj(tex3d, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
// OpImageSampleExplicitLod
|
||||
c = textureLod(tex1d, 0.0, 0.0);
|
||||
c = textureLod(tex2d, vec2(0.0, 0.0), 0.0);
|
||||
c = textureLod(tex3d, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCube, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(tex2dArray, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 0.0);
|
||||
|
||||
// OpImageSampleProjExplicitLod
|
||||
c = textureProjLod(tex1d, vec2(0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex2d, vec3(0.0, 0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex3d, vec4(0.0, 0.0, 0.0, 1.0), 0.0);
|
||||
|
||||
// OpImageFetch
|
||||
c = texelFetch(tex1d, 0, 0);
|
||||
c = texelFetch(tex2d, ivec2(0, 0), 0);
|
||||
c = texelFetch(tex3d, ivec3(0, 0, 0), 0);
|
||||
c = texelFetch(tex2dArray, ivec3(0, 0, 0), 0);
|
||||
|
||||
// Show that this transformation doesn't apply to Buffer images.
|
||||
c = texelFetch(texBuffer, 0);
|
||||
|
||||
// OpImageGather
|
||||
c = textureGather(tex2d, vec2(0.0, 0.0), 0);
|
||||
c = textureGather(texCube, vec3(0.0, 0.0, 0.0), 1);
|
||||
c = textureGather(tex2dArray, vec3(0.0, 0.0, 0.0), 2);
|
||||
c = textureGather(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 3);
|
||||
}
|
79
shaders-msl-no-opt/frag/texture-access.swizzle.frag
Normal file
79
shaders-msl-no-opt/frag/texture-access.swizzle.frag
Normal file
@ -0,0 +1,79 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler1D tex1d;
|
||||
layout(binding = 1) uniform sampler2D tex2d;
|
||||
layout(binding = 2) uniform sampler3D tex3d;
|
||||
layout(binding = 3) uniform samplerCube texCube;
|
||||
layout(binding = 4) uniform sampler2DArray tex2dArray;
|
||||
layout(binding = 5) uniform samplerCubeArray texCubeArray;
|
||||
layout(binding = 6) uniform samplerBuffer texBuffer;
|
||||
|
||||
layout(binding = 7) uniform sampler2DShadow depth2d;
|
||||
layout(binding = 8) uniform samplerCubeShadow depthCube;
|
||||
layout(binding = 9) uniform sampler2DArrayShadow depth2dArray;
|
||||
layout(binding = 10) uniform samplerCubeArrayShadow depthCubeArray;
|
||||
|
||||
void main()
|
||||
{
|
||||
// OpImageSampleImplicitLod
|
||||
vec4 c = texture(tex1d, 0.0);
|
||||
c = texture(tex2d, vec2(0.0, 0.0));
|
||||
c = texture(tex3d, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCube, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(tex2dArray, vec3(0.0, 0.0, 0.0));
|
||||
c = texture(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0));
|
||||
|
||||
// OpImageSampleDrefImplicitLod
|
||||
c.r = texture(depth2d, vec3(0.0, 0.0, 1.0));
|
||||
c.r = texture(depthCube, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
c.r = texture(depth2dArray, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
c.r = texture(depthCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 1.0);
|
||||
|
||||
// OpImageSampleProjImplicitLod
|
||||
c = textureProj(tex1d, vec2(0.0, 1.0));
|
||||
c = textureProj(tex2d, vec3(0.0, 0.0, 1.0));
|
||||
c = textureProj(tex3d, vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
// OpImageSampleProjDrefImplicitLod
|
||||
c.r = textureProj(depth2d, vec4(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
// OpImageSampleExplicitLod
|
||||
c = textureLod(tex1d, 0.0, 0.0);
|
||||
c = textureLod(tex2d, vec2(0.0, 0.0), 0.0);
|
||||
c = textureLod(tex3d, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCube, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(tex2dArray, vec3(0.0, 0.0, 0.0), 0.0);
|
||||
c = textureLod(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 0.0);
|
||||
|
||||
// OpImageSampleDrefExplicitLod
|
||||
c.r = textureLod(depth2d, vec3(0.0, 0.0, 1.0), 0.0);
|
||||
|
||||
// OpImageSampleProjExplicitLod
|
||||
c = textureProjLod(tex1d, vec2(0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex2d, vec3(0.0, 0.0, 1.0), 0.0);
|
||||
c = textureProjLod(tex3d, vec4(0.0, 0.0, 0.0, 1.0), 0.0);
|
||||
|
||||
// OpImageSampleProjDrefExplicitLod
|
||||
c.r = textureProjLod(depth2d, vec4(0.0, 0.0, 1.0, 1.0), 0.0);
|
||||
|
||||
// OpImageFetch
|
||||
c = texelFetch(tex1d, 0, 0);
|
||||
c = texelFetch(tex2d, ivec2(0, 0), 0);
|
||||
c = texelFetch(tex3d, ivec3(0, 0, 0), 0);
|
||||
c = texelFetch(tex2dArray, ivec3(0, 0, 0), 0);
|
||||
|
||||
// Show that this transformation doesn't apply to Buffer images.
|
||||
c = texelFetch(texBuffer, 0);
|
||||
|
||||
// OpImageGather
|
||||
c = textureGather(tex2d, vec2(0.0, 0.0), 0);
|
||||
c = textureGather(texCube, vec3(0.0, 0.0, 0.0), 1);
|
||||
c = textureGather(tex2dArray, vec3(0.0, 0.0, 0.0), 2);
|
||||
c = textureGather(texCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 3);
|
||||
|
||||
// OpImageDrefGather
|
||||
c = textureGather(depth2d, vec2(0.0, 0.0), 1.0);
|
||||
c = textureGather(depthCube, vec3(0.0, 0.0, 0.0), 1.0);
|
||||
c = textureGather(depth2dArray, vec3(0.0, 0.0, 0.0), 1.0);
|
||||
c = textureGather(depthCubeArray, vec4(0.0, 0.0, 0.0, 0.0), 1.0);
|
||||
}
|
@ -1237,6 +1237,7 @@ struct Meta
|
||||
Decoration decoration;
|
||||
std::vector<Decoration> members;
|
||||
uint32_t sampler = 0;
|
||||
uint32_t image = 0;
|
||||
|
||||
std::unordered_map<uint32_t, uint32_t> decoration_word_offset;
|
||||
|
||||
|
@ -1096,6 +1096,12 @@ const SPIRType &Compiler::get_non_pointer_type(uint32_t type_id) const
|
||||
return get_non_pointer_type(get<SPIRType>(type_id));
|
||||
}
|
||||
|
||||
bool Compiler::is_sampled_image_type(const SPIRType &type)
|
||||
{
|
||||
return (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage) &&
|
||||
type.image.sampled == 1 && type.image.dim != DimBuffer;
|
||||
}
|
||||
|
||||
void Compiler::set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
|
||||
const std::string &argument)
|
||||
{
|
||||
|
@ -179,6 +179,9 @@ public:
|
||||
// Gets the SPIR-V type underlying the given type_id, which might be a pointer.
|
||||
const SPIRType &get_non_pointer_type(uint32_t type_id) const;
|
||||
|
||||
// Returns if the given type refers to a sampled image.
|
||||
bool is_sampled_image_type(const SPIRType &type);
|
||||
|
||||
// Gets the underlying storage class for an OpVariable.
|
||||
spv::StorageClass get_storage_class(uint32_t id) const;
|
||||
|
||||
|
296
spirv_msl.cpp
296
spirv_msl.cpp
@ -28,6 +28,8 @@ using namespace std;
|
||||
static const uint32_t k_unknown_location = ~0u;
|
||||
static const uint32_t k_unknown_component = ~0u;
|
||||
|
||||
static const uint32_t k_aux_mbr_idx_swizzle_const = 0u;
|
||||
|
||||
CompilerMSL::CompilerMSL(vector<uint32_t> spirv_, vector<MSLVertexAttr> *p_vtx_attrs,
|
||||
vector<MSLResourceBinding> *p_res_bindings)
|
||||
: CompilerGLSL(move(spirv_))
|
||||
@ -139,6 +141,53 @@ void CompilerMSL::build_implicit_builtins()
|
||||
builtin_sample_id_id = var_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (msl_options.swizzle_texture_samples && has_sampled_images)
|
||||
{
|
||||
uint32_t offset = increase_bound_by(5);
|
||||
uint32_t type_id = offset;
|
||||
uint32_t type_arr_id = offset + 1;
|
||||
uint32_t struct_id = offset + 2;
|
||||
uint32_t struct_ptr_id = offset + 3;
|
||||
uint32_t var_id = offset + 4;
|
||||
|
||||
// Create a buffer to hold the swizzle constants.
|
||||
SPIRType uint_type;
|
||||
uint_type.basetype = SPIRType::UInt;
|
||||
uint_type.width = 32;
|
||||
set<SPIRType>(type_id, uint_type);
|
||||
|
||||
SPIRType uint_type_arr = uint_type;
|
||||
uint_type_arr.array.push_back(0);
|
||||
uint_type_arr.array_size_literal.push_back(true);
|
||||
uint_type_arr.parent_type = type_id;
|
||||
set<SPIRType>(type_arr_id, uint_type_arr);
|
||||
set_decoration(type_arr_id, DecorationArrayStride, 4);
|
||||
|
||||
SPIRType struct_type;
|
||||
struct_type.basetype = SPIRType::Struct;
|
||||
struct_type.member_types.push_back(type_arr_id);
|
||||
auto &type = set<SPIRType>(struct_id, struct_type);
|
||||
type.self = struct_id;
|
||||
set_decoration(struct_id, DecorationBlock);
|
||||
set_name(struct_id, "spvAux");
|
||||
set_member_name(struct_id, 0, "swizzleConst");
|
||||
set_member_decoration(struct_id, 0, DecorationOffset, 0);
|
||||
|
||||
SPIRType struct_type_ptr = struct_type;
|
||||
struct_type_ptr.pointer = true;
|
||||
struct_type_ptr.parent_type = struct_id;
|
||||
struct_type_ptr.storage = StorageClassUniform;
|
||||
auto &ptr_type = set<SPIRType>(struct_ptr_id, struct_type_ptr);
|
||||
ptr_type.self = struct_id;
|
||||
|
||||
set<SPIRVariable>(var_id, struct_ptr_id, StorageClassUniform);
|
||||
set_name(var_id, "spvAuxBuffer");
|
||||
// This should never match anything.
|
||||
set_decoration(var_id, DecorationDescriptorSet, 0xFFFFFFFE);
|
||||
set_decoration(var_id, DecorationBinding, msl_options.aux_buffer_index);
|
||||
aux_buffer_id = var_id;
|
||||
}
|
||||
}
|
||||
|
||||
static string create_sampler_address(const char *prefix, MSLSamplerAddress addr)
|
||||
@ -323,11 +372,14 @@ string CompilerMSL::compile()
|
||||
build_function_control_flow_graphs_and_analyze();
|
||||
update_active_builtins();
|
||||
analyze_image_and_sampler_usage();
|
||||
analyze_sampled_image_usage();
|
||||
build_implicit_builtins();
|
||||
|
||||
fixup_image_load_store_access();
|
||||
|
||||
set_enabled_interface_variables(get_active_interface_variables());
|
||||
if (aux_buffer_id)
|
||||
active_interface_variables.insert(aux_buffer_id);
|
||||
|
||||
// Preprocess OpCodes to extract the need to output additional header content
|
||||
preprocess_op_codes();
|
||||
@ -537,6 +589,13 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
|
||||
added_arg_ids.insert(builtin_frag_coord_id);
|
||||
}
|
||||
|
||||
if (msl_options.swizzle_texture_samples && is_sampled_image_type(type))
|
||||
{
|
||||
// Implicitly reads spvAuxBuffer.
|
||||
assert(aux_buffer_id != 0);
|
||||
added_arg_ids.insert(aux_buffer_id);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1584,6 +1643,113 @@ void CompilerMSL::emit_custom_functions()
|
||||
statement("");
|
||||
break;
|
||||
|
||||
case SPVFuncImplTextureSwizzle:
|
||||
statement("enum class spvSwizzle : uint");
|
||||
begin_scope();
|
||||
statement("none = 0,");
|
||||
statement("zero,");
|
||||
statement("one,");
|
||||
statement("red,");
|
||||
statement("green,");
|
||||
statement("blue,");
|
||||
statement("alpha");
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
statement("template<typename T> struct spvRemoveReference { typedef T type; };");
|
||||
statement("template<typename T> struct spvRemoveReference<thread T&> { typedef T type; };");
|
||||
statement("template<typename T> struct spvRemoveReference<thread T&&> { typedef T type; };");
|
||||
statement("template<typename T> inline constexpr thread T&& spvForward(thread typename "
|
||||
"spvRemoveReference<T>::type& x)");
|
||||
begin_scope();
|
||||
statement("return static_cast<thread T&&>(x);");
|
||||
end_scope();
|
||||
statement("template<typename T> inline constexpr thread T&& spvForward(thread typename "
|
||||
"spvRemoveReference<T>::type&& x)");
|
||||
begin_scope();
|
||||
statement("return static_cast<thread T&&>(x);");
|
||||
end_scope();
|
||||
statement("");
|
||||
statement("template<typename T>");
|
||||
statement("inline T spvGetSwizzle(vec<T, 4> x, spvSwizzle s)");
|
||||
begin_scope();
|
||||
statement("switch (s)");
|
||||
begin_scope();
|
||||
statement("case spvSwizzle::zero:");
|
||||
statement(" return 0;");
|
||||
statement("case spvSwizzle::one:");
|
||||
statement(" return 1;");
|
||||
statement("case spvSwizzle::red:");
|
||||
statement(" return x.r;");
|
||||
statement("case spvSwizzle::green:");
|
||||
statement(" return x.g;");
|
||||
statement("case spvSwizzle::blue:");
|
||||
statement(" return x.b;");
|
||||
statement("case spvSwizzle::alpha:");
|
||||
statement(" return x.a;");
|
||||
statement("default:");
|
||||
statement(" break;");
|
||||
end_scope();
|
||||
statement("return 0;");
|
||||
end_scope();
|
||||
statement("");
|
||||
statement("// Wrapper function that swizzles texture samples and fetches.");
|
||||
statement("template<typename T>");
|
||||
statement("inline vec<T, 4> spvTextureSwizzle(vec<T, 4> x, uint s)");
|
||||
begin_scope();
|
||||
statement("if (!s)");
|
||||
statement(" return x;");
|
||||
statement("return vec<T, 4>(spvGetSwizzle(x, spvSwizzle((s >> 0) & 0xFF)), "
|
||||
"spvGetSwizzle(x, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, spvSwizzle((s >> 16) & 0xFF)), "
|
||||
"spvGetSwizzle(x, spvSwizzle((s >> 24) & 0xFF)));");
|
||||
end_scope();
|
||||
statement("");
|
||||
statement("template<typename T>");
|
||||
statement("inline T spvTextureSwizzle(T x, uint s)");
|
||||
begin_scope();
|
||||
statement("return spvTextureSwizzle(vec<T, 4>(x, 0, 0, 1), s).x;");
|
||||
end_scope();
|
||||
statement("");
|
||||
statement("// Wrapper function that swizzles texture gathers.");
|
||||
statement("template<typename T, typename Tex, typename... Ts>");
|
||||
statement("inline vec<T, 4> spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) "
|
||||
"METAL_CONST_ARG(c)");
|
||||
begin_scope();
|
||||
statement("if (sw)");
|
||||
begin_scope();
|
||||
statement("switch (spvSwizzle((sw >> (uint(c) * 8)) & 0xFF))");
|
||||
begin_scope();
|
||||
statement("case spvSwizzle::none:");
|
||||
statement(" break;");
|
||||
statement("case spvSwizzle::zero:");
|
||||
statement(" return vec<T, 4>(0, 0, 0, 0);");
|
||||
statement("case spvSwizzle::one:");
|
||||
statement(" return vec<T, 4>(1, 1, 1, 1);");
|
||||
statement("case spvSwizzle::red:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::x);");
|
||||
statement("case spvSwizzle::green:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::y);");
|
||||
statement("case spvSwizzle::blue:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::z);");
|
||||
statement("case spvSwizzle::alpha:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::w);");
|
||||
end_scope();
|
||||
end_scope();
|
||||
// texture::gather insists on its component parameter being a constant
|
||||
// expression, so we need this silly workaround just to compile the shader.
|
||||
statement("switch (c)");
|
||||
begin_scope();
|
||||
statement("case component::x:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::x);");
|
||||
statement("case component::y:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::y);");
|
||||
statement("case component::z:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::z);");
|
||||
statement("case component::w:");
|
||||
statement(" return t.gather(s, spvForward<Ts>(params)..., component::w);");
|
||||
end_scope();
|
||||
end_scope();
|
||||
statement("");
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2680,11 +2846,41 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
|
||||
}
|
||||
|
||||
// Returns the texture sampling function string for the specified image and sampling characteristics.
|
||||
string CompilerMSL::to_function_name(uint32_t img, const SPIRType &, bool is_fetch, bool is_gather, bool, bool, bool,
|
||||
bool, bool has_dref, uint32_t)
|
||||
string CompilerMSL::to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool, bool,
|
||||
bool, bool, bool has_dref, uint32_t)
|
||||
{
|
||||
// Special-case gather. We have to alter the component being looked up
|
||||
// in the swizzle case.
|
||||
if (msl_options.swizzle_texture_samples && is_gather && !imgtype.image.depth)
|
||||
{
|
||||
string fname =
|
||||
"spvGatherSwizzle<" + type_to_glsl(get<SPIRType>(imgtype.image.type)) + ", " + type_to_glsl(imgtype);
|
||||
// Add the arg types ourselves. Yes, this sucks, but Clang can't
|
||||
// deduce template pack parameters in the middle of an argument list.
|
||||
switch (imgtype.image.dim)
|
||||
{
|
||||
case Dim2D:
|
||||
fname += ", float2";
|
||||
if (imgtype.image.arrayed)
|
||||
fname += ", uint";
|
||||
fname += ", int2";
|
||||
break;
|
||||
case DimCube:
|
||||
fname += ", float3";
|
||||
if (imgtype.image.arrayed)
|
||||
fname += ", uint";
|
||||
break;
|
||||
default:
|
||||
SPIRV_CROSS_THROW("Invalid texture dimension for gather op.");
|
||||
}
|
||||
fname += ">";
|
||||
return fname;
|
||||
}
|
||||
|
||||
// Texture reference
|
||||
string fname = to_expression(img) + ".";
|
||||
if (msl_options.swizzle_texture_samples && !is_gather && is_sampled_image_type(imgtype))
|
||||
fname = "spvTextureSwizzle(" + fname;
|
||||
|
||||
// Texture function and sampler
|
||||
if (is_fetch)
|
||||
@ -2701,7 +2897,7 @@ string CompilerMSL::to_function_name(uint32_t img, const SPIRType &, bool is_fet
|
||||
}
|
||||
|
||||
// Returns the function args for a texture sampling function for the specified image and sampling characteristics.
|
||||
string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool, bool is_proj,
|
||||
string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||
uint32_t coord, uint32_t, uint32_t dref, uint32_t grad_x, uint32_t grad_y,
|
||||
uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias, uint32_t comp,
|
||||
uint32_t sample, bool *p_forward)
|
||||
@ -2710,6 +2906,13 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
||||
if (!is_fetch)
|
||||
farg_str += to_sampler_expression(img);
|
||||
|
||||
if (msl_options.swizzle_texture_samples && is_gather && !imgtype.image.depth)
|
||||
{
|
||||
if (!farg_str.empty())
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(img);
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
bool forward = should_forward(coord);
|
||||
auto coord_expr = to_enclosed_expression(coord);
|
||||
@ -2958,6 +3161,28 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
||||
farg_str += to_expression(sample);
|
||||
}
|
||||
|
||||
if (msl_options.swizzle_texture_samples && is_sampled_image_type(imgtype) &&
|
||||
(!is_gather || !imgtype.image.depth))
|
||||
{
|
||||
// Add the swizzle constant from the swizzle buffer.
|
||||
if (!is_gather)
|
||||
farg_str += ")";
|
||||
// Get the original input variable for this image.
|
||||
uint32_t img_var = img;
|
||||
if (meta[img].image)
|
||||
img_var = meta[img].image;
|
||||
if (auto *var = maybe_get_backing_variable(img_var))
|
||||
{
|
||||
if (var->parameter && !var->parameter->alias_global_variable)
|
||||
SPIRV_CROSS_THROW("Cannot yet map non-aliased parameter to Metal resource!");
|
||||
img_var = var->self;
|
||||
}
|
||||
auto &aux_type = expression_type(aux_buffer_id);
|
||||
farg_str += ", " + to_name(aux_buffer_id) + "." + to_member_name(aux_type, k_aux_mbr_idx_swizzle_const) + "[" +
|
||||
convert_to_string(get_metal_resource_index(get<SPIRVariable>(img_var), SPIRType::Image)) + "]";
|
||||
used_aux_buffer = true;
|
||||
}
|
||||
|
||||
*p_forward = forward;
|
||||
|
||||
return farg_str;
|
||||
@ -3003,6 +3228,7 @@ void CompilerMSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_id
|
||||
{
|
||||
set<SPIRExpression>(result_id, to_expression(image_id), result_type, true);
|
||||
meta[result_id].sampler = samp_id;
|
||||
meta[result_id].image = image_id;
|
||||
}
|
||||
|
||||
// Returns a string representation of the ID, usable as a function arg.
|
||||
@ -4422,6 +4648,54 @@ bool CompilerMSL::skip_argument(uint32_t) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void CompilerMSL::analyze_sampled_image_usage()
|
||||
{
|
||||
if (msl_options.swizzle_texture_samples)
|
||||
{
|
||||
SampledImageScanner scanner(*this);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), scanner);
|
||||
}
|
||||
}
|
||||
|
||||
bool CompilerMSL::SampledImageScanner::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case OpLoad:
|
||||
case OpImage:
|
||||
case OpSampledImage:
|
||||
{
|
||||
if (length < 3)
|
||||
return false;
|
||||
|
||||
uint32_t result_type = args[0];
|
||||
auto &type = compiler.get<SPIRType>(result_type);
|
||||
if ((type.basetype != SPIRType::Image && type.basetype != SPIRType::SampledImage) || type.image.sampled != 1)
|
||||
return true;
|
||||
|
||||
uint32_t id = args[1];
|
||||
compiler.set<SPIRExpression>(id, "", result_type, true);
|
||||
break;
|
||||
}
|
||||
case OpImageSampleExplicitLod:
|
||||
case OpImageSampleProjExplicitLod:
|
||||
case OpImageSampleDrefExplicitLod:
|
||||
case OpImageSampleProjDrefExplicitLod:
|
||||
case OpImageSampleImplicitLod:
|
||||
case OpImageSampleProjImplicitLod:
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
case OpImageFetch:
|
||||
case OpImageGather:
|
||||
compiler.has_sampled_images = compiler.has_sampled_images ||
|
||||
compiler.is_sampled_image_type(compiler.expression_type(args[2]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t *args, uint32_t length)
|
||||
{
|
||||
// Since MSL exists in a single execution scope, function prototype declarations are not
|
||||
@ -4569,9 +4843,25 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
|
||||
if (tid && compiler.get<SPIRType>(tid).image.dim == DimBuffer)
|
||||
return SPVFuncImplTexelBufferCoords;
|
||||
|
||||
if (opcode == OpImageFetch && compiler.msl_options.swizzle_texture_samples)
|
||||
return SPVFuncImplTextureSwizzle;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OpImageSampleExplicitLod:
|
||||
case OpImageSampleProjExplicitLod:
|
||||
case OpImageSampleDrefExplicitLod:
|
||||
case OpImageSampleProjDrefExplicitLod:
|
||||
case OpImageSampleImplicitLod:
|
||||
case OpImageSampleProjImplicitLod:
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
case OpImageGather:
|
||||
if (compiler.msl_options.swizzle_texture_samples)
|
||||
return SPVFuncImplTextureSwizzle;
|
||||
break;
|
||||
|
||||
case OpCompositeConstruct:
|
||||
{
|
||||
auto &type = compiler.get<SPIRType>(args[0]);
|
||||
|
@ -152,9 +152,11 @@ public:
|
||||
Platform platform = macOS;
|
||||
uint32_t msl_version = make_msl_version(1, 2);
|
||||
uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers
|
||||
uint32_t aux_buffer_index = 0;
|
||||
bool enable_point_size_builtin = true;
|
||||
bool disable_rasterization = false;
|
||||
bool resolve_specialized_array_lengths = true;
|
||||
bool swizzle_texture_samples = false;
|
||||
|
||||
bool is_ios()
|
||||
{
|
||||
@ -211,6 +213,13 @@ public:
|
||||
return is_rasterization_disabled && (get_entry_point().model == spv::ExecutionModelVertex);
|
||||
}
|
||||
|
||||
// Provide feedback to calling API to allow it to pass an auxiliary
|
||||
// buffer if the shader needs it.
|
||||
bool needs_aux_buffer() const
|
||||
{
|
||||
return used_aux_buffer;
|
||||
}
|
||||
|
||||
// An enum of SPIR-V functions that are implemented in additional
|
||||
// source code that is added to the shader if necessary.
|
||||
enum SPVFuncImpl
|
||||
@ -241,6 +250,7 @@ public:
|
||||
SPVFuncImplRowMajor3x4,
|
||||
SPVFuncImplRowMajor4x2,
|
||||
SPVFuncImplRowMajor4x3,
|
||||
SPVFuncImplTextureSwizzle,
|
||||
SPVFuncImplArrayCopyMultidimMax = 6
|
||||
};
|
||||
|
||||
@ -374,10 +384,13 @@ protected:
|
||||
void emit_entry_point_declarations() override;
|
||||
uint32_t builtin_frag_coord_id = 0;
|
||||
uint32_t builtin_sample_id_id = 0;
|
||||
uint32_t aux_buffer_id = 0;
|
||||
|
||||
void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
|
||||
void analyze_sampled_image_usage();
|
||||
|
||||
Options msl_options;
|
||||
std::set<SPVFuncImpl> spv_function_implementations;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_location;
|
||||
@ -389,9 +402,11 @@ protected:
|
||||
MSLResourceBinding next_metal_resource_index;
|
||||
uint32_t stage_in_var_id = 0;
|
||||
uint32_t stage_out_var_id = 0;
|
||||
bool has_sampled_images = false;
|
||||
bool needs_vertex_idx_arg = false;
|
||||
bool needs_instance_idx_arg = false;
|
||||
bool is_rasterization_disabled = false;
|
||||
bool used_aux_buffer = false;
|
||||
std::string qual_pos_var_name;
|
||||
std::string stage_in_var_name = "in";
|
||||
std::string stage_out_var_name = "out";
|
||||
@ -419,6 +434,19 @@ protected:
|
||||
bool uses_resource_write = false;
|
||||
};
|
||||
|
||||
// OpcodeHandler that scans for uses of sampled images
|
||||
struct SampledImageScanner : OpcodeHandler
|
||||
{
|
||||
SampledImageScanner(CompilerMSL &compiler_)
|
||||
: compiler(compiler_)
|
||||
{
|
||||
}
|
||||
|
||||
bool handle(spv::Op opcode, const uint32_t *args, uint32_t) override;
|
||||
|
||||
CompilerMSL &compiler;
|
||||
};
|
||||
|
||||
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting
|
||||
// aspect, which defines which aspect of the struct members will be used to sort them.
|
||||
// Regardless of the sorting aspect, built-in members always appear at the end of the struct.
|
||||
|
@ -137,6 +137,8 @@ def cross_compile_msl(shader, spirv, opt):
|
||||
msl_args = [spirv_cross_path, '--entry', 'main', '--output', msl_path, spirv_path, '--msl']
|
||||
msl_args.append('--msl-version')
|
||||
msl_args.append(path_to_msl_standard_cli(shader))
|
||||
if '.swizzle.' in shader:
|
||||
msl_args.append('--msl-swizzle-texture-samples')
|
||||
|
||||
subprocess.check_call(msl_args)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user