mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-15 00:11:06 +00:00
Merge pull request #1113 from cdavis5e/msl-sampler-ycbcr-conversion
MSL: Add support for sampler Y'CbCr conversion.
This commit is contained in:
commit
a06997a6a4
@ -287,7 +287,7 @@ if (SPIRV_CROSS_STATIC)
|
||||
endif()
|
||||
|
||||
set(spirv-cross-abi-major 0)
|
||||
set(spirv-cross-abi-minor 16)
|
||||
set(spirv-cross-abi-minor 17)
|
||||
set(spirv-cross-abi-patch 0)
|
||||
|
||||
if (SPIRV_CROSS_SHARED)
|
||||
@ -461,6 +461,10 @@ if (SPIRV_CROSS_CLI)
|
||||
target_link_libraries(spirv-cross-msl-resource-binding-test spirv-cross-c)
|
||||
set_target_properties(spirv-cross-msl-resource-binding-test PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
|
||||
|
||||
add_executable(spirv-cross-msl-ycbcr-conversion-test tests-other/msl_ycbcr_conversion_test.cpp)
|
||||
target_link_libraries(spirv-cross-msl-ycbcr-conversion-test spirv-cross-c)
|
||||
set_target_properties(spirv-cross-msl-ycbcr-conversion-test PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))
|
||||
target_compile_options(spirv-cross-c-api-test PRIVATE -std=c89 -Wall -Wextra)
|
||||
endif()
|
||||
@ -475,6 +479,10 @@ if (SPIRV_CROSS_CLI)
|
||||
COMMAND $<TARGET_FILE:spirv-cross-msl-constexpr-test> ${CMAKE_CURRENT_SOURCE_DIR}/tests-other/msl_constexpr_test.spv)
|
||||
add_test(NAME spirv-cross-msl-resource-binding-test
|
||||
COMMAND $<TARGET_FILE:spirv-cross-msl-resource-binding-test> ${CMAKE_CURRENT_SOURCE_DIR}/tests-other/msl_resource_binding.spv)
|
||||
add_test(NAME spirv-cross-msl-ycbcr-conversion-test
|
||||
COMMAND $<TARGET_FILE:spirv-cross-msl-ycbcr-conversion-test> ${CMAKE_CURRENT_SOURCE_DIR}/tests-other/msl_ycbcr_conversion_test.spv)
|
||||
add_test(NAME spirv-cross-msl-ycbcr-conversion-test-2
|
||||
COMMAND $<TARGET_FILE:spirv-cross-msl-ycbcr-conversion-test> ${CMAKE_CURRENT_SOURCE_DIR}/tests-other/msl_ycbcr_conversion_test_2.spv)
|
||||
add_test(NAME spirv-cross-test
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
|
||||
${spirv-cross-externals}
|
||||
|
@ -5,17 +5,6 @@
|
||||
|
||||
using namespace metal;
|
||||
|
||||
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; };
|
||||
@ -28,6 +17,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -65,66 +65,6 @@ 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, const 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
kernel void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
|
||||
{
|
||||
constant uint& fooSwzl = spvSwizzleConstants[0];
|
||||
|
@ -22,17 +22,6 @@ struct main0_in
|
||||
float2 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
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; };
|
||||
@ -45,6 +34,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -82,66 +82,6 @@ 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, const 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> uSampler1 [[texture(0)]], sampler uSampler1Smplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
|
@ -15,17 +15,6 @@ struct main0_in
|
||||
float2 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
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; };
|
||||
@ -38,6 +27,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -75,66 +75,6 @@ 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, const 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant uint* spvSwizzleConstants [[buffer(30)]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
|
@ -11,17 +11,6 @@ inline 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; };
|
||||
@ -34,6 +23,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -72,8 +72,8 @@ inline T spvTextureSwizzle(T x, uint s)
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -109,8 +109,8 @@ inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params,
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(const thread Tex<T>& t, sampler s, uint sw, Ts... params)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -177,13 +177,13 @@ fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d
|
||||
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl);
|
||||
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl);
|
||||
c = texBuffer.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, metal::texture2d<float>, float2, int2>(tex2dSamp, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube<float>, float3>(texCubeSamp, texCube, float3(0.0), component::y, texCubeSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texture2d_array<float>, float2, uint, int2>(tex2dArraySamp, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube_array<float>, float3, uint>(texCubeArraySamp, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d<float>, float2, float>(depth2dSamp, depth2d, float2(0.0), 1.0, depth2dSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube<float>, float3, float>(depthCubeSamp, depthCube, float3(0.0), 1.0, depthCubeSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d_array<float>, float2, uint, float>(depth2dArraySamp, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, depth2dArraySwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube_array<float>, float3, uint, float>(depthCubeArraySamp, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, depthCubeArraySwzl);
|
||||
c = spvGatherSwizzle(tex2d, tex2dSamp, tex2dSwzl, component::x, float2(0.0), int2(0));
|
||||
c = spvGatherSwizzle(texCube, texCubeSamp, texCubeSwzl, component::y, float3(0.0));
|
||||
c = spvGatherSwizzle(tex2dArray, tex2dArraySamp, tex2dArraySwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0));
|
||||
c = spvGatherSwizzle(texCubeArray, texCubeArraySamp, texCubeArraySwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w)));
|
||||
c = spvGatherCompareSwizzle(depth2d, depth2dSamp, depth2dSwzl, float2(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(depthCube, depthCubeSamp, depthCubeSwzl, float3(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(depth2dArray, depth2dArraySamp, depth2dArraySwzl, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = spvGatherCompareSwizzle(depthCubeArray, depthCubeArraySamp, depthCubeArraySwzl, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
}
|
||||
|
||||
|
@ -11,17 +11,6 @@ inline 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; };
|
||||
@ -34,6 +23,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -72,8 +72,8 @@ inline T spvTextureSwizzle(T x, uint s)
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -108,29 +108,6 @@ inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params,
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], 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)]])
|
||||
{
|
||||
constant uint& tex1dSwzl = spvSwizzleConstants[0];
|
||||
@ -162,9 +139,9 @@ fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d
|
||||
c = float4(spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl));
|
||||
c = float4(texBuffer.read(spvTexelBufferCoord(0)));
|
||||
c = float4(spvGatherSwizzle<int, metal::texture2d<int>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl));
|
||||
c = float4(spvGatherSwizzle<int, metal::texturecube<int>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl));
|
||||
c = float4(spvGatherSwizzle<int, metal::texture2d_array<int>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl));
|
||||
c = float4(spvGatherSwizzle<int, metal::texturecube_array<int>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl));
|
||||
c = float4(spvGatherSwizzle(tex2d, tex2dSmplr, tex2dSwzl, component::x, float2(0.0), int2(0)));
|
||||
c = float4(spvGatherSwizzle(texCube, texCubeSmplr, texCubeSwzl, component::y, float3(0.0)));
|
||||
c = float4(spvGatherSwizzle(tex2dArray, tex2dArraySmplr, tex2dArraySwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0)));
|
||||
c = float4(spvGatherSwizzle(texCubeArray, texCubeArraySmplr, texCubeArraySwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w))));
|
||||
}
|
||||
|
||||
|
@ -11,17 +11,6 @@ inline 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; };
|
||||
@ -34,6 +23,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -72,8 +72,8 @@ inline T spvTextureSwizzle(T x, uint s)
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -109,8 +109,8 @@ inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params,
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(const thread Tex<T>& t, sampler s, uint sw, Ts... params)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -167,14 +167,14 @@ inline float4 doSwizzle(thread texture1d<float> tex1d, thread const sampler tex1
|
||||
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl);
|
||||
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl);
|
||||
c = texBuffer.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, metal::texture2d<float>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube<float>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texture2d_array<float>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube_array<float>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d<float>, float2, float>(depth2dSmplr, depth2d, float2(0.0), 1.0, depth2dSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube<float>, float3, float>(depthCubeSmplr, depthCube, float3(0.0), 1.0, depthCubeSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d_array<float>, float2, uint, float>(depth2dArraySmplr, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, depth2dArraySwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube_array<float>, float3, uint, float>(depthCubeArraySmplr, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, depthCubeArraySwzl);
|
||||
c = spvGatherSwizzle(tex2d, tex2dSmplr, tex2dSwzl, component::x, float2(0.0), int2(0));
|
||||
c = spvGatherSwizzle(texCube, texCubeSmplr, texCubeSwzl, component::y, float3(0.0));
|
||||
c = spvGatherSwizzle(tex2dArray, tex2dArraySmplr, tex2dArraySwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0));
|
||||
c = spvGatherSwizzle(texCubeArray, texCubeArraySmplr, texCubeArraySwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w)));
|
||||
c = spvGatherCompareSwizzle(depth2d, depth2dSmplr, depth2dSwzl, float2(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(depthCube, depthCubeSmplr, depthCubeSwzl, float3(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(depth2dArray, depth2dArraySmplr, depth2dArraySwzl, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = spvGatherCompareSwizzle(depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -11,17 +11,6 @@ inline 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; };
|
||||
@ -34,6 +23,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -72,8 +72,8 @@ inline T spvTextureSwizzle(T x, uint s)
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -108,29 +108,6 @@ inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params,
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], 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)]])
|
||||
{
|
||||
constant uint& tex1dSwzl = spvSwizzleConstants[0];
|
||||
@ -162,9 +139,9 @@ fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d
|
||||
c = float4(spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl));
|
||||
c = float4(spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl));
|
||||
c = float4(texBuffer.read(spvTexelBufferCoord(0)));
|
||||
c = float4(spvGatherSwizzle<uint, metal::texture2d<uint>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl));
|
||||
c = float4(spvGatherSwizzle<uint, metal::texturecube<uint>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl));
|
||||
c = float4(spvGatherSwizzle<uint, metal::texture2d_array<uint>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl));
|
||||
c = float4(spvGatherSwizzle<uint, metal::texturecube_array<uint>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl));
|
||||
c = float4(spvGatherSwizzle(tex2d, tex2dSmplr, tex2dSwzl, component::x, float2(0.0), int2(0)));
|
||||
c = float4(spvGatherSwizzle(texCube, texCubeSmplr, texCubeSwzl, component::y, float3(0.0)));
|
||||
c = float4(spvGatherSwizzle(tex2dArray, tex2dArraySmplr, tex2dArraySwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0)));
|
||||
c = float4(spvGatherSwizzle(texCubeArray, texCubeArraySmplr, texCubeArraySwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w))));
|
||||
}
|
||||
|
||||
|
@ -11,17 +11,6 @@ inline 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; };
|
||||
@ -34,6 +23,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -72,8 +72,8 @@ inline T spvTextureSwizzle(T x, uint s)
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -109,8 +109,8 @@ inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params,
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(const thread Tex<T>& t, sampler s, uint sw, Ts... params)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -177,13 +177,13 @@ fragment void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture1d
|
||||
c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl);
|
||||
c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl);
|
||||
c = texBuffer.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, metal::texture2d<float>, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube<float>, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texture2d_array<float>, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube_array<float>, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d<float>, float2, float>(depth2dSmplr, depth2d, float2(0.0), 1.0, depth2dSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube<float>, float3, float>(depthCubeSmplr, depthCube, float3(0.0), 1.0, depthCubeSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d_array<float>, float2, uint, float>(depth2dArraySmplr, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, depth2dArraySwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube_array<float>, float3, uint, float>(depthCubeArraySmplr, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, depthCubeArraySwzl);
|
||||
c = spvGatherSwizzle(tex2d, tex2dSmplr, tex2dSwzl, component::x, float2(0.0), int2(0));
|
||||
c = spvGatherSwizzle(texCube, texCubeSmplr, texCubeSwzl, component::y, float3(0.0));
|
||||
c = spvGatherSwizzle(tex2dArray, tex2dArraySmplr, tex2dArraySwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0));
|
||||
c = spvGatherSwizzle(texCubeArray, texCubeArraySmplr, texCubeArraySwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w)));
|
||||
c = spvGatherCompareSwizzle(depth2d, depth2dSmplr, depth2dSwzl, float2(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(depthCube, depthCubeSmplr, depthCubeSwzl, float3(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(depth2dArray, depth2dArraySmplr, depth2dArraySwzl, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = spvGatherCompareSwizzle(depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
}
|
||||
|
||||
|
@ -16,17 +16,6 @@ inline 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; };
|
||||
@ -39,6 +28,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -77,8 +77,8 @@ inline T spvTextureSwizzle(T x, uint s)
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherSwizzle(const thread Tex<T>& t, sampler s, uint sw, component c, Ts... params) METAL_CONST_ARG(c)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -114,8 +114,8 @@ inline vec<T, 4> spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params,
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
template<typename T, template<typename, access = access::sample, typename = void> class Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(const thread Tex<T>& t, sampler s, uint sw, Ts... params)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
@ -172,14 +172,14 @@ inline float4 do_samples(thread const texture1d<float> t1, thread const sampler
|
||||
c = spvTextureSwizzle(t3.read(uint3(int3(0)), 0), t3Swzl);
|
||||
c = spvTextureSwizzle(t2a.read(uint2(int3(0).xy), uint(int3(0).z), 0), t2aSwzl);
|
||||
c = tb.read(spvTexelBufferCoord(0));
|
||||
c = spvGatherSwizzle<float, metal::texture2d<float>, float2, int2>(defaultSampler, t2, float2(0.0), int2(0), component::x, t2Swzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube<float>, float3>(defaultSampler, tc, float3(0.0), component::y, tcSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texture2d_array<float>, float2, uint, int2>(t2aSmplr, t2a, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, t2aSwzl);
|
||||
c = spvGatherSwizzle<float, metal::texturecube_array<float>, float3, uint>(tcaSmplr, tca, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, tcaSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d<float>, float2, float>(d2Smplr, d2, float2(0.0), 1.0, d2Swzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube<float>, float3, float>(dcSmplr, dc, float3(0.0), 1.0, dcSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depth2d_array<float>, float2, uint, float>(shadowSampler, d2a, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, d2aSwzl);
|
||||
c = spvGatherCompareSwizzle<float, metal::depthcube_array<float>, float3, uint, float>(dcaSmplr, dca, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, dcaSwzl);
|
||||
c = spvGatherSwizzle(t2, defaultSampler, t2Swzl, component::x, float2(0.0), int2(0));
|
||||
c = spvGatherSwizzle(tc, defaultSampler, tcSwzl, component::y, float3(0.0));
|
||||
c = spvGatherSwizzle(t2a, t2aSmplr, t2aSwzl, component::z, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0));
|
||||
c = spvGatherSwizzle(tca, tcaSmplr, tcaSwzl, component::w, float4(0.0).xyz, uint(round(float4(0.0).w)));
|
||||
c = spvGatherCompareSwizzle(d2, d2Smplr, d2Swzl, float2(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(dc, dcSmplr, dcSwzl, float3(0.0), 1.0);
|
||||
c = spvGatherCompareSwizzle(d2a, shadowSampler, d2aSwzl, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0);
|
||||
c = spvGatherCompareSwizzle(dca, dcaSmplr, dcaSwzl, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -5,17 +5,6 @@
|
||||
|
||||
using namespace metal;
|
||||
|
||||
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; };
|
||||
@ -28,6 +17,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -65,66 +65,6 @@ 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, const 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
kernel void main0(constant uint* spvSwizzleConstants [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
|
||||
{
|
||||
constant uint& fooSwzl = spvSwizzleConstants[0];
|
||||
|
@ -22,17 +22,6 @@ struct main0_in
|
||||
float2 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
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; };
|
||||
@ -45,6 +34,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -82,66 +82,6 @@ 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, const 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
inline float4 sample_in_func_1(thread const array<texture2d<float>, 4> uSampler0, thread const array<sampler, 4> uSampler0Smplr, constant uint* uSampler0Swzl, thread float2& vUV)
|
||||
{
|
||||
return spvTextureSwizzle(uSampler0[2].sample(uSampler0Smplr[2], vUV), uSampler0Swzl[2]);
|
||||
|
@ -15,17 +15,6 @@ struct main0_in
|
||||
float2 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
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; };
|
||||
@ -38,6 +27,17 @@ template<typename T> inline constexpr thread T&& spvForward(thread typename spvR
|
||||
return static_cast<thread T&&>(x);
|
||||
}
|
||||
|
||||
enum class spvSwizzle : uint
|
||||
{
|
||||
none = 0,
|
||||
zero,
|
||||
one,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T spvGetSwizzle(vec<T, 4> x, T c, spvSwizzle s)
|
||||
{
|
||||
@ -75,66 +75,6 @@ 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, const 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function that swizzles depth texture gathers.
|
||||
template<typename T, typename Tex, typename... Ts>
|
||||
inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw)
|
||||
{
|
||||
if (sw)
|
||||
{
|
||||
switch (spvSwizzle(sw & 0xFF))
|
||||
{
|
||||
case spvSwizzle::none:
|
||||
case spvSwizzle::red:
|
||||
break;
|
||||
case spvSwizzle::zero:
|
||||
case spvSwizzle::green:
|
||||
case spvSwizzle::blue:
|
||||
case spvSwizzle::alpha:
|
||||
return vec<T, 4>(0, 0, 0, 0);
|
||||
case spvSwizzle::one:
|
||||
return vec<T, 4>(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
return t.gather_compare(s, spvForward<Ts>(params)...);
|
||||
}
|
||||
|
||||
inline float4 sample_in_func(thread const array<texture2d<float>, 4> uSampler, thread const array<sampler, 4> uSamplerSmplr, constant uint* uSamplerSwzl, thread float2& vUV)
|
||||
{
|
||||
return spvTextureSwizzle(uSampler[2].sample(uSamplerSmplr[2], vUV), uSamplerSwzl[2]);
|
||||
|
@ -1431,6 +1431,9 @@ enum ExtendedDecorations
|
||||
// Used for decorations like resource indices for samplers when part of combined image samplers.
|
||||
// A variable might need to hold two resource indices in this case.
|
||||
SPIRVCrossDecorationResourceIndexSecondary,
|
||||
// Used for resource indices for multiplanar images when part of combined image samplers.
|
||||
SPIRVCrossDecorationResourceIndexTertiary,
|
||||
SPIRVCrossDecorationResourceIndexQuaternary,
|
||||
|
||||
// Marks a buffer block for using explicit offsets (GLSL/HLSL).
|
||||
SPIRVCrossDecorationExplicitOffset,
|
||||
@ -1439,6 +1442,12 @@ enum ExtendedDecorations
|
||||
// In MSL, this is used to adjust the WorkgroupId and GlobalInvocationId variables.
|
||||
SPIRVCrossDecorationBuiltInDispatchBase,
|
||||
|
||||
// Apply to a variable that is a function parameter; marks it as being a "dynamic"
|
||||
// combined image-sampler. In MSL, this is used when a function parameter might hold
|
||||
// either a regular combined image-sampler or one that has an attached sampler
|
||||
// Y'CbCr conversion.
|
||||
SPIRVCrossDecorationDynamicImageSampler,
|
||||
|
||||
SPIRVCrossDecorationCount
|
||||
};
|
||||
|
||||
|
@ -1152,6 +1152,8 @@ static uint32_t get_default_extended_decoration(ExtendedDecorations decoration)
|
||||
{
|
||||
case SPIRVCrossDecorationResourceIndexPrimary:
|
||||
case SPIRVCrossDecorationResourceIndexSecondary:
|
||||
case SPIRVCrossDecorationResourceIndexTertiary:
|
||||
case SPIRVCrossDecorationResourceIndexQuaternary:
|
||||
case SPIRVCrossDecorationInterfaceMemberIndex:
|
||||
return ~(0u);
|
||||
|
||||
|
@ -545,6 +545,26 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_MSL_BUFFER_SIZE_BUFFER_INDEX:
|
||||
options->msl.buffer_size_buffer_index = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_MULTIVIEW:
|
||||
options->msl.multiview = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_VIEW_MASK_BUFFER_INDEX:
|
||||
options->msl.view_mask_buffer_index = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_DEVICE_INDEX:
|
||||
options->msl.device_index = value;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_VIEW_INDEX_FROM_DEVICE_INDEX:
|
||||
options->msl.view_index_from_device_index = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_DISPATCH_BASE:
|
||||
options->msl.dispatch_base = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@ -960,6 +980,22 @@ static void spvc_convert_msl_sampler(MSLConstexprSampler &samp, const spvc_msl_c
|
||||
samp.coord = static_cast<MSLSamplerCoord>(sampler->coord);
|
||||
samp.border_color = static_cast<MSLSamplerBorderColor>(sampler->border_color);
|
||||
}
|
||||
|
||||
static void spvc_convert_msl_sampler_ycbcr_conversion(MSLConstexprSampler &samp, const spvc_msl_sampler_ycbcr_conversion *conv)
|
||||
{
|
||||
samp.ycbcr_conversion_enable = conv != nullptr;
|
||||
if (conv == nullptr) return;
|
||||
samp.planes = conv->planes;
|
||||
samp.resolution = static_cast<MSLFormatResolution>(conv->resolution);
|
||||
samp.chroma_filter = static_cast<MSLSamplerFilter>(conv->chroma_filter);
|
||||
samp.x_chroma_offset = static_cast<MSLChromaLocation>(conv->x_chroma_offset);
|
||||
samp.y_chroma_offset = static_cast<MSLChromaLocation>(conv->y_chroma_offset);
|
||||
for (int i = 0; i < 4; i++)
|
||||
samp.swizzle[i] = static_cast<MSLComponentSwizzle>(conv->swizzle[i]);
|
||||
samp.ycbcr_model = static_cast<MSLSamplerYCbCrModelConversion>(conv->ycbcr_model);
|
||||
samp.ycbcr_range = static_cast<MSLSamplerYCbCrRange>(conv->ycbcr_range);
|
||||
samp.bpc = conv->bpc;
|
||||
}
|
||||
#endif
|
||||
|
||||
spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id,
|
||||
@ -1010,6 +1046,60 @@ spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler c
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_remap_constexpr_sampler_ycbcr(spvc_compiler compiler, spvc_variable_id id,
|
||||
const spvc_msl_constexpr_sampler *sampler,
|
||||
const spvc_msl_sampler_ycbcr_conversion *conv)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLConstexprSampler samp;
|
||||
spvc_convert_msl_sampler(samp, sampler);
|
||||
spvc_convert_msl_sampler_ycbcr_conversion(samp, conv);
|
||||
msl.remap_constexpr_sampler(id, samp);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)id;
|
||||
(void)sampler;
|
||||
(void)conv;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(spvc_compiler compiler,
|
||||
unsigned desc_set, unsigned binding,
|
||||
const spvc_msl_constexpr_sampler *sampler,
|
||||
const spvc_msl_sampler_ycbcr_conversion *conv)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLConstexprSampler samp;
|
||||
spvc_convert_msl_sampler(samp, sampler);
|
||||
spvc_convert_msl_sampler_ycbcr_conversion(samp, conv);
|
||||
msl.remap_constexpr_sampler_by_binding(desc_set, binding, samp);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)desc_set;
|
||||
(void)binding;
|
||||
(void)sampler;
|
||||
(void)conv;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location,
|
||||
unsigned components)
|
||||
{
|
||||
@ -1997,6 +2087,24 @@ void spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler *sampler)
|
||||
#endif
|
||||
}
|
||||
|
||||
void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
MSLConstexprSampler defaults;
|
||||
conv->planes = defaults.planes;
|
||||
conv->resolution = static_cast<spvc_msl_format_resolution>(defaults.resolution);
|
||||
conv->chroma_filter = static_cast<spvc_msl_sampler_filter>(defaults.chroma_filter);
|
||||
conv->x_chroma_offset = static_cast<spvc_msl_chroma_location>(defaults.x_chroma_offset);
|
||||
conv->y_chroma_offset = static_cast<spvc_msl_chroma_location>(defaults.y_chroma_offset);
|
||||
for (int i = 0; i < 4; i++)
|
||||
conv->swizzle[i] = static_cast<spvc_msl_component_swizzle>(defaults.swizzle[i]);
|
||||
conv->ycbcr_model = static_cast<spvc_msl_sampler_ycbcr_model_conversion>(defaults.ycbcr_model);
|
||||
conv->ycbcr_range = static_cast<spvc_msl_sampler_ycbcr_range>(defaults.ycbcr_range);
|
||||
#else
|
||||
memset(conv, 0, sizeof(*conv));
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned spvc_compiler_get_current_id_bound(spvc_compiler compiler)
|
||||
{
|
||||
return compiler->compiler->get_current_id_bound();
|
||||
|
@ -33,7 +33,7 @@ extern "C" {
|
||||
/* Bumped if ABI or API breaks backwards compatibility. */
|
||||
#define SPVC_C_API_VERSION_MAJOR 0
|
||||
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
|
||||
#define SPVC_C_API_VERSION_MINOR 16
|
||||
#define SPVC_C_API_VERSION_MINOR 17
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
@ -370,6 +370,55 @@ typedef enum spvc_msl_sampler_border_color
|
||||
SPVC_MSL_SAMPLER_BORDER_COLOR_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_border_color;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_format_resolution
|
||||
{
|
||||
SPVC_MSL_FORMAT_RESOLUTION_444 = 0,
|
||||
SPVC_MSL_FORMAT_RESOLUTION_422,
|
||||
SPVC_MSL_FORMAT_RESOLUTION_420,
|
||||
SPVC_MSL_FORMAT_RESOLUTION_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_format_resolution;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_chroma_location
|
||||
{
|
||||
SPVC_MSL_CHROMA_LOCATION_COSITED_EVEN = 0,
|
||||
SPVC_MSL_CHROMA_LOCATION_MIDPOINT,
|
||||
SPVC_MSL_CHROMA_LOCATION_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_chroma_location;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_component_swizzle
|
||||
{
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_IDENTITY = 0,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_ZERO,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_ONE,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_R,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_G,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_B,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_A,
|
||||
SPVC_MSL_COMPONENT_SWIZZLE_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_component_swizzle;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_ycbcr_model_conversion
|
||||
{
|
||||
SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0,
|
||||
SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY,
|
||||
SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_709,
|
||||
SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_601,
|
||||
SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_2020,
|
||||
SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_ycbcr_model_conversion;
|
||||
|
||||
/* Maps to C+ API. */
|
||||
typedef enum spvc_msl_sampler_ycbcr_range
|
||||
{
|
||||
SPVC_MSL_SAMPLER_YCBCR_RANGE_ITU_FULL = 0,
|
||||
SPVC_MSL_SAMPLER_YCBCR_RANGE_ITU_NARROW,
|
||||
SPVC_MSL_SAMPLER_YCBCR_RANGE_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_ycbcr_range;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_constexpr_sampler
|
||||
{
|
||||
@ -397,6 +446,26 @@ typedef struct spvc_msl_constexpr_sampler
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler *sampler);
|
||||
|
||||
/* Maps to the sampler Y'CbCr conversion-related portions of MSLConstexprSampler. See C++ API for defaults and details. */
|
||||
typedef struct spvc_msl_sampler_ycbcr_conversion
|
||||
{
|
||||
unsigned planes;
|
||||
spvc_msl_format_resolution resolution;
|
||||
spvc_msl_sampler_filter chroma_filter;
|
||||
spvc_msl_chroma_location x_chroma_offset;
|
||||
spvc_msl_chroma_location y_chroma_offset;
|
||||
spvc_msl_component_swizzle swizzle[4];
|
||||
spvc_msl_sampler_ycbcr_model_conversion ycbcr_model;
|
||||
spvc_msl_sampler_ycbcr_range ycbcr_range;
|
||||
unsigned bpc;
|
||||
} spvc_msl_sampler_ycbcr_conversion;
|
||||
|
||||
/*
|
||||
* Initializes the constexpr sampler struct.
|
||||
* The defaults are non-zero.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv);
|
||||
|
||||
/* Maps to the various spirv_cross::Compiler*::Option structures. See C++ API for defaults and details. */
|
||||
typedef enum spvc_compiler_option
|
||||
{
|
||||
@ -452,6 +521,12 @@ typedef enum spvc_compiler_option
|
||||
|
||||
SPVC_COMPILER_OPTION_EMIT_LINE_DIRECTIVES = 37 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_MULTIVIEW = 38 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_VIEW_MASK_BUFFER_INDEX = 39 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_DEVICE_INDEX = 40 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_VIEW_INDEX_FROM_DEVICE_INDEX = 41 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_DISPATCH_BASE = 42 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
@ -550,6 +625,8 @@ SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compi
|
||||
unsigned binding);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler, unsigned desc_set, unsigned binding, const spvc_msl_constexpr_sampler *sampler);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_ycbcr(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler, const spvc_msl_sampler_ycbcr_conversion *conv);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(spvc_compiler compiler, unsigned desc_set, unsigned binding, const spvc_msl_constexpr_sampler *sampler, const spvc_msl_sampler_ycbcr_conversion *conv);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location, unsigned components);
|
||||
|
||||
SPVC_PUBLIC_API unsigned spvc_compiler_msl_get_automatic_resource_binding(spvc_compiler compiler, spvc_variable_id id);
|
||||
|
@ -2719,7 +2719,7 @@ void CompilerGLSL::emit_resources()
|
||||
// Returns a string representation of the ID, usable as a function arg.
|
||||
// Default is to simply return the expression representation fo the arg ID.
|
||||
// Subclasses may override to modify the return value.
|
||||
string CompilerGLSL::to_func_call_arg(uint32_t id)
|
||||
string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &, uint32_t id)
|
||||
{
|
||||
// Make sure that we use the name of the original variable, and not the parameter alias.
|
||||
uint32_t name_id = id;
|
||||
@ -4796,12 +4796,40 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
SmallVector<uint32_t> inherited_expressions;
|
||||
|
||||
uint32_t result_type_id = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
|
||||
bool forward = false;
|
||||
string expr = to_texture_op(i, &forward, inherited_expressions);
|
||||
emit_op(result_type_id, id, expr, forward);
|
||||
for (auto &inherit : inherited_expressions)
|
||||
inherit_expression_dependencies(id, inherit);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleImplicitLod:
|
||||
case OpImageSampleProjImplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
register_control_dependent_expression(id);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CompilerGLSL::to_texture_op(const Instruction &i, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
uint32_t result_type_id = ops[0];
|
||||
uint32_t img = ops[2];
|
||||
uint32_t coord = ops[3];
|
||||
uint32_t dref = 0;
|
||||
@ -4942,12 +4970,11 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
test(minlod, ImageOperandsMinLodMask);
|
||||
|
||||
string expr;
|
||||
bool forward = false;
|
||||
expr += to_function_name(img, imgtype, !!fetch, !!gather, !!proj, !!coffsets, (!!coffset || !!offset),
|
||||
(!!grad_x || !!grad_y), !!dref, lod, minlod);
|
||||
expr += "(";
|
||||
expr += to_function_args(img, imgtype, fetch, gather, proj, coord, coord_components, dref, grad_x, grad_y, lod,
|
||||
coffset, offset, bias, comp, sample, minlod, &forward);
|
||||
coffset, offset, bias, comp, sample, minlod, forward);
|
||||
expr += ")";
|
||||
|
||||
// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
|
||||
@ -4989,22 +5016,7 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
if (op == OpImageRead)
|
||||
expr = remap_swizzle(result_type, 4, expr);
|
||||
|
||||
emit_op(result_type_id, id, expr, forward);
|
||||
for (auto &inherit : inherited_expressions)
|
||||
inherit_expression_dependencies(id, inherit);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleImplicitLod:
|
||||
case OpImageSampleProjImplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
register_control_dependent_expression(id);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
bool CompilerGLSL::expression_is_constant_null(uint32_t id) const
|
||||
@ -8078,7 +8090,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
if (skip_argument(arg[i]))
|
||||
continue;
|
||||
|
||||
arglist.push_back(to_func_call_arg(arg[i]));
|
||||
arglist.push_back(to_func_call_arg(callee.arguments[i], arg[i]));
|
||||
}
|
||||
|
||||
for (auto &combined : callee.combined_parameters)
|
||||
@ -10126,7 +10138,7 @@ void CompilerGLSL::append_global_func_args(const SPIRFunction &func, uint32_t in
|
||||
if (var_id)
|
||||
flush_variable_declaration(var_id);
|
||||
|
||||
arglist.push_back(to_func_call_arg(arg.id));
|
||||
arglist.push_back(to_func_call_arg(arg, arg.id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,8 @@ protected:
|
||||
|
||||
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
||||
virtual void emit_texture_op(const Instruction &i);
|
||||
virtual std::string to_texture_op(const Instruction &i, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions);
|
||||
virtual void emit_subgroup_op(const Instruction &i);
|
||||
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
|
||||
virtual std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage);
|
||||
@ -256,7 +258,7 @@ protected:
|
||||
virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector);
|
||||
virtual void emit_fixup();
|
||||
virtual std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0);
|
||||
virtual std::string to_func_call_arg(uint32_t id);
|
||||
virtual std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id);
|
||||
virtual std::string to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
|
||||
bool is_proj, bool has_array_offsets, bool has_offset, bool has_grad,
|
||||
bool has_dref, uint32_t lod, uint32_t minlod);
|
||||
|
@ -2014,9 +2014,9 @@ void CompilerHLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerHLSL::to_func_call_arg(uint32_t id)
|
||||
string CompilerHLSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id)
|
||||
{
|
||||
string arg_str = CompilerGLSL::to_func_call_arg(id);
|
||||
string arg_str = CompilerGLSL::to_func_call_arg(arg, id);
|
||||
|
||||
if (hlsl_options.shader_model <= 30)
|
||||
return arg_str;
|
||||
|
@ -145,7 +145,7 @@ private:
|
||||
std::string layout_for_member(const SPIRType &type, uint32_t index) override;
|
||||
std::string to_interpolation_qualifiers(const Bitset &flags) override;
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
|
||||
std::string to_func_call_arg(uint32_t id) override;
|
||||
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
|
||||
std::string to_sampler_expression(uint32_t id);
|
||||
std::string to_resource_binding(const SPIRVariable &var);
|
||||
std::string to_resource_binding_sampler(const SPIRVariable &var);
|
||||
|
1536
spirv_msl.cpp
1536
spirv_msl.cpp
File diff suppressed because it is too large
Load Diff
119
spirv_msl.hpp
119
spirv_msl.hpp
@ -122,6 +122,50 @@ enum MSLSamplerBorderColor
|
||||
MSL_SAMPLER_BORDER_COLOR_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLFormatResolution
|
||||
{
|
||||
MSL_FORMAT_RESOLUTION_444 = 0,
|
||||
MSL_FORMAT_RESOLUTION_422,
|
||||
MSL_FORMAT_RESOLUTION_420,
|
||||
MSL_FORMAT_RESOLUTION_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLChromaLocation
|
||||
{
|
||||
MSL_CHROMA_LOCATION_COSITED_EVEN = 0,
|
||||
MSL_CHROMA_LOCATION_MIDPOINT,
|
||||
MSL_CHROMA_LOCATION_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLComponentSwizzle
|
||||
{
|
||||
MSL_COMPONENT_SWIZZLE_IDENTITY = 0,
|
||||
MSL_COMPONENT_SWIZZLE_ZERO,
|
||||
MSL_COMPONENT_SWIZZLE_ONE,
|
||||
MSL_COMPONENT_SWIZZLE_R,
|
||||
MSL_COMPONENT_SWIZZLE_G,
|
||||
MSL_COMPONENT_SWIZZLE_B,
|
||||
MSL_COMPONENT_SWIZZLE_A,
|
||||
MSL_COMPONENT_SWIZZLE_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerYCbCrModelConversion
|
||||
{
|
||||
MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0,
|
||||
MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY,
|
||||
MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_709,
|
||||
MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_601,
|
||||
MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_2020,
|
||||
MSL_SAMPLER_YCBCR_MODEL_CONVERSION_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerYCbCrRange
|
||||
{
|
||||
MSL_SAMPLER_YCBCR_RANGE_ITU_FULL = 0,
|
||||
MSL_SAMPLER_YCBCR_RANGE_ITU_NARROW,
|
||||
MSL_SAMPLER_YCBCR_RANGE_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
struct MSLConstexprSampler
|
||||
{
|
||||
MSLSamplerCoord coord = MSL_SAMPLER_COORD_NORMALIZED;
|
||||
@ -137,9 +181,39 @@ struct MSLConstexprSampler
|
||||
float lod_clamp_max = 1000.0f;
|
||||
int max_anisotropy = 1;
|
||||
|
||||
// Sampler Y'CbCr conversion parameters
|
||||
uint32_t planes = 0;
|
||||
MSLFormatResolution resolution = MSL_FORMAT_RESOLUTION_444;
|
||||
MSLSamplerFilter chroma_filter = MSL_SAMPLER_FILTER_NEAREST;
|
||||
MSLChromaLocation x_chroma_offset = MSL_CHROMA_LOCATION_COSITED_EVEN;
|
||||
MSLChromaLocation y_chroma_offset = MSL_CHROMA_LOCATION_COSITED_EVEN;
|
||||
MSLComponentSwizzle swizzle[4]; // IDENTITY, IDENTITY, IDENTITY, IDENTITY
|
||||
MSLSamplerYCbCrModelConversion ycbcr_model = MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
|
||||
MSLSamplerYCbCrRange ycbcr_range = MSL_SAMPLER_YCBCR_RANGE_ITU_FULL;
|
||||
uint32_t bpc = 8;
|
||||
|
||||
bool compare_enable = false;
|
||||
bool lod_clamp_enable = false;
|
||||
bool anisotropy_enable = false;
|
||||
bool ycbcr_conversion_enable = false;
|
||||
|
||||
MSLConstexprSampler()
|
||||
{
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
swizzle[i] = MSL_COMPONENT_SWIZZLE_IDENTITY;
|
||||
}
|
||||
bool swizzle_is_identity() const
|
||||
{
|
||||
return (swizzle[0] == MSL_COMPONENT_SWIZZLE_IDENTITY && swizzle[1] == MSL_COMPONENT_SWIZZLE_IDENTITY &&
|
||||
swizzle[2] == MSL_COMPONENT_SWIZZLE_IDENTITY && swizzle[3] == MSL_COMPONENT_SWIZZLE_IDENTITY);
|
||||
}
|
||||
bool swizzle_has_one_or_zero() const
|
||||
{
|
||||
return (swizzle[0] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[0] == MSL_COMPONENT_SWIZZLE_ONE ||
|
||||
swizzle[1] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[1] == MSL_COMPONENT_SWIZZLE_ONE ||
|
||||
swizzle[2] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[2] == MSL_COMPONENT_SWIZZLE_ONE ||
|
||||
swizzle[3] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[3] == MSL_COMPONENT_SWIZZLE_ONE);
|
||||
}
|
||||
};
|
||||
|
||||
// Special constant used in a MSLResourceBinding desc_set
|
||||
@ -349,6 +423,14 @@ public:
|
||||
// sampler's binding is returned instead. For any other resource type, -1 is returned.
|
||||
uint32_t get_automatic_msl_resource_binding_secondary(uint32_t id) const;
|
||||
|
||||
// Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers for multiplanar images,
|
||||
// in which case the second plane's binding is returned instead. For any other resource type, -1 is returned.
|
||||
uint32_t get_automatic_msl_resource_binding_tertiary(uint32_t id) const;
|
||||
|
||||
// Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers for triplanar images,
|
||||
// in which case the third plane's binding is returned instead. For any other resource type, -1 is returned.
|
||||
uint32_t get_automatic_msl_resource_binding_quaternary(uint32_t id) const;
|
||||
|
||||
// Compiles the SPIR-V code into Metal Shading Language.
|
||||
std::string compile() override;
|
||||
|
||||
@ -395,7 +477,14 @@ protected:
|
||||
SPVFuncImplInverse4x4,
|
||||
SPVFuncImplInverse3x3,
|
||||
SPVFuncImplInverse2x2,
|
||||
// It is very important that this come before *Swizzle and ChromaReconstruct*, to ensure it's
|
||||
// emitted before them.
|
||||
SPVFuncImplForwardArgs,
|
||||
// Likewise, this must come before *Swizzle.
|
||||
SPVFuncImplGetSwizzle,
|
||||
SPVFuncImplTextureSwizzle,
|
||||
SPVFuncImplGatherSwizzle,
|
||||
SPVFuncImplGatherCompareSwizzle,
|
||||
SPVFuncImplSubgroupBallot,
|
||||
SPVFuncImplSubgroupBallotBitExtract,
|
||||
SPVFuncImplSubgroupBallotFindLSB,
|
||||
@ -405,6 +494,27 @@ protected:
|
||||
SPVFuncImplReflectScalar,
|
||||
SPVFuncImplRefractScalar,
|
||||
SPVFuncImplFaceForwardScalar,
|
||||
SPVFuncImplChromaReconstructNearest2Plane,
|
||||
SPVFuncImplChromaReconstructNearest3Plane,
|
||||
SPVFuncImplChromaReconstructLinear422CositedEven2Plane,
|
||||
SPVFuncImplChromaReconstructLinear422CositedEven3Plane,
|
||||
SPVFuncImplChromaReconstructLinear422Midpoint2Plane,
|
||||
SPVFuncImplChromaReconstructLinear422Midpoint3Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XCositedEvenYCositedEven2Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XCositedEvenYCositedEven3Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XMidpointYCositedEven2Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XMidpointYCositedEven3Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XCositedEvenYMidpoint2Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XCositedEvenYMidpoint3Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XMidpointYMidpoint2Plane,
|
||||
SPVFuncImplChromaReconstructLinear420XMidpointYMidpoint3Plane,
|
||||
SPVFuncImplExpandITUFullRange,
|
||||
SPVFuncImplExpandITUNarrowRange,
|
||||
SPVFuncImplConvertYCbCrBT709,
|
||||
SPVFuncImplConvertYCbCrBT601,
|
||||
SPVFuncImplConvertYCbCrBT2020,
|
||||
SPVFuncImplDynamicImageSampler,
|
||||
|
||||
SPVFuncImplArrayCopyMultidimMax = 6
|
||||
};
|
||||
|
||||
@ -418,6 +528,8 @@ protected:
|
||||
void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
|
||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||
void emit_subgroup_op(const Instruction &i) override;
|
||||
std::string to_texture_op(const Instruction &i, bool *forward,
|
||||
SmallVector<uint32_t> &inherited_expressions) override;
|
||||
void emit_fixup() override;
|
||||
std::string to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||
const std::string &qualifier = "");
|
||||
@ -428,7 +540,7 @@ protected:
|
||||
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string sampler_type(const SPIRType &type);
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||
std::string to_func_call_arg(uint32_t id) override;
|
||||
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
|
||||
std::string to_name(uint32_t id, bool allow_alias = true) const override;
|
||||
std::string to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||
bool has_array_offsets, bool has_offset, bool has_grad, bool has_dref, uint32_t lod,
|
||||
@ -513,7 +625,7 @@ protected:
|
||||
std::string member_attribute_qualifier(const SPIRType &type, uint32_t index);
|
||||
std::string argument_decl(const SPIRFunction::Parameter &arg);
|
||||
std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp);
|
||||
uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype);
|
||||
uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane = 0);
|
||||
uint32_t get_ordered_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
|
||||
|
||||
// MSL packing rules. These compute the effective packing rules as observed by the MSL compiler in the MSL output.
|
||||
@ -652,6 +764,7 @@ protected:
|
||||
std::string sampler_name_suffix = "Smplr";
|
||||
std::string swizzle_name_suffix = "Swzl";
|
||||
std::string buffer_size_name_suffix = "BufferSize";
|
||||
std::string plane_name_suffix = "Plane";
|
||||
std::string input_wg_var_name = "gl_in";
|
||||
std::string output_buffer_var_name = "spvOut";
|
||||
std::string patch_output_buffer_var_name = "spvPatchOut";
|
||||
@ -676,6 +789,8 @@ protected:
|
||||
|
||||
bool suppress_missing_prototypes = false;
|
||||
|
||||
void add_spv_func_and_recompile(SPVFuncImpl spv_func);
|
||||
|
||||
// OpcodeHandler that handles several MSL preprocessing operations.
|
||||
struct OpCodePreprocessor : OpcodeHandler
|
||||
{
|
||||
|
103
tests-other/msl_ycbcr_conversion_test.cpp
Normal file
103
tests-other/msl_ycbcr_conversion_test.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// Testbench for MSL constexpr samplers, with Y'CbCr conversion.
|
||||
// It does not validate output, but it's useful for ad-hoc testing.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <spirv_cross_c.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#define SPVC_CHECKED_CALL(x) do { \
|
||||
if ((x) != SPVC_SUCCESS) { \
|
||||
fprintf(stderr, "Failed at line %d.\n", __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while(0)
|
||||
#define SPVC_CHECKED_CALL_NEGATIVE(x) do { \
|
||||
g_fail_on_error = SPVC_FALSE; \
|
||||
if ((x) == SPVC_SUCCESS) { \
|
||||
fprintf(stderr, "Failed at line %d.\n", __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
g_fail_on_error = SPVC_TRUE; \
|
||||
} while(0)
|
||||
|
||||
static std::vector<SpvId> read_file(const char *path)
|
||||
{
|
||||
long len;
|
||||
FILE *file = fopen(path, "rb");
|
||||
|
||||
if (!file)
|
||||
return {};
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
len = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
std::vector<SpvId> buffer(len / sizeof(SpvId));
|
||||
if (fread(buffer.data(), 1, len, file) != (size_t)len)
|
||||
{
|
||||
fclose(file);
|
||||
return {};
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
auto buffer = read_file(argv[1]);
|
||||
if (buffer.empty())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
spvc_context ctx;
|
||||
spvc_parsed_ir parsed_ir;
|
||||
spvc_compiler compiler;
|
||||
spvc_compiler_options options;
|
||||
|
||||
SPVC_CHECKED_CALL(spvc_context_create(&ctx));
|
||||
SPVC_CHECKED_CALL(spvc_context_parse_spirv(ctx, buffer.data(), buffer.size(), &parsed_ir));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(ctx, SPVC_BACKEND_MSL, parsed_ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_VERSION, SPVC_MAKE_MSL_VERSION(2, 0, 0)));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler, options));
|
||||
|
||||
spvc_msl_resource_binding binding;
|
||||
spvc_msl_resource_binding_init(&binding);
|
||||
binding.desc_set = 1;
|
||||
binding.binding = 2;
|
||||
binding.stage = SpvExecutionModelFragment;
|
||||
binding.msl_texture = 0;
|
||||
binding.msl_sampler = 0;
|
||||
SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
|
||||
|
||||
spvc_msl_constexpr_sampler samp;
|
||||
spvc_msl_sampler_ycbcr_conversion conv;
|
||||
spvc_msl_constexpr_sampler_init(&samp);
|
||||
spvc_msl_sampler_ycbcr_conversion_init(&conv);
|
||||
conv.planes = 3;
|
||||
conv.resolution = SPVC_MSL_FORMAT_RESOLUTION_422;
|
||||
conv.chroma_filter = SPVC_MSL_SAMPLER_FILTER_LINEAR;
|
||||
conv.x_chroma_offset = SPVC_MSL_CHROMA_LOCATION_MIDPOINT;
|
||||
conv.ycbcr_model = SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_2020;
|
||||
conv.ycbcr_range = SPVC_MSL_SAMPLER_YCBCR_RANGE_ITU_NARROW;
|
||||
conv.bpc = 8;
|
||||
SPVC_CHECKED_CALL(spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(compiler, 1, 2, &samp, &conv));
|
||||
|
||||
const char *str;
|
||||
SPVC_CHECKED_CALL(spvc_compiler_compile(compiler, &str));
|
||||
|
||||
// Should be marked, as a sanity check.
|
||||
if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 1, 2))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
fprintf(stderr, "Output:\n%s\n", str);
|
||||
}
|
||||
|
BIN
tests-other/msl_ycbcr_conversion_test.spv
Normal file
BIN
tests-other/msl_ycbcr_conversion_test.spv
Normal file
Binary file not shown.
BIN
tests-other/msl_ycbcr_conversion_test_2.spv
Normal file
BIN
tests-other/msl_ycbcr_conversion_test_2.spv
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user