diff --git a/3rdparty/spirv-cross/README.md b/3rdparty/spirv-cross/README.md index 6bf7d37d3..8457cae47 100644 --- a/3rdparty/spirv-cross/README.md +++ b/3rdparty/spirv-cross/README.md @@ -3,7 +3,7 @@ SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader languages. [![Build Status](https://travis-ci.org/KhronosGroup/SPIRV-Cross.svg?branch=master)](https://travis-ci.org/KhronosGroup/SPIRV-Cross) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/KhronosGroup/SPIRV-Cross?svg=true&branch=master)](https://ci.appveyor.com/project/HansKristian-ARM/SPIRV-Cross) +[![Build Status](https://ci.appveyor.com/api/projects/status/github/KhronosGroup/SPIRV-Cross?svg=true&branch=master)](https://ci.appveyor.com/project/HansKristian-Work/SPIRV-Cross) ## Features diff --git a/3rdparty/spirv-cross/main.cpp b/3rdparty/spirv-cross/main.cpp index 660d77e3a..78991094a 100644 --- a/3rdparty/spirv-cross/main.cpp +++ b/3rdparty/spirv-cross/main.cpp @@ -492,6 +492,7 @@ struct CLIArguments bool support_nonzero_baseinstance = true; bool msl_swizzle_texture_samples = false; bool msl_ios = false; + bool msl_pad_fragment_output = false; vector pls_in; vector pls_out; vector remaps; @@ -516,6 +517,7 @@ struct CLIArguments bool msl = false; bool hlsl = false; bool hlsl_compat = false; + bool hlsl_support_nonzero_base = false; bool vulkan_semantics = false; bool flatten_multidimensional_arrays = false; bool use_420pack_extension = true; @@ -545,10 +547,12 @@ static void print_help() "\t[--msl-version ]\n" "\t[--msl-swizzle-texture-samples]\n" "\t[--msl-ios]\n" + "\t[--msl-pad-fragment-output]\n" "\t[--hlsl]\n" "\t[--reflect]\n" "\t[--shader-model]\n" "\t[--hlsl-enable-compat]\n" + "\t[--hlsl-support-nonzero-basevertex-baseinstance]\n" "\t[--separate-shader-objects]\n" "\t[--pls-in format input-name]\n" "\t[--pls-out format output-name]\n" @@ -705,11 +709,14 @@ static int main_inner(int argc, char *argv[]) cbs.add("--msl", [&args](CLIParser &) { args.msl = true; }); cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; }); cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; }); + cbs.add("--hlsl-support-nonzero-basevertex-baseinstance", + [&args](CLIParser &) { args.hlsl_support_nonzero_base = true; }); 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("--msl-ios", [&args](CLIParser &) { args.msl_ios = true; }); + cbs.add("--msl-pad-fragment-output", [&args](CLIParser &) { args.msl_pad_fragment_output = 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(); @@ -839,6 +846,7 @@ static int main_inner(int argc, char *argv[]) msl_opts.swizzle_texture_samples = args.msl_swizzle_texture_samples; if (args.msl_ios) msl_opts.platform = CompilerMSL::Options::iOS; + msl_opts.pad_fragment_output_components = args.msl_pad_fragment_output; msl_comp->set_msl_options(msl_opts); } else if (args.hlsl) @@ -991,6 +999,7 @@ static int main_inner(int argc, char *argv[]) build_dummy_sampler = true; } + hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base; hlsl->set_hlsl_options(hlsl_opts); } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert index a72a098fd..2cebffffa 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert +++ b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert @@ -2,11 +2,11 @@ #define SPIRV_CROSS_CONSTANT_ID_201 -10 #endif static const int _7 = SPIRV_CROSS_CONSTANT_ID_201; +static const int _20 = (_7 + 2); #ifndef SPIRV_CROSS_CONSTANT_ID_202 #define SPIRV_CROSS_CONSTANT_ID_202 100u #endif static const uint _8 = SPIRV_CROSS_CONSTANT_ID_202; -static const int _20 = (_7 + 2); static const uint _25 = (_8 % 5u); #ifndef SPIRV_CROSS_CONSTANT_ID_0 #define SPIRV_CROSS_CONSTANT_ID_0 int4(20, 30, _20, _20) diff --git a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/composite-array-initialization.comp b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/composite-array-initialization.comp index 617e0987d..e39f4d068 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/composite-array-initialization.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/composite-array-initialization.comp @@ -1,15 +1,16 @@ -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 4.0f -#endif -static const float X = SPIRV_CROSS_CONSTANT_ID_0; -static const uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); - struct Data { float a; float b; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 4.0f +#endif +static const float X = SPIRV_CROSS_CONSTANT_ID_0; + +static const uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); + static const Data _21 = { 1.0f, 2.0f }; static const Data _24 = { 3.0f, 4.0f }; static const Data _25[2] = { { 1.0f, 2.0f }, { 3.0f, 4.0f } }; @@ -29,14 +30,13 @@ struct SPIRV_Cross_Input void comp_main() { - Data data[2] = _25; Data _28 = { X, 2.0f }; Data _31[2] = { _28, _30 }; Data data2[2] = _31; if (gl_LocalInvocationIndex == 0u) { - _61.Store(gl_WorkGroupID.x * 8 + 0, asuint(data[gl_LocalInvocationID.x].a + data2[gl_LocalInvocationID.x].a)); - _61.Store(gl_WorkGroupID.x * 8 + 4, asuint(data[gl_LocalInvocationID.x].b + data2[gl_LocalInvocationID.x].b)); + _61.Store(gl_WorkGroupID.x * 8 + 0, asuint(_25[gl_LocalInvocationID.x].a + data2[gl_LocalInvocationID.x].a)); + _61.Store(gl_WorkGroupID.x * 8 + 4, asuint(_25[gl_LocalInvocationID.x].b + data2[gl_LocalInvocationID.x].b)); } } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/spec-constant-op-member-array.comp b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/spec-constant-op-member-array.comp index ad815b282..c35031b84 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/spec-constant-op-member-array.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/comp/spec-constant-op-member-array.comp @@ -6,15 +6,6 @@ static const int a = SPIRV_CROSS_CONSTANT_ID_0; #define SPIRV_CROSS_CONSTANT_ID_1 200 #endif static const int b = SPIRV_CROSS_CONSTANT_ID_1; -#ifndef SPIRV_CROSS_CONSTANT_ID_2 -#define SPIRV_CROSS_CONSTANT_ID_2 300 -#endif -static const int c = SPIRV_CROSS_CONSTANT_ID_2; -static const int _18 = (c + 50); -#ifndef SPIRV_CROSS_CONSTANT_ID_3 -#define SPIRV_CROSS_CONSTANT_ID_3 400 -#endif -static const int e = SPIRV_CROSS_CONSTANT_ID_3; struct A { @@ -28,6 +19,16 @@ struct B int member1[a]; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_2 +#define SPIRV_CROSS_CONSTANT_ID_2 300 +#endif +static const int c = SPIRV_CROSS_CONSTANT_ID_2; +static const int _18 = (c + 50); +#ifndef SPIRV_CROSS_CONSTANT_ID_3 +#define SPIRV_CROSS_CONSTANT_ID_3 400 +#endif +static const int e = SPIRV_CROSS_CONSTANT_ID_3; + RWByteAddressBuffer _22 : register(u0); static uint3 gl_GlobalInvocationID; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/constant-composites.frag b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/constant-composites.frag index ab14fab4c..306ca5cad 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/constant-composites.frag +++ b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/constant-composites.frag @@ -24,9 +24,8 @@ struct SPIRV_Cross_Output void frag_main() { - Foo foos[2] = _28; FragColor = _16[_line].xxxx; - FragColor += (foos[_line].a * foos[1 - _line].a).xxxx; + FragColor += (_28[_line].a * _28[1 - _line].a).xxxx; } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) diff --git a/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/dual-source-blending.frag b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/dual-source-blending.frag new file mode 100644 index 000000000..961e80001 --- /dev/null +++ b/3rdparty/spirv-cross/reference/opt/shaders-hlsl/frag/dual-source-blending.frag @@ -0,0 +1,23 @@ +static float4 FragColor0; +static float4 FragColor1; + +struct SPIRV_Cross_Output +{ + float4 FragColor0 : SV_Target0; + float4 FragColor1 : SV_Target1; +}; + +void frag_main() +{ + FragColor0 = 1.0f.xxxx; + FragColor1 = 2.0f.xxxx; +} + +SPIRV_Cross_Output main() +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor0 = FragColor0; + stage_output.FragColor1 = FragColor1; + return stage_output; +} diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp index 5802ddac9..1cf531c4b 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp @@ -3,17 +3,17 @@ using namespace metal; +struct SSBO +{ + float a; +}; + constant uint _5_tmp [[function_constant(10)]]; constant uint _5 = is_function_constant_defined(_5_tmp) ? _5_tmp : 9u; constant uint _6_tmp [[function_constant(12)]]; constant uint _6 = is_function_constant_defined(_6_tmp) ? _6_tmp : 4u; constant uint3 gl_WorkGroupSize = uint3(_5, 20u, _6); -struct SSBO -{ - float a; -}; - kernel void main0(device SSBO& _4 [[buffer(0)]]) { _4.a += 1.0; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp index 2c9b038b2..8c56e7af4 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp @@ -3,17 +3,17 @@ using namespace metal; +struct _6 +{ + float _m0[1]; +}; + constant uint _3_tmp [[function_constant(0)]]; constant uint _3 = is_function_constant_defined(_3_tmp) ? _3_tmp : 1u; constant uint _4_tmp [[function_constant(2)]]; constant uint _4 = is_function_constant_defined(_4_tmp) ? _4_tmp : 3u; constant uint3 gl_WorkGroupSize = uint3(_3, 2u, _4); -struct _6 -{ - float _m0[1]; -}; - kernel void main0(device _6& _8 [[buffer(0)]], device _6& _9 [[buffer(1)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) { _8._m0[gl_WorkGroupID.x] = _9._m0[gl_WorkGroupID.x] + _8._m0[gl_WorkGroupID.x]; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp index 9627124d2..7b7e91208 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp @@ -3,13 +3,13 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); - struct cb1_struct { float4 _m0[1]; }; +constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); + kernel void main0(constant cb1_struct& cb0_1 [[buffer(0)]], texture2d u0 [[texture(1)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { int2 _46 = int2(u0.get_width(), u0.get_height()) >> int2(uint2(4u)); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp index 9ab3a8729..037940237 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp @@ -3,13 +3,13 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); - struct cb1_struct { float4 _m0[1]; }; +constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); + kernel void main0(constant cb1_struct& cb0_1 [[buffer(0)]], texture2d u0 [[texture(1)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { int2 _40 = int2(u0.get_width(), u0.get_height()) >> int2(uint2(4u)); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag index ee1926a9a..d7d6ef634 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag @@ -3,6 +3,11 @@ using namespace metal; +struct _28 +{ + float4 _m0; +}; + struct _6 { float4 _m0; @@ -83,11 +88,6 @@ struct _18 float4 _m38[2]; }; -struct _28 -{ - float4 _m0; -}; - constant _28 _74 = {}; struct main0_out diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert index b0852f0be..ed5c5f9ad 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert @@ -5,9 +5,9 @@ using namespace metal; constant int _7_tmp [[function_constant(201)]]; constant int _7 = is_function_constant_defined(_7_tmp) ? _7_tmp : -10; +constant int _20 = (_7 + 2); constant uint _8_tmp [[function_constant(202)]]; constant uint _8 = is_function_constant_defined(_8_tmp) ? _8_tmp : 100u; -constant int _20 = (_7 + 2); constant uint _25 = (_8 % 5u); constant int4 _30 = int4(20, 30, _20, _20); constant int2 _32 = int2(_30.y, _30.x); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/composite-array-initialization.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/composite-array-initialization.comp index 9e47e8971..8b1faa109 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/composite-array-initialization.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/composite-array-initialization.comp @@ -5,10 +5,6 @@ using namespace metal; -constant float X_tmp [[function_constant(0)]]; -constant float X = is_function_constant_defined(X_tmp) ? X_tmp : 4.0; -constant uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); - struct Data { float a; @@ -21,12 +17,17 @@ struct Data_1 float b; }; +constant float X_tmp [[function_constant(0)]]; +constant float X = is_function_constant_defined(X_tmp) ? X_tmp : 4.0; + struct SSBO { - Data_1 outdata[1]; + Data outdata[1]; }; -constant Data _25[2] = { Data{ 1.0, 2.0 }, Data{ 3.0, 4.0 } }; +constant uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); + +constant Data_1 _25[2] = { Data_1{ 1.0, 2.0 }, Data_1{ 3.0, 4.0 } }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. template @@ -43,11 +44,10 @@ void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N]) kernel void main0(device SSBO& _53 [[buffer(0)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { - Data data[2] = { Data{ 1.0, 2.0 }, Data{ 3.0, 4.0 } }; - Data _31[2] = { Data{ X, 2.0 }, Data{ 3.0, 5.0 } }; - Data data2[2]; + Data_1 _31[2] = { Data_1{ X, 2.0 }, Data_1{ 3.0, 5.0 } }; + Data_1 data2[2]; spvArrayCopyFromStack1(data2, _31); - _53.outdata[gl_WorkGroupID.x].a = data[gl_LocalInvocationID.x].a + data2[gl_LocalInvocationID.x].a; - _53.outdata[gl_WorkGroupID.x].b = data[gl_LocalInvocationID.x].b + data2[gl_LocalInvocationID.x].b; + _53.outdata[gl_WorkGroupID.x].a = _25[gl_LocalInvocationID.x].a + data2[gl_LocalInvocationID.x].a; + _53.outdata[gl_WorkGroupID.x].b = _25[gl_LocalInvocationID.x].b + data2[gl_LocalInvocationID.x].b; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/culling.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/culling.comp index 9eac8c9ff..edc01a878 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/culling.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/culling.comp @@ -6,8 +6,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); - struct SSBO { float in_data[1]; @@ -23,6 +21,8 @@ struct SSBO3 uint count; }; +constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); + kernel void main0(const device SSBO& _22 [[buffer(0)]], device SSBO2& _38 [[buffer(1)]], device SSBO3& _41 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { float _28 = _22.in_data[gl_GlobalInvocationID.x]; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-1.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-1.comp index 44d2b2d74..241335431 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-1.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-1.comp @@ -3,8 +3,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); - struct T1 { packed_float3 a; @@ -21,6 +19,8 @@ struct Buffer1 float buf1[1]; }; +constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); + kernel void main0(device Buffer0& _15 [[buffer(1)]], device Buffer1& _34 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { _34.buf1[gl_GlobalInvocationID.x] = _15.buf0[0].b; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-2.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-2.comp index 4cc9c673a..460f12768 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-2.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/packing-test-2.comp @@ -3,8 +3,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); - struct T1 { packed_float3 a; @@ -21,6 +19,8 @@ struct Buffer1 float buf1[1]; }; +constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); + kernel void main0(device Buffer0& _14 [[buffer(1)]], device Buffer1& _24 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { _24.buf1[gl_GlobalInvocationID.x] = _14.buf0[0].b; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared-array-of-arrays.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared-array-of-arrays.comp index 3884c22f5..86d77e593 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared-array-of-arrays.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared-array-of-arrays.comp @@ -3,13 +3,13 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(4u, 4u, 1u); - struct SSBO { float out_data[1]; }; +constant uint3 gl_WorkGroupSize = uint3(4u, 4u, 1u); + kernel void main0(device SSBO& _67 [[buffer(0)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { threadgroup float foo[4][4]; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared.comp index e58638b5c..ca8420f74 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/shared.comp @@ -3,8 +3,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); - struct SSBO { float in_data[1]; @@ -15,6 +13,8 @@ struct SSBO2 float out_data[1]; }; +constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); + kernel void main0(const device SSBO& _22 [[buffer(0)]], device SSBO2& _44 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]]) { threadgroup float sShared[4]; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-op-member-array.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-op-member-array.comp index 35ebe1592..1d78f3f4f 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-op-member-array.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-op-member-array.comp @@ -11,13 +11,6 @@ constant int a = SPIRV_CROSS_CONSTANT_ID_0; #define SPIRV_CROSS_CONSTANT_ID_1 200 #endif constant int b = SPIRV_CROSS_CONSTANT_ID_1; -#ifndef SPIRV_CROSS_CONSTANT_ID_2 -#define SPIRV_CROSS_CONSTANT_ID_2 300 -#endif -constant int c = SPIRV_CROSS_CONSTANT_ID_2; -constant int _18 = (c + 50); -constant int e_tmp [[function_constant(3)]]; -constant int e = is_function_constant_defined(e_tmp) ? e_tmp : 400; struct A { @@ -31,6 +24,12 @@ struct B int member1[a]; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_2 +#define SPIRV_CROSS_CONSTANT_ID_2 300 +#endif +constant int c = SPIRV_CROSS_CONSTANT_ID_2; +constant int _18 = (c + 50); + struct SSBO { A member_a; @@ -39,6 +38,9 @@ struct SSBO int w[_18]; }; +constant int e_tmp [[function_constant(3)]]; +constant int e = is_function_constant_defined(e_tmp) ? e_tmp : 400; + kernel void main0(device SSBO& _22 [[buffer(0)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { _22.w[gl_GlobalInvocationID.x] += (_22.v[gl_GlobalInvocationID.x] + e); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-work-group-size.comp b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-work-group-size.comp index e46ab8939..b875e1bb5 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-work-group-size.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/comp/spec-constant-work-group-size.comp @@ -9,6 +9,12 @@ using namespace metal; constant int b = SPIRV_CROSS_CONSTANT_ID_1; constant int a_tmp [[function_constant(0)]]; constant int a = is_function_constant_defined(a_tmp) ? a_tmp : 1; + +struct SSBO +{ + int v[1]; +}; + constant uint _21 = (uint(a) + 0u); constant uint _22_tmp [[function_constant(10)]]; constant uint _22 = is_function_constant_defined(_22_tmp) ? _22_tmp : 1u; @@ -19,11 +25,6 @@ constant uint _29 = gl_WorkGroupSize.y; constant uint _30 = (_28 + _29); constant int _32 = (1 - a); -struct SSBO -{ - int v[1]; -}; - kernel void main0(device SSBO& _17 [[buffer(0)]]) { int spec_const_array_size[b]; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-array.frag b/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-array.frag index 0ba2781b0..a0b830daa 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-array.frag +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-array.frag @@ -1,5 +1,3 @@ -#pragma clang diagnostic ignored "-Wmissing-prototypes" - #include #include @@ -27,24 +25,10 @@ struct main0_in int index [[user(locn0)]]; }; -// Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopyFromStack1(thread T (&dst)[N], thread const T (&src)[N]) -{ - for (uint i = 0; i < N; dst[i] = src[i], i++); -} - -template -void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N]) -{ - for (uint i = 0; i < N; dst[i] = src[i], i++); -} - fragment main0_out main0(main0_in in [[stage_in]]) { main0_out out = {}; - Foobar indexable[2] = { Foobar{ 10.0, 40.0 }, Foobar{ 90.0, 70.0 } }; - out.FragColor = ((_37[in.index] + _55[in.index][in.index + 1]) + float4(30.0)) + float4(indexable[in.index].a + indexable[in.index].b); + out.FragColor = ((_37[in.index] + _55[in.index][in.index + 1]) + float4(30.0)) + float4(_75[in.index].a + _75[in.index].b); return out; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-composites.frag b/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-composites.frag index deb7eaaf8..335cbcd79 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-composites.frag +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/constant-composites.frag @@ -1,5 +1,3 @@ -#pragma clang diagnostic ignored "-Wmissing-prototypes" - #include #include @@ -24,25 +22,11 @@ struct main0_in int line [[user(locn0)]]; }; -// Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopyFromStack1(thread T (&dst)[N], thread const T (&src)[N]) -{ - for (uint i = 0; i < N; dst[i] = src[i], i++); -} - -template -void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N]) -{ - for (uint i = 0; i < N; dst[i] = src[i], i++); -} - fragment main0_out main0(main0_in in [[stage_in]]) { main0_out out = {}; - Foo foos[2] = { Foo{ 10.0, 20.0 }, Foo{ 30.0, 40.0 } }; out.FragColor = float4(_16[in.line]); - out.FragColor += float4(foos[in.line].a * foos[1 - in.line].a); + out.FragColor += float4(_28[in.line].a * _28[1 - in.line].a); return out; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/fragment-component-padding.pad-fragment.frag b/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/fragment-component-padding.pad-fragment.frag new file mode 100644 index 000000000..53aafa5f7 --- /dev/null +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/frag/fragment-component-padding.pad-fragment.frag @@ -0,0 +1,35 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 FragColors_0 [[color(0)]]; + float4 FragColors_1 [[color(1)]]; + float4 FragColor2 [[color(2)]]; + float4 FragColor3 [[color(3)]]; +}; + +struct main0_in +{ + float3 vColor [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + float FragColors[2] = {}; + float2 FragColor2 = {}; + float3 FragColor3 = {}; + FragColors[0] = in.vColor.x; + FragColors[1] = in.vColor.y; + FragColor2 = in.vColor.xz; + FragColor3 = in.vColor.zzz; + out.FragColors_0 = float4(FragColors[0]); + out.FragColors_1 = float4(FragColors[1]); + out.FragColor2 = FragColor2.xyyy; + out.FragColor3 = FragColor3.xyzz; + return out; +} + diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays-leaf.ios.vert b/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays-leaf.ios.vert index 22dc480b2..93704af28 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays-leaf.ios.vert +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays-leaf.ios.vert @@ -3,11 +3,6 @@ using namespace metal; -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 3 -#endif -constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; - struct storage_block { uint4 baz; @@ -20,6 +15,11 @@ struct constant_block int bar; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 3 +#endif +constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; + vertex void main0(device storage_block* storage_0 [[buffer(0)]], device storage_block* storage_1 [[buffer(1)]], constant constant_block* constants_0 [[buffer(2)]], constant constant_block* constants_1 [[buffer(3)]], constant constant_block* constants_2 [[buffer(4)]], constant constant_block* constants_3 [[buffer(5)]], array, 3> images [[texture(0)]]) { device storage_block* storage[] = diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays.ios.vert b/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays.ios.vert index 22dc480b2..93704af28 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays.ios.vert +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/vert/resource-arrays.ios.vert @@ -3,11 +3,6 @@ using namespace metal; -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 3 -#endif -constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; - struct storage_block { uint4 baz; @@ -20,6 +15,11 @@ struct constant_block int bar; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 3 +#endif +constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; + vertex void main0(device storage_block* storage_0 [[buffer(0)]], device storage_block* storage_1 [[buffer(1)]], constant constant_block* constants_0 [[buffer(2)]], constant constant_block* constants_1 [[buffer(3)]], constant constant_block* constants_2 [[buffer(4)]], constant constant_block* constants_3 [[buffer(5)]], array, 3> images [[texture(0)]]) { device storage_block* storage[] = diff --git a/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert b/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert index d001d30c0..2608c1d57 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert +++ b/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert @@ -4,11 +4,11 @@ #define SPIRV_CROSS_CONSTANT_ID_201 -10 #endif const int _7 = SPIRV_CROSS_CONSTANT_ID_201; +const int _20 = (_7 + 2); #ifndef SPIRV_CROSS_CONSTANT_ID_202 #define SPIRV_CROSS_CONSTANT_ID_202 100u #endif const uint _8 = SPIRV_CROSS_CONSTANT_ID_202; -const int _20 = (_7 + 2); const uint _25 = (_8 % 5u); const ivec4 _30 = ivec4(20, 30, _20, _20); const ivec2 _32 = ivec2(_30.y, _30.x); diff --git a/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk b/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk index f39495646..10da8f4b8 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk +++ b/3rdparty/spirv-cross/reference/opt/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk @@ -1,8 +1,8 @@ #version 450 layout(constant_id = 201) const int _7 = -10; -layout(constant_id = 202) const uint _8 = 100u; const int _20 = (_7 + 2); +layout(constant_id = 202) const uint _8 = 100u; const uint _25 = (_8 % 5u); const ivec4 _30 = ivec4(20, 30, _20, _20); const ivec2 _32 = ivec2(_30.y, _30.x); diff --git a/3rdparty/spirv-cross/reference/opt/shaders/comp/composite-array-initialization.comp b/3rdparty/spirv-cross/reference/opt/shaders/comp/composite-array-initialization.comp index e91313667..2e6dbebf8 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/comp/composite-array-initialization.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders/comp/composite-array-initialization.comp @@ -1,17 +1,18 @@ #version 310 es layout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in; -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 4.0 -#endif -const float X = SPIRV_CROSS_CONSTANT_ID_0; - struct Data { float a; float b; }; +const Data _25[2] = Data[](Data(1.0, 2.0), Data(3.0, 4.0)); +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 4.0 +#endif +const float X = SPIRV_CROSS_CONSTANT_ID_0; + layout(binding = 0, std430) buffer SSBO { Data outdata[]; @@ -19,9 +20,8 @@ layout(binding = 0, std430) buffer SSBO void main() { - Data data[2] = Data[](Data(1.0, 2.0), Data(3.0, 4.0)); Data data2[2] = Data[](Data(X, 2.0), Data(3.0, 5.0)); - _53.outdata[gl_WorkGroupID.x].a = data[gl_LocalInvocationID.x].a + data2[gl_LocalInvocationID.x].a; - _53.outdata[gl_WorkGroupID.x].b = data[gl_LocalInvocationID.x].b + data2[gl_LocalInvocationID.x].b; + _53.outdata[gl_WorkGroupID.x].a = _25[gl_LocalInvocationID.x].a + data2[gl_LocalInvocationID.x].a; + _53.outdata[gl_WorkGroupID.x].b = _25[gl_LocalInvocationID.x].b + data2[gl_LocalInvocationID.x].b; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-array.frag b/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-array.frag index 749fc8098..914888aaf 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-array.frag +++ b/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-array.frag @@ -2,21 +2,21 @@ precision mediump float; precision highp int; -const vec4 _37[3] = vec4[](vec4(1.0), vec4(2.0), vec4(3.0)); -const vec4 _55[2][2] = vec4[][](vec4[](vec4(1.0), vec4(2.0)), vec4[](vec4(8.0), vec4(10.0))); - struct Foobar { float a; float b; }; +const vec4 _37[3] = vec4[](vec4(1.0), vec4(2.0), vec4(3.0)); +const vec4 _55[2][2] = vec4[][](vec4[](vec4(1.0), vec4(2.0)), vec4[](vec4(8.0), vec4(10.0))); +const Foobar _75[2] = Foobar[](Foobar(10.0, 40.0), Foobar(90.0, 70.0)); + layout(location = 0) out vec4 FragColor; layout(location = 0) flat in mediump int index; void main() { - Foobar indexable[2] = Foobar[](Foobar(10.0, 40.0), Foobar(90.0, 70.0)); - FragColor = ((_37[index] + _55[index][index + 1]) + vec4(30.0)) + vec4(indexable[index].a + indexable[index].b); + FragColor = ((_37[index] + _55[index][index + 1]) + vec4(30.0)) + vec4(_75[index].a + _75[index].b); } diff --git a/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-composites.frag b/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-composites.frag index d4ab613e8..7813b98db 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-composites.frag +++ b/3rdparty/spirv-cross/reference/opt/shaders/frag/constant-composites.frag @@ -10,13 +10,14 @@ struct Foo float b; }; +const Foo _28[2] = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0)); + layout(location = 0) out vec4 FragColor; layout(location = 0) flat in mediump int line; void main() { - Foo foos[2] = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0)); FragColor = vec4(_16[line]); - FragColor += vec4(foos[line].a * foos[1 - line].a); + FragColor += vec4(_28[line].a * _28[1 - line].a); } diff --git a/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp b/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp index 9344a7a24..33647a423 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp +++ b/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp @@ -9,15 +9,6 @@ const int a = SPIRV_CROSS_CONSTANT_ID_0; #define SPIRV_CROSS_CONSTANT_ID_1 200 #endif const int b = SPIRV_CROSS_CONSTANT_ID_1; -#ifndef SPIRV_CROSS_CONSTANT_ID_2 -#define SPIRV_CROSS_CONSTANT_ID_2 300 -#endif -const int c = SPIRV_CROSS_CONSTANT_ID_2; -const int _18 = (c + 50); -#ifndef SPIRV_CROSS_CONSTANT_ID_3 -#define SPIRV_CROSS_CONSTANT_ID_3 400 -#endif -const int e = SPIRV_CROSS_CONSTANT_ID_3; struct A { @@ -31,6 +22,16 @@ struct B int member1[a]; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_2 +#define SPIRV_CROSS_CONSTANT_ID_2 300 +#endif +const int c = SPIRV_CROSS_CONSTANT_ID_2; +const int _18 = (c + 50); +#ifndef SPIRV_CROSS_CONSTANT_ID_3 +#define SPIRV_CROSS_CONSTANT_ID_3 400 +#endif +const int e = SPIRV_CROSS_CONSTANT_ID_3; + layout(binding = 0, std430) buffer SSBO { A member_a; diff --git a/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk b/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk index d9a2822f7..cd68e93d7 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk +++ b/3rdparty/spirv-cross/reference/opt/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk @@ -3,9 +3,6 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(constant_id = 0) const int a = 100; layout(constant_id = 1) const int b = 200; -layout(constant_id = 2) const int c = 300; -const int _18 = (c + 50); -layout(constant_id = 3) const int e = 400; struct A { @@ -19,6 +16,10 @@ struct B int member1[a]; }; +layout(constant_id = 2) const int c = 300; +const int _18 = (c + 50); +layout(constant_id = 3) const int e = 400; + layout(set = 1, binding = 0, std430) buffer SSBO { A member_a; diff --git a/3rdparty/spirv-cross/reference/shaders-hlsl-no-opt/vert/pass-array-by-value.vert b/3rdparty/spirv-cross/reference/shaders-hlsl-no-opt/vert/pass-array-by-value.vert new file mode 100644 index 000000000..20afdb513 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-hlsl-no-opt/vert/pass-array-by-value.vert @@ -0,0 +1,48 @@ +static const float4 _68[4] = { 0.0f.xxxx, 1.0f.xxxx, 2.0f.xxxx, 3.0f.xxxx }; + +static float4 gl_Position; +static int Index1; +static int Index2; + +struct SPIRV_Cross_Input +{ + int Index1 : TEXCOORD0; + int Index2 : TEXCOORD1; +}; + +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +float4 consume_constant_arrays2(float4 positions[4], float4 positions2[4]) +{ + float4 indexable[4] = positions; + float4 indexable_1[4] = positions2; + return indexable[Index1] + indexable_1[Index2]; +} + +float4 consume_constant_arrays(float4 positions[4], float4 positions2[4]) +{ + return consume_constant_arrays2(positions, positions2); +} + +void vert_main() +{ + float4 LUT2[4]; + LUT2[0] = 10.0f.xxxx; + LUT2[1] = 11.0f.xxxx; + LUT2[2] = 12.0f.xxxx; + LUT2[3] = 13.0f.xxxx; + gl_Position = consume_constant_arrays(_68, LUT2); +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + Index1 = stage_input.Index1; + Index2 = stage_input.Index2; + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/3rdparty/spirv-cross/reference/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert b/3rdparty/spirv-cross/reference/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert index ddec81f20..84b91b69b 100644 --- a/3rdparty/spirv-cross/reference/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert +++ b/3rdparty/spirv-cross/reference/shaders-hlsl/asm/vert/spec-constant-op-composite.asm.vert @@ -2,15 +2,11 @@ #define SPIRV_CROSS_CONSTANT_ID_201 -10 #endif static const int _7 = SPIRV_CROSS_CONSTANT_ID_201; +static const int _20 = (_7 + 2); #ifndef SPIRV_CROSS_CONSTANT_ID_202 #define SPIRV_CROSS_CONSTANT_ID_202 100u #endif static const uint _8 = SPIRV_CROSS_CONSTANT_ID_202; -#ifndef SPIRV_CROSS_CONSTANT_ID_200 -#define SPIRV_CROSS_CONSTANT_ID_200 3.141590118408203125f -#endif -static const float _9 = SPIRV_CROSS_CONSTANT_ID_200; -static const int _20 = (_7 + 2); static const uint _25 = (_8 % 5u); #ifndef SPIRV_CROSS_CONSTANT_ID_0 #define SPIRV_CROSS_CONSTANT_ID_0 int4(20, 30, _20, _20) @@ -18,6 +14,10 @@ static const uint _25 = (_8 % 5u); static const int4 _30 = SPIRV_CROSS_CONSTANT_ID_0; static const int2 _32 = int2(_30.y, _30.x); static const int _33 = _30.y; +#ifndef SPIRV_CROSS_CONSTANT_ID_200 +#define SPIRV_CROSS_CONSTANT_ID_200 3.141590118408203125f +#endif +static const float _9 = SPIRV_CROSS_CONSTANT_ID_200; static float4 gl_Position; static int _4; diff --git a/3rdparty/spirv-cross/reference/shaders-hlsl/comp/composite-array-initialization.comp b/3rdparty/spirv-cross/reference/shaders-hlsl/comp/composite-array-initialization.comp index 675913cf1..dbd8cf704 100644 --- a/3rdparty/spirv-cross/reference/shaders-hlsl/comp/composite-array-initialization.comp +++ b/3rdparty/spirv-cross/reference/shaders-hlsl/comp/composite-array-initialization.comp @@ -1,15 +1,16 @@ -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 4.0f -#endif -static const float X = SPIRV_CROSS_CONSTANT_ID_0; -static const uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); - struct Data { float a; float b; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 4.0f +#endif +static const float X = SPIRV_CROSS_CONSTANT_ID_0; + +static const uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); + static const Data _21 = { 1.0f, 2.0f }; static const Data _24 = { 3.0f, 4.0f }; static const Data _25[2] = { { 1.0f, 2.0f }, { 3.0f, 4.0f } }; diff --git a/3rdparty/spirv-cross/reference/shaders-hlsl/comp/spec-constant-op-member-array.comp b/3rdparty/spirv-cross/reference/shaders-hlsl/comp/spec-constant-op-member-array.comp index ad815b282..c35031b84 100644 --- a/3rdparty/spirv-cross/reference/shaders-hlsl/comp/spec-constant-op-member-array.comp +++ b/3rdparty/spirv-cross/reference/shaders-hlsl/comp/spec-constant-op-member-array.comp @@ -6,15 +6,6 @@ static const int a = SPIRV_CROSS_CONSTANT_ID_0; #define SPIRV_CROSS_CONSTANT_ID_1 200 #endif static const int b = SPIRV_CROSS_CONSTANT_ID_1; -#ifndef SPIRV_CROSS_CONSTANT_ID_2 -#define SPIRV_CROSS_CONSTANT_ID_2 300 -#endif -static const int c = SPIRV_CROSS_CONSTANT_ID_2; -static const int _18 = (c + 50); -#ifndef SPIRV_CROSS_CONSTANT_ID_3 -#define SPIRV_CROSS_CONSTANT_ID_3 400 -#endif -static const int e = SPIRV_CROSS_CONSTANT_ID_3; struct A { @@ -28,6 +19,16 @@ struct B int member1[a]; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_2 +#define SPIRV_CROSS_CONSTANT_ID_2 300 +#endif +static const int c = SPIRV_CROSS_CONSTANT_ID_2; +static const int _18 = (c + 50); +#ifndef SPIRV_CROSS_CONSTANT_ID_3 +#define SPIRV_CROSS_CONSTANT_ID_3 400 +#endif +static const int e = SPIRV_CROSS_CONSTANT_ID_3; + RWByteAddressBuffer _22 : register(u0); static uint3 gl_GlobalInvocationID; diff --git a/3rdparty/spirv-cross/reference/shaders-hlsl/frag/dual-source-blending.frag b/3rdparty/spirv-cross/reference/shaders-hlsl/frag/dual-source-blending.frag new file mode 100644 index 000000000..961e80001 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-hlsl/frag/dual-source-blending.frag @@ -0,0 +1,23 @@ +static float4 FragColor0; +static float4 FragColor1; + +struct SPIRV_Cross_Output +{ + float4 FragColor0 : SV_Target0; + float4 FragColor1 : SV_Target1; +}; + +void frag_main() +{ + FragColor0 = 1.0f.xxxx; + FragColor1 = 2.0f.xxxx; +} + +SPIRV_Cross_Output main() +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor0 = FragColor0; + stage_output.FragColor1 = FragColor1; + return stage_output; +} diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag index f418c072a..d56bef8b2 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag @@ -78,7 +78,7 @@ inline T spvTextureSwizzle(T x, uint s) // Wrapper function that swizzles texture gathers. template -inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) +inline vec spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) { if (sw) { @@ -115,7 +115,7 @@ inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, compon // Wrapper function that swizzles depth texture gathers. template -inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, uint sw) +inline vec spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) { if (sw) { @@ -138,47 +138,57 @@ inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d tex1d [[texture(0)]], texture2d tex2d [[texture(1)]], texture3d tex3d [[texture(2)]], texturecube texCube [[texture(3)]], texture2d_array tex2dArray [[texture(4)]], texturecube_array texCubeArray [[texture(5)]], texture2d texBuffer [[texture(6)]], depth2d depth2d [[texture(7)]], depthcube depthCube [[texture(8)]], depth2d_array depth2dArray [[texture(9)]], depthcube_array 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]); + constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0]; + constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1]; + constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2]; + constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3]; + constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4]; + constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5]; + constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7]; + constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8]; + constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9]; + constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10]; + float4 c = spvTextureSwizzle(tex1d.sample(tex1dSamp, 0.0), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float2(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float3(0.0)), tex3dSwzl); + c = spvTextureSwizzle(texCube.sample(texCubeSamp, float3(0.0)), texCubeSwzl); + c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySamp, float3(0.0).xy, uint(round(float3(0.0).z))), tex2dArraySwzl); + c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w))), texCubeArraySwzl); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), depth2dSwzl); + 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), depthCubeSwzl); + 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), depth2dArraySwzl); + c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), depthCubeArraySwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSamp, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), tex2dSwzl); + 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), tex3dSwzl); 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]); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, _152.xy / _152.z, float4(0.0, 0.0, 1.0, 1.0).z), depth2dSwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSamp, 0.0), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float2(0.0), level(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSamp, float3(0.0), level(0.0)), tex3dSwzl); + c = spvTextureSwizzle(texCube.sample(texCubeSamp, float3(0.0), level(0.0)), texCubeSwzl); + c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySamp, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), tex2dArraySwzl); + c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySamp, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), texCubeArraySwzl); + 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)), depth2dSwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSamp, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSamp, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), tex2dSwzl); + 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)), tex3dSwzl); 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.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSamp, _202.xy / _202.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), depth2dSwzl); + c = spvTextureSwizzle(tex1d.read(uint(0)), tex1dSwzl); + c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), tex2dSwzl); + c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl); + c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl); c = texBuffer.read(spvTexelBufferCoord(0)); - c = spvGatherSwizzle, float2, int2>(tex2dSamp, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]); - c = spvGatherSwizzle, float3>(texCubeSamp, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]); - c = spvGatherSwizzle, float2, uint, int2>(tex2dArraySamp, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]); - c = spvGatherSwizzle, float3, uint>(texCubeArraySamp, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]); - c = spvGatherCompareSwizzle, float2, float>(depth2dSamp, depth2d, float2(0.0), 1.0, spvAuxBuffer.swizzleConst[7]); - c = spvGatherCompareSwizzle, float3, float>(depthCubeSamp, depthCube, float3(0.0), 1.0, spvAuxBuffer.swizzleConst[8]); - c = spvGatherCompareSwizzle, float2, uint, float>(depth2dArraySamp, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, spvAuxBuffer.swizzleConst[9]); - c = spvGatherCompareSwizzle, float3, uint, float>(depthCubeArraySamp, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, spvAuxBuffer.swizzleConst[10]); + c = spvGatherSwizzle, float2, int2>(tex2dSamp, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl); + c = spvGatherSwizzle, float3>(texCubeSamp, texCube, float3(0.0), component::y, texCubeSwzl); + c = spvGatherSwizzle, float2, uint, int2>(tex2dArraySamp, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl); + c = spvGatherSwizzle, float3, uint>(texCubeArraySamp, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl); + c = spvGatherCompareSwizzle, float2, float>(depth2dSamp, depth2d, float2(0.0), 1.0, depth2dSwzl); + c = spvGatherCompareSwizzle, float3, float>(depthCubeSamp, depthCube, float3(0.0), 1.0, depthCubeSwzl); + c = spvGatherCompareSwizzle, float2, uint, float>(depth2dArraySamp, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, depth2dArraySwzl); + c = spvGatherCompareSwizzle, float3, uint, float>(depthCubeArraySamp, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, depthCubeArraySwzl); } diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag index ec765650a..2a2dbe6a2 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag @@ -78,7 +78,7 @@ inline T spvTextureSwizzle(T x, uint s) // Wrapper function that swizzles texture gathers. template -inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) +inline vec spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) { if (sw) { @@ -115,7 +115,7 @@ inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, compon // Wrapper function that swizzles depth texture gathers. template -inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, uint sw) +inline vec spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) { if (sw) { @@ -138,32 +138,38 @@ inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d tex1d [[texture(0)]], texture2d tex2d [[texture(1)]], texture3d tex3d [[texture(2)]], texturecube texCube [[texture(3)]], texture2d_array tex2dArray [[texture(4)]], texturecube_array texCubeArray [[texture(5)]], texture2d 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])); + constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0]; + constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1]; + constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2]; + constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3]; + constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4]; + constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5]; + float4 c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl)); + c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl)); + c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), texCubeSwzl)); + c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), tex2dArraySwzl)); + c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), texCubeArraySwzl)); + c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), tex2dSwzl)); + 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), tex3dSwzl)); + c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), tex2dSwzl)); + c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), tex3dSwzl)); + c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), texCubeSwzl)); + c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), tex2dArraySwzl)); + c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), texCubeArraySwzl)); + c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl)); + 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)), tex2dSwzl)); + 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)), tex3dSwzl)); + c = float4(spvTextureSwizzle(tex1d.read(uint(0)), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), tex2dSwzl)); + 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, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1])); - c = float4(spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3])); - c = float4(spvGatherSwizzle, 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, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5])); + c = float4(spvGatherSwizzle, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl)); + c = float4(spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl)); + c = float4(spvGatherSwizzle, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl)); + c = float4(spvGatherSwizzle, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl)); } diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag index b821c1c50..250bc0e26 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag @@ -78,7 +78,7 @@ inline T spvTextureSwizzle(T x, uint s) // Wrapper function that swizzles texture gathers. template -inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) +inline vec spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) { if (sw) { @@ -115,7 +115,7 @@ inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, compon // Wrapper function that swizzles depth texture gathers. template -inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, uint sw) +inline vec spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) { if (sw) { @@ -136,55 +136,65 @@ inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, return t.gather_compare(s, spvForward(params)...); } -float4 doSwizzle(thread texture1d tex1d, thread const sampler tex1dSmplr, thread texture2d tex2d, thread const sampler tex2dSmplr, thread texture3d tex3d, thread const sampler tex3dSmplr, thread texturecube texCube, thread const sampler texCubeSmplr, thread texture2d_array tex2dArray, thread const sampler tex2dArraySmplr, thread texturecube_array texCubeArray, thread const sampler texCubeArraySmplr, thread depth2d depth2d, thread const sampler depth2dSmplr, thread depthcube depthCube, thread const sampler depthCubeSmplr, thread depth2d_array depth2dArray, thread const sampler depth2dArraySmplr, thread depthcube_array depthCubeArray, thread const sampler depthCubeArraySmplr, thread texture2d texBuffer, constant spvAux& spvAuxBuffer) +float4 doSwizzle(thread texture1d tex1d, thread const sampler tex1dSmplr, constant uint32_t& tex1dSwzl, thread texture2d tex2d, thread const sampler tex2dSmplr, constant uint32_t& tex2dSwzl, thread texture3d tex3d, thread const sampler tex3dSmplr, constant uint32_t& tex3dSwzl, thread texturecube texCube, thread const sampler texCubeSmplr, constant uint32_t& texCubeSwzl, thread texture2d_array tex2dArray, thread const sampler tex2dArraySmplr, constant uint32_t& tex2dArraySwzl, thread texturecube_array texCubeArray, thread const sampler texCubeArraySmplr, constant uint32_t& texCubeArraySwzl, thread depth2d depth2d, thread const sampler depth2dSmplr, constant uint32_t& depth2dSwzl, thread depthcube depthCube, thread const sampler depthCubeSmplr, constant uint32_t& depthCubeSwzl, thread depth2d_array depth2dArray, thread const sampler depth2dArraySmplr, constant uint32_t& depth2dArraySwzl, thread depthcube_array depthCubeArray, thread const sampler depthCubeArraySmplr, constant uint32_t& depthCubeArraySwzl, thread texture2d 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 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl); + c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), texCubeSwzl); + c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), tex2dArraySwzl); + c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), texCubeArraySwzl); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), depth2dSwzl); + c.x = spvTextureSwizzle(depthCube.sample_compare(depthCubeSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz, float4(0.0, 0.0, 0.0, 1.0).w), depthCubeSwzl); + c.x = spvTextureSwizzle(depth2dArray.sample_compare(depth2dArraySmplr, float4(0.0, 0.0, 0.0, 1.0).xy, uint(round(float4(0.0, 0.0, 0.0, 1.0).z)), float4(0.0, 0.0, 0.0, 1.0).w), depth2dArraySwzl); + c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), depthCubeArraySwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), tex3dSwzl); 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]); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _103.xy / _103.z, float4(0.0, 0.0, 1.0, 1.0).z), depth2dSwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), tex3dSwzl); + c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), texCubeSwzl); + c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), tex2dArraySwzl); + c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), texCubeArraySwzl); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z, level(0.0)), depth2dSwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w, level(0.0)), tex3dSwzl); 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.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _131.xy / _131.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), depth2dSwzl); + c = spvTextureSwizzle(tex1d.read(uint(0)), tex1dSwzl); + c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), tex2dSwzl); + c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl); + c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl); c = texBuffer.read(spvTexelBufferCoord(0)); - c = spvGatherSwizzle, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]); - c = spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]); - c = spvGatherSwizzle, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]); - c = spvGatherSwizzle, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]); - c = spvGatherCompareSwizzle, float2, float>(depth2dSmplr, depth2d, float2(0.0), 1.0, spvAuxBuffer.swizzleConst[7]); - c = spvGatherCompareSwizzle, float3, float>(depthCubeSmplr, depthCube, float3(0.0), 1.0, spvAuxBuffer.swizzleConst[8]); - c = spvGatherCompareSwizzle, float2, uint, float>(depth2dArraySmplr, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, spvAuxBuffer.swizzleConst[9]); - c = spvGatherCompareSwizzle, float3, uint, float>(depthCubeArraySmplr, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, spvAuxBuffer.swizzleConst[10]); + c = spvGatherSwizzle, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl); + c = spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl); + c = spvGatherSwizzle, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl); + c = spvGatherSwizzle, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl); + c = spvGatherCompareSwizzle, float2, float>(depth2dSmplr, depth2d, float2(0.0), 1.0, depth2dSwzl); + c = spvGatherCompareSwizzle, float3, float>(depthCubeSmplr, depthCube, float3(0.0), 1.0, depthCubeSwzl); + c = spvGatherCompareSwizzle, float2, uint, float>(depth2dArraySmplr, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, depth2dArraySwzl); + c = spvGatherCompareSwizzle, float3, uint, float>(depthCubeArraySmplr, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, depthCubeArraySwzl); return c; } fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d tex1d [[texture(0)]], texture2d tex2d [[texture(1)]], texture3d tex3d [[texture(2)]], texturecube texCube [[texture(3)]], texture2d_array tex2dArray [[texture(4)]], texturecube_array texCubeArray [[texture(5)]], texture2d texBuffer [[texture(6)]], depth2d depth2d [[texture(7)]], depthcube depthCube [[texture(8)]], depth2d_array depth2dArray [[texture(9)]], depthcube_array 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); + constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0]; + constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1]; + constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2]; + constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3]; + constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4]; + constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5]; + constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7]; + constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8]; + constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9]; + constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10]; + float4 c = doSwizzle(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSmplr, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSmplr, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySmplr, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, texBuffer, spvAuxBuffer); } diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag index f4ff6717e..fa8a385c3 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag @@ -78,7 +78,7 @@ inline T spvTextureSwizzle(T x, uint s) // Wrapper function that swizzles texture gathers. template -inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) +inline vec spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) { if (sw) { @@ -115,7 +115,7 @@ inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, compon // Wrapper function that swizzles depth texture gathers. template -inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, uint sw) +inline vec spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) { if (sw) { @@ -138,32 +138,38 @@ inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d tex1d [[texture(0)]], texture2d tex2d [[texture(1)]], texture3d tex3d [[texture(2)]], texturecube texCube [[texture(3)]], texture2d_array tex2dArray [[texture(4)]], texturecube_array texCubeArray [[texture(5)]], texture2d 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])); + constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0]; + constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1]; + constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2]; + constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3]; + constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4]; + constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5]; + float4 c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl)); + c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl)); + c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), texCubeSwzl)); + c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), tex2dArraySwzl)); + c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), texCubeArraySwzl)); + c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), tex2dSwzl)); + 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), tex3dSwzl)); + c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), tex2dSwzl)); + c = float4(spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), tex3dSwzl)); + c = float4(spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), texCubeSwzl)); + c = float4(spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), tex2dArraySwzl)); + c = float4(spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), texCubeArraySwzl)); + c = float4(spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl)); + 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)), tex2dSwzl)); + 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)), tex3dSwzl)); + c = float4(spvTextureSwizzle(tex1d.read(uint(0)), tex1dSwzl)); + c = float4(spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), tex2dSwzl)); + 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, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1])); - c = float4(spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3])); - c = float4(spvGatherSwizzle, 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, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5])); + c = float4(spvGatherSwizzle, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl)); + c = float4(spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl)); + c = float4(spvGatherSwizzle, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl)); + c = float4(spvGatherSwizzle, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl)); } diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag index 7997d894e..9d1abcaec 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag @@ -78,7 +78,7 @@ inline T spvTextureSwizzle(T x, uint s) // Wrapper function that swizzles texture gathers. template -inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) +inline vec spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) METAL_CONST_ARG(c) { if (sw) { @@ -115,7 +115,7 @@ inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, compon // Wrapper function that swizzles depth texture gathers. template -inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, uint sw) +inline vec spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) { if (sw) { @@ -138,47 +138,57 @@ inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d tex1d [[texture(0)]], texture2d tex2d [[texture(1)]], texture3d tex3d [[texture(2)]], texturecube texCube [[texture(3)]], texture2d_array tex2dArray [[texture(4)]], texturecube_array texCubeArray [[texture(5)]], texture2d texBuffer [[texture(6)]], depth2d depth2d [[texture(7)]], depthcube depthCube [[texture(8)]], depth2d_array depth2dArray [[texture(9)]], depthcube_array 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]); + constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0]; + constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1]; + constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2]; + constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3]; + constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4]; + constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5]; + constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7]; + constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8]; + constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9]; + constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10]; + float4 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0)), tex3dSwzl); + c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0)), texCubeSwzl); + c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z))), tex2dArraySwzl); + c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), texCubeArraySwzl); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), depth2dSwzl); + c.x = spvTextureSwizzle(depthCube.sample_compare(depthCubeSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz, float4(0.0, 0.0, 0.0, 1.0).w), depthCubeSwzl); + c.x = spvTextureSwizzle(depth2dArray.sample_compare(depth2dArraySmplr, float4(0.0, 0.0, 0.0, 1.0).xy, uint(round(float4(0.0, 0.0, 0.0, 1.0).z)), float4(0.0, 0.0, 0.0, 1.0).w), depth2dArraySwzl); + c.x = spvTextureSwizzle(depthCubeArray.sample_compare(depthCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), depthCubeArraySwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), tex3dSwzl); 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]); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _100.xy / _100.z, float4(0.0, 0.0, 1.0, 1.0).z), depth2dSwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0), level(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float3(0.0), level(0.0)), tex3dSwzl); + c = spvTextureSwizzle(texCube.sample(texCubeSmplr, float3(0.0), level(0.0)), texCubeSwzl); + c = spvTextureSwizzle(tex2dArray.sample(tex2dArraySmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), tex2dArraySwzl); + c = spvTextureSwizzle(texCubeArray.sample(texCubeArraySmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), texCubeArraySwzl); + c.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z, level(0.0)), depth2dSwzl); + c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), tex1dSwzl); + c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), tex2dSwzl); + c = spvTextureSwizzle(tex3d.sample(tex3dSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w, level(0.0)), tex3dSwzl); 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.x = spvTextureSwizzle(depth2d.sample_compare(depth2dSmplr, _128.xy / _128.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), depth2dSwzl); + c = spvTextureSwizzle(tex1d.read(uint(0)), tex1dSwzl); + c = spvTextureSwizzle(tex2d.read(uint2(int2(0)), 0), tex2dSwzl); + c = spvTextureSwizzle(tex3d.read(uint3(int3(0)), 0), tex3dSwzl); + c = spvTextureSwizzle(tex2dArray.read(uint2(int3(0).xy), uint(int3(0).z), 0), tex2dArraySwzl); c = texBuffer.read(spvTexelBufferCoord(0)); - c = spvGatherSwizzle, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, spvAuxBuffer.swizzleConst[1]); - c = spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, spvAuxBuffer.swizzleConst[3]); - c = spvGatherSwizzle, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, spvAuxBuffer.swizzleConst[4]); - c = spvGatherSwizzle, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, spvAuxBuffer.swizzleConst[5]); - c = spvGatherCompareSwizzle, float2, float>(depth2dSmplr, depth2d, float2(0.0), 1.0, spvAuxBuffer.swizzleConst[7]); - c = spvGatherCompareSwizzle, float3, float>(depthCubeSmplr, depthCube, float3(0.0), 1.0, spvAuxBuffer.swizzleConst[8]); - c = spvGatherCompareSwizzle, float2, uint, float>(depth2dArraySmplr, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, spvAuxBuffer.swizzleConst[9]); - c = spvGatherCompareSwizzle, float3, uint, float>(depthCubeArraySmplr, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, spvAuxBuffer.swizzleConst[10]); + c = spvGatherSwizzle, float2, int2>(tex2dSmplr, tex2d, float2(0.0), int2(0), component::x, tex2dSwzl); + c = spvGatherSwizzle, float3>(texCubeSmplr, texCube, float3(0.0), component::y, texCubeSwzl); + c = spvGatherSwizzle, float2, uint, int2>(tex2dArraySmplr, tex2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, tex2dArraySwzl); + c = spvGatherSwizzle, float3, uint>(texCubeArraySmplr, texCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, texCubeArraySwzl); + c = spvGatherCompareSwizzle, float2, float>(depth2dSmplr, depth2d, float2(0.0), 1.0, depth2dSwzl); + c = spvGatherCompareSwizzle, float3, float>(depthCubeSmplr, depthCube, float3(0.0), 1.0, depthCubeSwzl); + c = spvGatherCompareSwizzle, float2, uint, float>(depth2dArraySmplr, depth2dArray, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, depth2dArraySwzl); + c = spvGatherCompareSwizzle, float3, uint, float>(depthCubeArraySmplr, depthCubeArray, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, depthCubeArraySwzl); } diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/vert/pass-array-by-value.vert b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/vert/pass-array-by-value.vert new file mode 100644 index 000000000..ab5631366 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/vert/pass-array-by-value.vert @@ -0,0 +1,60 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +constant float4 _68[4] = { float4(0.0), float4(1.0), float4(2.0), float4(3.0) }; + +struct main0_out +{ + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + int Index1 [[attribute(0)]]; + int Index2 [[attribute(1)]]; +}; + +// Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. +template +void spvArrayCopyFromStack1(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +template +void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +float4 consume_constant_arrays2(thread const float4 (&positions)[4], thread const float4 (&positions2)[4], thread int& Index1, thread int& Index2) +{ + float4 indexable[4]; + spvArrayCopyFromStack1(indexable, positions); + float4 indexable_1[4]; + spvArrayCopyFromStack1(indexable_1, positions2); + return indexable[Index1] + indexable_1[Index2]; +} + +float4 consume_constant_arrays(thread const float4 (&positions)[4], thread const float4 (&positions2)[4], thread int& Index1, thread int& Index2) +{ + return consume_constant_arrays2(positions, positions2, Index1, Index2); +} + +vertex main0_out main0(main0_in in [[stage_in]]) +{ + float4 _68_array_copy[4] = { float4(0.0), float4(1.0), float4(2.0), float4(3.0) }; + main0_out out = {}; + float4 LUT2[4]; + LUT2[0] = float4(10.0); + LUT2[1] = float4(11.0); + LUT2[2] = float4(12.0); + LUT2[3] = float4(13.0); + out.gl_Position = consume_constant_arrays(_68_array_copy, LUT2, in.Index1, in.Index2); + return out; +} + diff --git a/3rdparty/spirv-cross/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag new file mode 100644 index 000000000..b34a1ec81 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag @@ -0,0 +1,207 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct spvAux +{ + uint swizzleConst[1]; +}; + +struct main0_out +{ + float4 fragColor [[color(0)]]; +}; + +// 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 struct spvRemoveReference { typedef T type; }; +template struct spvRemoveReference { typedef T type; }; +template struct spvRemoveReference { typedef T type; }; +template inline constexpr thread T&& spvForward(thread typename spvRemoveReference::type& x) +{ + return static_cast(x); +} +template inline constexpr thread T&& spvForward(thread typename spvRemoveReference::type&& x) +{ + return static_cast(x); +} + +template +inline T spvGetSwizzle(vec x, T c, spvSwizzle s) +{ + switch (s) + { + case spvSwizzle::none: + return c; + case spvSwizzle::zero: + return 0; + case spvSwizzle::one: + return 1; + case spvSwizzle::red: + return x.r; + case spvSwizzle::green: + return x.g; + case spvSwizzle::blue: + return x.b; + case spvSwizzle::alpha: + return x.a; + } +} + +// Wrapper function that swizzles texture samples and fetches. +template +inline vec spvTextureSwizzle(vec x, uint s) +{ + if (!s) + return x; + return vec(spvGetSwizzle(x, x.r, spvSwizzle((s >> 0) & 0xFF)), spvGetSwizzle(x, x.g, spvSwizzle((s >> 8) & 0xFF)), spvGetSwizzle(x, x.b, spvSwizzle((s >> 16) & 0xFF)), spvGetSwizzle(x, x.a, spvSwizzle((s >> 24) & 0xFF))); +} + +template +inline T spvTextureSwizzle(T x, uint s) +{ + return spvTextureSwizzle(vec(x, 0, 0, 1), s).x; +} + +// Wrapper function that swizzles texture gathers. +template +inline vec 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(0, 0, 0, 0); + case spvSwizzle::one: + return vec(1, 1, 1, 1); + case spvSwizzle::red: + return t.gather(s, spvForward(params)..., component::x); + case spvSwizzle::green: + return t.gather(s, spvForward(params)..., component::y); + case spvSwizzle::blue: + return t.gather(s, spvForward(params)..., component::z); + case spvSwizzle::alpha: + return t.gather(s, spvForward(params)..., component::w); + } + } + switch (c) + { + case component::x: + return t.gather(s, spvForward(params)..., component::x); + case component::y: + return t.gather(s, spvForward(params)..., component::y); + case component::z: + return t.gather(s, spvForward(params)..., component::z); + case component::w: + return t.gather(s, spvForward(params)..., component::w); + } +} + +// Wrapper function that swizzles depth texture gathers. +template +inline vec 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(0, 0, 0, 0); + case spvSwizzle::one: + return vec(1, 1, 1, 1); + } + } + return t.gather_compare(s, spvForward(params)...); +} + +float4 do_samples(thread const texture1d t1, thread const sampler t1Smplr, constant uint32_t& t1Swzl, thread const texture2d t2, constant uint32_t& t2Swzl, thread const texture3d t3, thread const sampler t3Smplr, constant uint32_t& t3Swzl, thread const texturecube tc, constant uint32_t& tcSwzl, thread const texture2d_array t2a, thread const sampler t2aSmplr, constant uint32_t& t2aSwzl, thread const texturecube_array tca, thread const sampler tcaSmplr, constant uint32_t& tcaSwzl, thread const texture2d tb, thread const depth2d d2, thread const sampler d2Smplr, constant uint32_t& d2Swzl, thread const depthcube dc, thread const sampler dcSmplr, constant uint32_t& dcSwzl, thread const depth2d_array d2a, constant uint32_t& d2aSwzl, thread const depthcube_array dca, thread const sampler dcaSmplr, constant uint32_t& dcaSwzl, thread sampler defaultSampler, thread sampler shadowSampler, constant spvAux& spvAuxBuffer) +{ + float4 c = spvTextureSwizzle(t1.sample(t1Smplr, 0.0), t1Swzl); + c = spvTextureSwizzle(t2.sample(defaultSampler, float2(0.0)), t2Swzl); + c = spvTextureSwizzle(t3.sample(t3Smplr, float3(0.0)), t3Swzl); + c = spvTextureSwizzle(tc.sample(defaultSampler, float3(0.0)), tcSwzl); + c = spvTextureSwizzle(t2a.sample(t2aSmplr, float3(0.0).xy, uint(round(float3(0.0).z))), t2aSwzl); + c = spvTextureSwizzle(tca.sample(tcaSmplr, float4(0.0).xyz, uint(round(float4(0.0).w))), tcaSwzl); + c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z), d2Swzl); + c.x = spvTextureSwizzle(dc.sample_compare(dcSmplr, float4(0.0, 0.0, 0.0, 1.0).xyz, float4(0.0, 0.0, 0.0, 1.0).w), dcSwzl); + c.x = spvTextureSwizzle(d2a.sample_compare(shadowSampler, 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), d2aSwzl); + c.x = spvTextureSwizzle(dca.sample_compare(dcaSmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0), dcaSwzl); + c = spvTextureSwizzle(t1.sample(t1Smplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), t1Swzl); + c = spvTextureSwizzle(t2.sample(defaultSampler, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z), t2Swzl); + c = spvTextureSwizzle(t3.sample(t3Smplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w), t3Swzl); + float4 _119 = float4(0.0, 0.0, 1.0, 1.0); + _119.z = float4(0.0, 0.0, 1.0, 1.0).w; + c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, _119.xy / _119.z, float4(0.0, 0.0, 1.0, 1.0).z), d2Swzl); + c = spvTextureSwizzle(t1.sample(t1Smplr, 0.0), t1Swzl); + c = spvTextureSwizzle(t2.sample(defaultSampler, float2(0.0), level(0.0)), t2Swzl); + c = spvTextureSwizzle(t3.sample(t3Smplr, float3(0.0), level(0.0)), t3Swzl); + c = spvTextureSwizzle(tc.sample(defaultSampler, float3(0.0), level(0.0)), tcSwzl); + c = spvTextureSwizzle(t2a.sample(t2aSmplr, float3(0.0).xy, uint(round(float3(0.0).z)), level(0.0)), t2aSwzl); + c = spvTextureSwizzle(tca.sample(tcaSmplr, float4(0.0).xyz, uint(round(float4(0.0).w)), level(0.0)), tcaSwzl); + c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, float3(0.0, 0.0, 1.0).xy, float3(0.0, 0.0, 1.0).z, level(0.0)), d2Swzl); + c = spvTextureSwizzle(t1.sample(t1Smplr, float2(0.0, 1.0).x / float2(0.0, 1.0).y), t1Swzl); + c = spvTextureSwizzle(t2.sample(defaultSampler, float3(0.0, 0.0, 1.0).xy / float3(0.0, 0.0, 1.0).z, level(0.0)), t2Swzl); + c = spvTextureSwizzle(t3.sample(t3Smplr, float4(0.0, 0.0, 0.0, 1.0).xyz / float4(0.0, 0.0, 0.0, 1.0).w, level(0.0)), t3Swzl); + float4 _153 = float4(0.0, 0.0, 1.0, 1.0); + _153.z = float4(0.0, 0.0, 1.0, 1.0).w; + c.x = spvTextureSwizzle(d2.sample_compare(d2Smplr, _153.xy / _153.z, float4(0.0, 0.0, 1.0, 1.0).z, level(0.0)), d2Swzl); + c = spvTextureSwizzle(t1.read(uint(0)), t1Swzl); + c = spvTextureSwizzle(t2.read(uint2(int2(0)), 0), t2Swzl); + 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, float2, int2>(defaultSampler, t2, float2(0.0), int2(0), component::x, t2Swzl); + c = spvGatherSwizzle, float3>(defaultSampler, tc, float3(0.0), component::y, tcSwzl); + c = spvGatherSwizzle, float2, uint, int2>(t2aSmplr, t2a, float3(0.0).xy, uint(round(float3(0.0).z)), int2(0), component::z, t2aSwzl); + c = spvGatherSwizzle, float3, uint>(tcaSmplr, tca, float4(0.0).xyz, uint(round(float4(0.0).w)), component::w, tcaSwzl); + c = spvGatherCompareSwizzle, float2, float>(d2Smplr, d2, float2(0.0), 1.0, d2Swzl); + c = spvGatherCompareSwizzle, float3, float>(dcSmplr, dc, float3(0.0), 1.0, dcSwzl); + c = spvGatherCompareSwizzle, float2, uint, float>(shadowSampler, d2a, float3(0.0).xy, uint(round(float3(0.0).z)), 1.0, d2aSwzl); + c = spvGatherCompareSwizzle, float3, uint, float>(dcaSmplr, dca, float4(0.0).xyz, uint(round(float4(0.0).w)), 1.0, dcaSwzl); + return c; +} + +fragment main0_out main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d tex1d [[texture(0)]], texture2d tex2d [[texture(1)]], texture3d tex3d [[texture(2)]], texturecube texCube [[texture(3)]], texture2d_array tex2dArray [[texture(4)]], texturecube_array texCubeArray [[texture(5)]], texture2d texBuffer [[texture(6)]], depth2d depth2d [[texture(7)]], depthcube depthCube [[texture(8)]], depth2d_array depth2dArray [[texture(9)]], depthcube_array depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex3dSmplr [[sampler(2)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depthCubeArraySmplr [[sampler(10)]], sampler defaultSampler [[sampler(11)]], sampler shadowSampler [[sampler(12)]]) +{ + main0_out out = {}; + constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0]; + constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1]; + constant uint32_t& tex3dSwzl = spvAuxBuffer.swizzleConst[2]; + constant uint32_t& texCubeSwzl = spvAuxBuffer.swizzleConst[3]; + constant uint32_t& tex2dArraySwzl = spvAuxBuffer.swizzleConst[4]; + constant uint32_t& texCubeArraySwzl = spvAuxBuffer.swizzleConst[5]; + constant uint32_t& depth2dSwzl = spvAuxBuffer.swizzleConst[7]; + constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8]; + constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9]; + constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10]; + out.fragColor = do_samples(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, texBuffer, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, defaultSampler, shadowSampler, spvAuxBuffer); + return out; +} + diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp index 5802ddac9..1cf531c4b 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/specialization-constant-workgroup.asm.comp @@ -3,17 +3,17 @@ using namespace metal; +struct SSBO +{ + float a; +}; + constant uint _5_tmp [[function_constant(10)]]; constant uint _5 = is_function_constant_defined(_5_tmp) ? _5_tmp : 9u; constant uint _6_tmp [[function_constant(12)]]; constant uint _6 = is_function_constant_defined(_6_tmp) ? _6_tmp : 4u; constant uint3 gl_WorkGroupSize = uint3(_5, 20u, _6); -struct SSBO -{ - float a; -}; - kernel void main0(device SSBO& _4 [[buffer(0)]]) { _4.a += 1.0; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp index 2c9b038b2..8c56e7af4 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/storage-buffer-basic.invalid.asm.comp @@ -3,17 +3,17 @@ using namespace metal; +struct _6 +{ + float _m0[1]; +}; + constant uint _3_tmp [[function_constant(0)]]; constant uint _3 = is_function_constant_defined(_3_tmp) ? _3_tmp : 1u; constant uint _4_tmp [[function_constant(2)]]; constant uint _4 = is_function_constant_defined(_4_tmp) ? _4_tmp : 3u; constant uint3 gl_WorkGroupSize = uint3(_3, 2u, _4); -struct _6 -{ - float _m0[1]; -}; - kernel void main0(device _6& _8 [[buffer(0)]], device _6& _9 [[buffer(1)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) { _8._m0[gl_WorkGroupID.x] = _9._m0[gl_WorkGroupID.x] + _8._m0[gl_WorkGroupID.x]; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp index 55afb839b..a16d019cc 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast-func.asm.comp @@ -5,13 +5,13 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); - struct cb1_struct { float4 _m0[1]; }; +constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); + int2 get_texcoord(thread const int2& base, thread const int2& index, thread uint3& gl_LocalInvocationID) { return (base * int3(gl_LocalInvocationID).xy) + index; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp index 0e3ebd72a..0ece12c11 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/comp/vector-builtin-type-cast.asm.comp @@ -3,13 +3,13 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); - struct cb1_struct { float4 _m0[1]; }; +constant uint3 gl_WorkGroupSize = uint3(16u, 16u, 1u); + kernel void main0(constant cb1_struct& cb0_1 [[buffer(0)]], texture2d u0 [[texture(1)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { int2 r0 = int2(int2(u0.get_width(), u0.get_height()) >> int2(uint2(4u))); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/extract-packed-from-composite.asm.frag b/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/extract-packed-from-composite.asm.frag index 1eabc93a2..7d51b1538 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/extract-packed-from-composite.asm.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/extract-packed-from-composite.asm.frag @@ -7,19 +7,19 @@ using namespace metal; struct Foo { - float3 a; + packed_float3 a; float b; }; struct Foo_1 { - packed_float3 a; + float3 a; float b; }; struct buf { - Foo_1 results[16]; + Foo results[16]; float4 bar; }; @@ -31,7 +31,7 @@ struct main0_out float4 _main(thread const float4& pos, constant buf& v_11) { int _46 = int(pos.x) % 16; - Foo foo; + Foo_1 foo; foo.a = v_11.results[_46].a; foo.b = v_11.results[_46].b; return float4(dot(foo.a, v_11.bar.xyz), foo.b, 0.0, 0.0); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag b/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag index d06da7a68..74bd618c4 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/vector-shuffle-oom.asm.frag @@ -3,6 +3,11 @@ using namespace metal; +struct _28 +{ + float4 _m0; +}; + struct _6 { float4 _m0; @@ -113,11 +118,6 @@ struct _21 float4 _m0; }; -struct _28 -{ - float4 _m0; -}; - constant _28 _74 = {}; struct main0_out diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert b/3rdparty/spirv-cross/reference/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert index 67485d732..05a69e48a 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/vert/spec-constant-op-composite.asm.vert @@ -5,15 +5,15 @@ using namespace metal; constant int _7_tmp [[function_constant(201)]]; constant int _7 = is_function_constant_defined(_7_tmp) ? _7_tmp : -10; +constant int _20 = (_7 + 2); constant uint _8_tmp [[function_constant(202)]]; constant uint _8 = is_function_constant_defined(_8_tmp) ? _8_tmp : 100u; -constant float _9_tmp [[function_constant(200)]]; -constant float _9 = is_function_constant_defined(_9_tmp) ? _9_tmp : 3.141590118408203125; -constant int _20 = (_7 + 2); constant uint _25 = (_8 % 5u); constant int4 _30 = int4(20, 30, _20, _20); constant int2 _32 = int2(_30.y, _30.x); constant int _33 = _30.y; +constant float _9_tmp [[function_constant(200)]]; +constant float _9 = is_function_constant_defined(_9_tmp) ? _9_tmp : 3.141590118408203125; struct main0_out { diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/composite-array-initialization.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/composite-array-initialization.comp index 1a901dc8e..37a36b7fe 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/composite-array-initialization.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/composite-array-initialization.comp @@ -5,10 +5,6 @@ using namespace metal; -constant float X_tmp [[function_constant(0)]]; -constant float X = is_function_constant_defined(X_tmp) ? X_tmp : 4.0; -constant uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); - struct Data { float a; @@ -21,12 +17,17 @@ struct Data_1 float b; }; +constant float X_tmp [[function_constant(0)]]; +constant float X = is_function_constant_defined(X_tmp) ? X_tmp : 4.0; + struct SSBO { - Data_1 outdata[1]; + Data outdata[1]; }; -constant Data _25[2] = { Data{ 1.0, 2.0 }, Data{ 3.0, 4.0 } }; +constant uint3 gl_WorkGroupSize = uint3(2u, 1u, 1u); + +constant Data_1 _25[2] = { Data_1{ 1.0, 2.0 }, Data_1{ 3.0, 4.0 } }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. template @@ -41,20 +42,20 @@ void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N]) for (uint i = 0; i < N; dst[i] = src[i], i++); } -Data combine(thread const Data& a, thread const Data& b) +Data_1 combine(thread const Data_1& a, thread const Data_1& b) { - return Data{ a.a + b.a, a.b + b.b }; + return Data_1{ a.a + b.a, a.b + b.b }; } kernel void main0(device SSBO& _53 [[buffer(0)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { - Data data[2] = { Data{ 1.0, 2.0 }, Data{ 3.0, 4.0 } }; - Data _31[2] = { Data{ X, 2.0 }, Data{ 3.0, 5.0 } }; - Data data2[2]; + Data_1 data[2] = { Data_1{ 1.0, 2.0 }, Data_1{ 3.0, 4.0 } }; + Data_1 _31[2] = { Data_1{ X, 2.0 }, Data_1{ 3.0, 5.0 } }; + Data_1 data2[2]; spvArrayCopyFromStack1(data2, _31); - Data param = data[gl_LocalInvocationID.x]; - Data param_1 = data2[gl_LocalInvocationID.x]; - Data _73 = combine(param, param_1); + Data_1 param = data[gl_LocalInvocationID.x]; + Data_1 param_1 = data2[gl_LocalInvocationID.x]; + Data_1 _73 = combine(param, param_1); _53.outdata[gl_WorkGroupID.x].a = _73.a; _53.outdata[gl_WorkGroupID.x].b = _73.b; } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/culling.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/culling.comp index 1f6bdcbee..e6d8f44af 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/culling.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/culling.comp @@ -6,8 +6,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); - struct SSBO { float in_data[1]; @@ -23,6 +21,8 @@ struct SSBO3 uint count; }; +constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); + kernel void main0(const device SSBO& _22 [[buffer(0)]], device SSBO2& _38 [[buffer(1)]], device SSBO3& _41 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { uint ident = gl_GlobalInvocationID.x; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-1.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-1.comp index d98ad59aa..92351c67a 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-1.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-1.comp @@ -3,23 +3,21 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); - struct T1 -{ - float3 a; - float b; -}; - -struct T1_1 { packed_float3 a; float b; }; +struct T1_1 +{ + float3 a; + float b; +}; + struct Buffer0 { - T1_1 buf0[1]; + T1 buf0[1]; }; struct Buffer1 @@ -27,9 +25,11 @@ struct Buffer1 float buf1[1]; }; +constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); + kernel void main0(device Buffer0& _15 [[buffer(1)]], device Buffer1& _34 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { - T1 v; + T1_1 v; v.a = _15.buf0[0].a; v.b = _15.buf0[0].b; float x = v.b; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-2.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-2.comp index dfccbf863..cdf909ff8 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-2.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/packing-test-2.comp @@ -3,8 +3,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); - struct T1 { packed_float3 a; @@ -21,6 +19,8 @@ struct Buffer1 float buf1[1]; }; +constant uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); + kernel void main0(device Buffer0& _14 [[buffer(1)]], device Buffer1& _24 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { float x = _14.buf0[0].b; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/shared-array-of-arrays.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/shared-array-of-arrays.comp index 3133e5f29..9a09e2978 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/shared-array-of-arrays.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/shared-array-of-arrays.comp @@ -5,13 +5,13 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(4u, 4u, 1u); - struct SSBO { float out_data[1]; }; +constant uint3 gl_WorkGroupSize = uint3(4u, 4u, 1u); + void work(threadgroup float (&foo)[4][4], thread uint3& gl_LocalInvocationID, thread uint& gl_LocalInvocationIndex, device SSBO& v_67, thread uint3& gl_GlobalInvocationID) { foo[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = float(gl_LocalInvocationIndex); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/shared.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/shared.comp index e296190bd..3648639c6 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/shared.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/shared.comp @@ -3,8 +3,6 @@ using namespace metal; -constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); - struct SSBO { float in_data[1]; @@ -15,6 +13,8 @@ struct SSBO2 float out_data[1]; }; +constant uint3 gl_WorkGroupSize = uint3(4u, 1u, 1u); + kernel void main0(const device SSBO& _22 [[buffer(0)]], device SSBO2& _44 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]]) { threadgroup float sShared[4]; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-op-member-array.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-op-member-array.comp index 35ebe1592..1d78f3f4f 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-op-member-array.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-op-member-array.comp @@ -11,13 +11,6 @@ constant int a = SPIRV_CROSS_CONSTANT_ID_0; #define SPIRV_CROSS_CONSTANT_ID_1 200 #endif constant int b = SPIRV_CROSS_CONSTANT_ID_1; -#ifndef SPIRV_CROSS_CONSTANT_ID_2 -#define SPIRV_CROSS_CONSTANT_ID_2 300 -#endif -constant int c = SPIRV_CROSS_CONSTANT_ID_2; -constant int _18 = (c + 50); -constant int e_tmp [[function_constant(3)]]; -constant int e = is_function_constant_defined(e_tmp) ? e_tmp : 400; struct A { @@ -31,6 +24,12 @@ struct B int member1[a]; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_2 +#define SPIRV_CROSS_CONSTANT_ID_2 300 +#endif +constant int c = SPIRV_CROSS_CONSTANT_ID_2; +constant int _18 = (c + 50); + struct SSBO { A member_a; @@ -39,6 +38,9 @@ struct SSBO int w[_18]; }; +constant int e_tmp [[function_constant(3)]]; +constant int e = is_function_constant_defined(e_tmp) ? e_tmp : 400; + kernel void main0(device SSBO& _22 [[buffer(0)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { _22.w[gl_GlobalInvocationID.x] += (_22.v[gl_GlobalInvocationID.x] + e); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-work-group-size.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-work-group-size.comp index e46ab8939..b875e1bb5 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-work-group-size.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/spec-constant-work-group-size.comp @@ -9,6 +9,12 @@ using namespace metal; constant int b = SPIRV_CROSS_CONSTANT_ID_1; constant int a_tmp [[function_constant(0)]]; constant int a = is_function_constant_defined(a_tmp) ? a_tmp : 1; + +struct SSBO +{ + int v[1]; +}; + constant uint _21 = (uint(a) + 0u); constant uint _22_tmp [[function_constant(10)]]; constant uint _22 = is_function_constant_defined(_22_tmp) ? _22_tmp : 1u; @@ -19,11 +25,6 @@ constant uint _29 = gl_WorkGroupSize.y; constant uint _30 = (_28 + _29); constant int _32 = (1 - a); -struct SSBO -{ - int v[1]; -}; - kernel void main0(device SSBO& _17 [[buffer(0)]]) { int spec_const_array_size[b]; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/struct-nested.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/struct-nested.comp index 117e492d6..c94d9c335 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/struct-nested.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/struct-nested.comp @@ -13,24 +13,24 @@ struct s2 s1 b; }; +struct s2_1 +{ + s1 b; +}; + struct s1_1 { int a; }; -struct s2_1 -{ - s1_1 b; -}; - struct dstbuffer { - s2_1 test[1]; + s2 test[1]; }; kernel void main0(device dstbuffer& _19 [[buffer(1)]]) { - s2 testVal; + s2_1 testVal; testVal.b.a = 0; _19.test[0].b.a = testVal.b.a; } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/comp/type-alias.comp b/3rdparty/spirv-cross/reference/shaders-msl/comp/type-alias.comp index 25a49f59f..9052bdd14 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/comp/type-alias.comp +++ b/3rdparty/spirv-cross/reference/shaders-msl/comp/type-alias.comp @@ -10,19 +10,14 @@ struct S0 float4 a; }; -struct S1 -{ - float4 a; -}; - struct S0_1 { float4 a; }; -struct SSBO0 +struct S1 { - S0_1 s0s[1]; + float4 a; }; struct S1_1 @@ -30,9 +25,14 @@ struct S1_1 float4 a; }; +struct SSBO0 +{ + S0 s0s[1]; +}; + struct SSBO1 { - S1_1 s1s[1]; + S1 s1s[1]; }; struct SSBO2 @@ -40,24 +40,24 @@ struct SSBO2 float4 outputs[1]; }; -float4 overload(thread const S0& s0) +float4 overload(thread const S0_1& s0) { return s0.a; } -float4 overload(thread const S1& s1) +float4 overload(thread const S1_1& s1) { return s1.a; } kernel void main0(device SSBO0& _36 [[buffer(0)]], device SSBO1& _55 [[buffer(1)]], device SSBO2& _66 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { - S0 s0; + S0_1 s0; s0.a = _36.s0s[gl_GlobalInvocationID.x].a; - S1 s1; + S1_1 s1; s1.a = _55.s1s[gl_GlobalInvocationID.x].a; - S0 param = s0; - S1 param_1 = s1; + S0_1 param = s0; + S1_1 param_1 = s1; _66.outputs[gl_GlobalInvocationID.x] = overload(param) + overload(param_1); } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/frag/constant-array.frag b/3rdparty/spirv-cross/reference/shaders-msl/frag/constant-array.frag index f6989a2a3..c4e87d987 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/frag/constant-array.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl/frag/constant-array.frag @@ -27,19 +27,6 @@ struct main0_in int index [[user(locn0)]]; }; -// Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopyFromStack1(thread T (&dst)[N], thread const T (&src)[N]) -{ - for (uint i = 0; i < N; dst[i] = src[i], i++); -} - -template -void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N]) -{ - for (uint i = 0; i < N; dst[i] = src[i], i++); -} - float4 resolve(thread const Foobar& f) { return float4(f.a + f.b); @@ -49,8 +36,7 @@ fragment main0_out main0(main0_in in [[stage_in]]) { main0_out out = {}; Foobar param = Foobar{ 10.0, 20.0 }; - Foobar indexable[2] = { Foobar{ 10.0, 40.0 }, Foobar{ 90.0, 70.0 } }; - Foobar param_1 = indexable[in.index]; + Foobar param_1 = _75[in.index]; out.FragColor = ((_37[in.index] + _55[in.index][in.index + 1]) + resolve(param)) + resolve(param_1); return out; } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/frag/fragment-component-padding.pad-fragment.frag b/3rdparty/spirv-cross/reference/shaders-msl/frag/fragment-component-padding.pad-fragment.frag new file mode 100644 index 000000000..2d339c473 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-msl/frag/fragment-component-padding.pad-fragment.frag @@ -0,0 +1,42 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 FragColors_0 [[color(0)]]; + float4 FragColors_1 [[color(1)]]; + float4 FragColor2 [[color(2)]]; + float4 FragColor3 [[color(3)]]; +}; + +struct main0_in +{ + float3 vColor [[user(locn0)]]; +}; + +void set_globals(thread float (&FragColors)[2], thread float3& vColor, thread float2& FragColor2, thread float3& FragColor3) +{ + FragColors[0] = vColor.x; + FragColors[1] = vColor.y; + FragColor2 = vColor.xz; + FragColor3 = vColor.zzz; +} + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + float FragColors[2] = {}; + float2 FragColor2 = {}; + float3 FragColor3 = {}; + set_globals(FragColors, in.vColor, FragColor2, FragColor3); + out.FragColors_0 = float4(FragColors[0]); + out.FragColors_1 = float4(FragColors[1]); + out.FragColor2 = FragColor2.xyyy; + out.FragColor3 = FragColor3.xyzz; + return out; +} + diff --git a/3rdparty/spirv-cross/reference/shaders-msl/frag/packing-test-3.frag b/3rdparty/spirv-cross/reference/shaders-msl/frag/packing-test-3.frag index 9c59bc164..a02884e85 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/frag/packing-test-3.frag +++ b/3rdparty/spirv-cross/reference/shaders-msl/frag/packing-test-3.frag @@ -12,19 +12,19 @@ struct VertexOutput struct TestStruct { - float3 position; + packed_float3 position; float radius; }; struct TestStruct_1 { - packed_float3 position; + float3 position; float radius; }; struct CB0 { - TestStruct_1 CB0[16]; + TestStruct CB0[16]; }; struct main0_out @@ -34,7 +34,7 @@ struct main0_out float4 _main(thread const VertexOutput& IN, constant CB0& v_26) { - TestStruct st; + TestStruct_1 st; st.position = v_26.CB0[1].position; st.radius = v_26.CB0[1].radius; float4 col = float4(st.position, st.radius); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays-leaf.ios.vert b/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays-leaf.ios.vert index 731a69efc..bef2acc88 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays-leaf.ios.vert +++ b/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays-leaf.ios.vert @@ -5,11 +5,6 @@ using namespace metal; -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 3 -#endif -constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; - struct storage_block { uint4 baz; @@ -22,6 +17,11 @@ struct constant_block int bar; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 3 +#endif +constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; + void doWork(device storage_block* (&storage)[2], constant constant_block* (&constants)[4], thread const array, 3> images) { storage[0]->baz = uint4(constants[3]->foo); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays.ios.vert b/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays.ios.vert index 22dc480b2..93704af28 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays.ios.vert +++ b/3rdparty/spirv-cross/reference/shaders-msl/vert/resource-arrays.ios.vert @@ -3,11 +3,6 @@ using namespace metal; -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 3 -#endif -constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; - struct storage_block { uint4 baz; @@ -20,6 +15,11 @@ struct constant_block int bar; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 3 +#endif +constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0; + vertex void main0(device storage_block* storage_0 [[buffer(0)]], device storage_block* storage_1 [[buffer(1)]], constant constant_block* constants_0 [[buffer(2)]], constant constant_block* constants_1 [[buffer(3)]], constant constant_block* constants_2 [[buffer(4)]], constant constant_block* constants_3 [[buffer(5)]], array, 3> images [[texture(0)]]) { device storage_block* storage[] = diff --git a/3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/out-of-order-struct-id.asm.frag b/3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/out-of-order-struct-id.asm.frag new file mode 100644 index 000000000..22d72a6e4 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/out-of-order-struct-id.asm.frag @@ -0,0 +1,25 @@ +#version 450 + +struct Foo +{ + vec4 a; +}; + +struct Bar +{ + Foo foo; + Foo foo2; +}; + +layout(binding = 0, std140) uniform UBO +{ + Bar bar; +} _7; + +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = _7.bar.foo.a + _7.bar.foo2.a; +} + diff --git a/3rdparty/spirv-cross/reference/shaders-no-opt/vert/pass-array-by-value.vert b/3rdparty/spirv-cross/reference/shaders-no-opt/vert/pass-array-by-value.vert new file mode 100644 index 000000000..45d421081 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-no-opt/vert/pass-array-by-value.vert @@ -0,0 +1,27 @@ +#version 310 es + +layout(location = 0) in int Index1; +layout(location = 1) in int Index2; + +vec4 consume_constant_arrays2(vec4 positions[4], vec4 positions2[4]) +{ + vec4 indexable[4] = positions; + vec4 indexable_1[4] = positions2; + return indexable[Index1] + indexable_1[Index2]; +} + +vec4 consume_constant_arrays(vec4 positions[4], vec4 positions2[4]) +{ + return consume_constant_arrays2(positions, positions2); +} + +void main() +{ + vec4 LUT2[4]; + LUT2[0] = vec4(10.0); + LUT2[1] = vec4(11.0); + LUT2[2] = vec4(12.0); + LUT2[3] = vec4(13.0); + gl_Position = consume_constant_arrays(vec4[](vec4(0.0), vec4(1.0), vec4(2.0), vec4(3.0)), LUT2); +} + diff --git a/3rdparty/spirv-cross/reference/shaders/asm/frag/op-constant-null.asm.frag b/3rdparty/spirv-cross/reference/shaders/asm/frag/op-constant-null.asm.frag index 970b4c4a6..f293c1802 100644 --- a/3rdparty/spirv-cross/reference/shaders/asm/frag/op-constant-null.asm.frag +++ b/3rdparty/spirv-cross/reference/shaders/asm/frag/op-constant-null.asm.frag @@ -2,14 +2,14 @@ precision mediump float; precision highp int; -const vec4 _14[4] = vec4[](vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); - struct D { vec4 a; float b; }; +const vec4 _14[4] = vec4[](vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); + layout(location = 0) out float FragColor; void main() diff --git a/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert b/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert index 46e998d7f..fdba2a260 100644 --- a/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert +++ b/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert @@ -4,19 +4,19 @@ #define SPIRV_CROSS_CONSTANT_ID_201 -10 #endif const int _7 = SPIRV_CROSS_CONSTANT_ID_201; +const int _20 = (_7 + 2); #ifndef SPIRV_CROSS_CONSTANT_ID_202 #define SPIRV_CROSS_CONSTANT_ID_202 100u #endif const uint _8 = SPIRV_CROSS_CONSTANT_ID_202; -#ifndef SPIRV_CROSS_CONSTANT_ID_200 -#define SPIRV_CROSS_CONSTANT_ID_200 3.141590118408203125 -#endif -const float _9 = SPIRV_CROSS_CONSTANT_ID_200; -const int _20 = (_7 + 2); const uint _25 = (_8 % 5u); const ivec4 _30 = ivec4(20, 30, _20, _20); const ivec2 _32 = ivec2(_30.y, _30.x); const int _33 = _30.y; +#ifndef SPIRV_CROSS_CONSTANT_ID_200 +#define SPIRV_CROSS_CONSTANT_ID_200 3.141590118408203125 +#endif +const float _9 = SPIRV_CROSS_CONSTANT_ID_200; layout(location = 0) flat out int _4; diff --git a/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk b/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk index d308693aa..02c3e3125 100644 --- a/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk +++ b/3rdparty/spirv-cross/reference/shaders/asm/vert/spec-constant-op-composite.asm.vk.vert.vk @@ -1,13 +1,13 @@ #version 450 layout(constant_id = 201) const int _7 = -10; -layout(constant_id = 202) const uint _8 = 100u; -layout(constant_id = 200) const float _9 = 3.141590118408203125; const int _20 = (_7 + 2); +layout(constant_id = 202) const uint _8 = 100u; const uint _25 = (_8 % 5u); const ivec4 _30 = ivec4(20, 30, _20, _20); const ivec2 _32 = ivec2(_30.y, _30.x); const int _33 = _30.y; +layout(constant_id = 200) const float _9 = 3.141590118408203125; layout(location = 0) flat out int _4; diff --git a/3rdparty/spirv-cross/reference/shaders/comp/composite-array-initialization.comp b/3rdparty/spirv-cross/reference/shaders/comp/composite-array-initialization.comp index 1269831f3..847a15200 100644 --- a/3rdparty/spirv-cross/reference/shaders/comp/composite-array-initialization.comp +++ b/3rdparty/spirv-cross/reference/shaders/comp/composite-array-initialization.comp @@ -1,17 +1,17 @@ #version 310 es layout(local_size_x = 2, local_size_y = 1, local_size_z = 1) in; -#ifndef SPIRV_CROSS_CONSTANT_ID_0 -#define SPIRV_CROSS_CONSTANT_ID_0 4.0 -#endif -const float X = SPIRV_CROSS_CONSTANT_ID_0; - struct Data { float a; float b; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_0 +#define SPIRV_CROSS_CONSTANT_ID_0 4.0 +#endif +const float X = SPIRV_CROSS_CONSTANT_ID_0; + layout(binding = 0, std430) buffer SSBO { Data outdata[]; diff --git a/3rdparty/spirv-cross/reference/shaders/comp/composite-construct.comp b/3rdparty/spirv-cross/reference/shaders/comp/composite-construct.comp index 3018be8f1..b39755072 100644 --- a/3rdparty/spirv-cross/reference/shaders/comp/composite-construct.comp +++ b/3rdparty/spirv-cross/reference/shaders/comp/composite-construct.comp @@ -2,7 +2,6 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; const vec4 _66[2] = vec4[](vec4(10.0), vec4(30.0)); -const float _94[2][3] = float[][](float[](1.0, 1.0, 1.0), float[](2.0, 2.0, 2.0)); struct Composite { @@ -10,6 +9,8 @@ struct Composite vec4 b[2]; }; +const float _94[2][3] = float[][](float[](1.0, 1.0, 1.0), float[](2.0, 2.0, 2.0)); + layout(binding = 0, std430) buffer SSBO0 { vec4 as[]; diff --git a/3rdparty/spirv-cross/reference/shaders/frag/constant-array.frag b/3rdparty/spirv-cross/reference/shaders/frag/constant-array.frag index be033f387..fac956039 100644 --- a/3rdparty/spirv-cross/reference/shaders/frag/constant-array.frag +++ b/3rdparty/spirv-cross/reference/shaders/frag/constant-array.frag @@ -2,15 +2,16 @@ precision mediump float; precision highp int; -const vec4 _37[3] = vec4[](vec4(1.0), vec4(2.0), vec4(3.0)); -const vec4 _55[2][2] = vec4[][](vec4[](vec4(1.0), vec4(2.0)), vec4[](vec4(8.0), vec4(10.0))); - struct Foobar { float a; float b; }; +const vec4 _37[3] = vec4[](vec4(1.0), vec4(2.0), vec4(3.0)); +const vec4 _55[2][2] = vec4[][](vec4[](vec4(1.0), vec4(2.0)), vec4[](vec4(8.0), vec4(10.0))); +const Foobar _75[2] = Foobar[](Foobar(10.0, 40.0), Foobar(90.0, 70.0)); + layout(location = 0) out vec4 FragColor; layout(location = 0) flat in mediump int index; @@ -22,8 +23,7 @@ vec4 resolve(Foobar f) void main() { Foobar param = Foobar(10.0, 20.0); - Foobar indexable[2] = Foobar[](Foobar(10.0, 40.0), Foobar(90.0, 70.0)); - Foobar param_1 = indexable[index]; + Foobar param_1 = _75[index]; FragColor = ((_37[index] + _55[index][index + 1]) + resolve(param)) + resolve(param_1); } diff --git a/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp b/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp index 9344a7a24..33647a423 100644 --- a/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp +++ b/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp @@ -9,15 +9,6 @@ const int a = SPIRV_CROSS_CONSTANT_ID_0; #define SPIRV_CROSS_CONSTANT_ID_1 200 #endif const int b = SPIRV_CROSS_CONSTANT_ID_1; -#ifndef SPIRV_CROSS_CONSTANT_ID_2 -#define SPIRV_CROSS_CONSTANT_ID_2 300 -#endif -const int c = SPIRV_CROSS_CONSTANT_ID_2; -const int _18 = (c + 50); -#ifndef SPIRV_CROSS_CONSTANT_ID_3 -#define SPIRV_CROSS_CONSTANT_ID_3 400 -#endif -const int e = SPIRV_CROSS_CONSTANT_ID_3; struct A { @@ -31,6 +22,16 @@ struct B int member1[a]; }; +#ifndef SPIRV_CROSS_CONSTANT_ID_2 +#define SPIRV_CROSS_CONSTANT_ID_2 300 +#endif +const int c = SPIRV_CROSS_CONSTANT_ID_2; +const int _18 = (c + 50); +#ifndef SPIRV_CROSS_CONSTANT_ID_3 +#define SPIRV_CROSS_CONSTANT_ID_3 400 +#endif +const int e = SPIRV_CROSS_CONSTANT_ID_3; + layout(binding = 0, std430) buffer SSBO { A member_a; diff --git a/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk b/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk index d9a2822f7..cd68e93d7 100644 --- a/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk +++ b/3rdparty/spirv-cross/reference/shaders/vulkan/comp/spec-constant-op-member-array.vk.comp.vk @@ -3,9 +3,6 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(constant_id = 0) const int a = 100; layout(constant_id = 1) const int b = 200; -layout(constant_id = 2) const int c = 300; -const int _18 = (c + 50); -layout(constant_id = 3) const int e = 400; struct A { @@ -19,6 +16,10 @@ struct B int member1[a]; }; +layout(constant_id = 2) const int c = 300; +const int _18 = (c + 50); +layout(constant_id = 3) const int e = 400; + layout(set = 1, binding = 0, std430) buffer SSBO { A member_a; diff --git a/3rdparty/spirv-cross/shaders-hlsl-no-opt/vert/pass-array-by-value.vert b/3rdparty/spirv-cross/shaders-hlsl-no-opt/vert/pass-array-by-value.vert new file mode 100644 index 000000000..2c142a781 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-hlsl-no-opt/vert/pass-array-by-value.vert @@ -0,0 +1,26 @@ +#version 310 es + +layout(location = 0) in int Index1; +layout(location = 1) in int Index2; + +vec4 consume_constant_arrays2(const vec4 positions[4], const vec4 positions2[4]) +{ + return positions[Index1] + positions2[Index2]; +} + +vec4 consume_constant_arrays(const vec4 positions[4], const vec4 positions2[4]) +{ + return consume_constant_arrays2(positions, positions2); +} + +const vec4 LUT1[] = vec4[](vec4(0.0), vec4(1.0), vec4(2.0), vec4(3.0)); + +void main() +{ + vec4 LUT2[4]; + LUT2[0] = vec4(10.0); + LUT2[1] = vec4(11.0); + LUT2[2] = vec4(12.0); + LUT2[3] = vec4(13.0); + gl_Position = consume_constant_arrays(LUT1, LUT2); +} diff --git a/3rdparty/spirv-cross/shaders-hlsl/frag/dual-source-blending.frag b/3rdparty/spirv-cross/shaders-hlsl/frag/dual-source-blending.frag new file mode 100644 index 000000000..f322cf4c3 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-hlsl/frag/dual-source-blending.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0, index = 0) out vec4 FragColor0; +layout(location = 0, index = 1) out vec4 FragColor1; + +void main() +{ + FragColor0 = vec4(1.0); + FragColor1 = vec4(2.0); +} diff --git a/3rdparty/spirv-cross/shaders-msl-no-opt/vert/pass-array-by-value.vert b/3rdparty/spirv-cross/shaders-msl-no-opt/vert/pass-array-by-value.vert new file mode 100644 index 000000000..2c142a781 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-msl-no-opt/vert/pass-array-by-value.vert @@ -0,0 +1,26 @@ +#version 310 es + +layout(location = 0) in int Index1; +layout(location = 1) in int Index2; + +vec4 consume_constant_arrays2(const vec4 positions[4], const vec4 positions2[4]) +{ + return positions[Index1] + positions2[Index2]; +} + +vec4 consume_constant_arrays(const vec4 positions[4], const vec4 positions2[4]) +{ + return consume_constant_arrays2(positions, positions2); +} + +const vec4 LUT1[] = vec4[](vec4(0.0), vec4(1.0), vec4(2.0), vec4(3.0)); + +void main() +{ + vec4 LUT2[4]; + LUT2[0] = vec4(10.0); + LUT2[1] = vec4(11.0); + LUT2[2] = vec4(12.0); + LUT2[3] = vec4(13.0); + gl_Position = consume_constant_arrays(LUT1, LUT2); +} diff --git a/3rdparty/spirv-cross/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag b/3rdparty/spirv-cross/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag new file mode 100644 index 000000000..91f086655 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag @@ -0,0 +1,90 @@ +#version 450 + +layout(binding = 0) uniform sampler1D tex1d; +layout(binding = 1) uniform texture2D tex2d; +layout(binding = 2) uniform sampler3D tex3d; +layout(binding = 3) uniform textureCube 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 texture2DArray depth2dArray; +layout(binding = 10) uniform samplerCubeArrayShadow depthCubeArray; + +layout(binding = 11) uniform sampler defaultSampler; +layout(binding = 12) uniform samplerShadow shadowSampler; + +layout(location = 0) out vec4 fragColor; + +vec4 do_samples(sampler1D t1, texture2D t2, sampler3D t3, textureCube tc, sampler2DArray t2a, samplerCubeArray tca, samplerBuffer tb, sampler2DShadow d2, samplerCubeShadow dc, texture2DArray d2a, samplerCubeArrayShadow dca) +{ + // OpImageSampleImplicitLod + vec4 c = texture(t1, 0.0); + c = texture(sampler2D(t2, defaultSampler), vec2(0.0, 0.0)); + c = texture(t3, vec3(0.0, 0.0, 0.0)); + c = texture(samplerCube(tc, defaultSampler), vec3(0.0, 0.0, 0.0)); + c = texture(t2a, vec3(0.0, 0.0, 0.0)); + c = texture(tca, vec4(0.0, 0.0, 0.0, 0.0)); + + // OpImageSampleDrefImplicitLod + c.r = texture(d2, vec3(0.0, 0.0, 1.0)); + c.r = texture(dc, vec4(0.0, 0.0, 0.0, 1.0)); + c.r = texture(sampler2DArrayShadow(d2a, shadowSampler), vec4(0.0, 0.0, 0.0, 1.0)); + c.r = texture(dca, vec4(0.0, 0.0, 0.0, 0.0), 1.0); + + // OpImageSampleProjImplicitLod + c = textureProj(t1, vec2(0.0, 1.0)); + c = textureProj(sampler2D(t2, defaultSampler), vec3(0.0, 0.0, 1.0)); + c = textureProj(t3, vec4(0.0, 0.0, 0.0, 1.0)); + + // OpImageSampleProjDrefImplicitLod + c.r = textureProj(d2, vec4(0.0, 0.0, 1.0, 1.0)); + + // OpImageSampleExplicitLod + c = textureLod(t1, 0.0, 0.0); + c = textureLod(sampler2D(t2, defaultSampler), vec2(0.0, 0.0), 0.0); + c = textureLod(t3, vec3(0.0, 0.0, 0.0), 0.0); + c = textureLod(samplerCube(tc, defaultSampler), vec3(0.0, 0.0, 0.0), 0.0); + c = textureLod(t2a, vec3(0.0, 0.0, 0.0), 0.0); + c = textureLod(tca, vec4(0.0, 0.0, 0.0, 0.0), 0.0); + + // OpImageSampleDrefExplicitLod + c.r = textureLod(d2, vec3(0.0, 0.0, 1.0), 0.0); + + // OpImageSampleProjExplicitLod + c = textureProjLod(t1, vec2(0.0, 1.0), 0.0); + c = textureProjLod(sampler2D(t2, defaultSampler), vec3(0.0, 0.0, 1.0), 0.0); + c = textureProjLod(t3, vec4(0.0, 0.0, 0.0, 1.0), 0.0); + + // OpImageSampleProjDrefExplicitLod + c.r = textureProjLod(d2, vec4(0.0, 0.0, 1.0, 1.0), 0.0); + + // OpImageFetch + c = texelFetch(t1, 0, 0); + c = texelFetch(sampler2D(t2, defaultSampler), ivec2(0, 0), 0); + c = texelFetch(t3, ivec3(0, 0, 0), 0); + c = texelFetch(t2a, ivec3(0, 0, 0), 0); + + // Show that this transformation doesn't apply to Buffer images. + c = texelFetch(tb, 0); + + // OpImageGather + c = textureGather(sampler2D(t2, defaultSampler), vec2(0.0, 0.0), 0); + c = textureGather(samplerCube(tc, defaultSampler), vec3(0.0, 0.0, 0.0), 1); + c = textureGather(t2a, vec3(0.0, 0.0, 0.0), 2); + c = textureGather(tca, vec4(0.0, 0.0, 0.0, 0.0), 3); + + // OpImageDrefGather + c = textureGather(d2, vec2(0.0, 0.0), 1.0); + c = textureGather(dc, vec3(0.0, 0.0, 0.0), 1.0); + c = textureGather(sampler2DArrayShadow(d2a, shadowSampler), vec3(0.0, 0.0, 0.0), 1.0); + c = textureGather(dca, vec4(0.0, 0.0, 0.0, 0.0), 1.0); + return c; +} + +void main() +{ + fragColor = do_samples(tex1d, tex2d, tex3d, texCube, tex2dArray, texCubeArray, texBuffer, depth2d, depthCube, depth2dArray, depthCubeArray); +} diff --git a/3rdparty/spirv-cross/shaders-msl/frag/fragment-component-padding.pad-fragment.frag b/3rdparty/spirv-cross/shaders-msl/frag/fragment-component-padding.pad-fragment.frag new file mode 100644 index 000000000..240c59b9b --- /dev/null +++ b/3rdparty/spirv-cross/shaders-msl/frag/fragment-component-padding.pad-fragment.frag @@ -0,0 +1,18 @@ +#version 450 +layout(location = 0) out float FragColors[2]; +layout(location = 2) out vec2 FragColor2; +layout(location = 3) out vec3 FragColor3; +layout(location = 0) in vec3 vColor; + +void set_globals() +{ + FragColors[0] = vColor.x; + FragColors[1] = vColor.y; + FragColor2 = vColor.xz; + FragColor3 = vColor.zzz; +} + +void main() +{ + set_globals(); +} diff --git a/3rdparty/spirv-cross/shaders-no-opt/asm/frag/out-of-order-struct-id.asm.frag b/3rdparty/spirv-cross/shaders-no-opt/asm/frag/out-of-order-struct-id.asm.frag new file mode 100644 index 000000000..4a7885e5d --- /dev/null +++ b/3rdparty/spirv-cross/shaders-no-opt/asm/frag/out-of-order-struct-id.asm.frag @@ -0,0 +1,54 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 24 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %FragColor + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %FragColor "FragColor" + OpName %80 "Foo" + OpMemberName %80 0 "a" + OpName %79 "Bar" + OpMemberName %79 0 "foo" + OpMemberName %79 1 "foo2" + OpName %UBO "UBO" + OpMemberName %UBO 0 "bar" + OpName %_ "" + OpDecorate %FragColor Location 0 + OpMemberDecorate %80 0 Offset 0 + OpMemberDecorate %79 0 Offset 0 + OpMemberDecorate %79 1 Offset 16 + OpMemberDecorate %UBO 0 Offset 0 + OpDecorate %UBO Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %FragColor = OpVariable %_ptr_Output_v4float Output + %80 = OpTypeStruct %v4float + %79 = OpTypeStruct %80 %80 + %UBO = OpTypeStruct %79 +%_ptr_Uniform_UBO = OpTypePointer Uniform %UBO + %_ = OpVariable %_ptr_Uniform_UBO Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float + %int_1 = OpConstant %int 1 + %main = OpFunction %void None %3 + %5 = OpLabel + %18 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %int_0 %int_0 + %19 = OpLoad %v4float %18 + %21 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %int_1 %int_0 + %22 = OpLoad %v4float %21 + %23 = OpFAdd %v4float %19 %22 + OpStore %FragColor %23 + OpReturn + OpFunctionEnd diff --git a/3rdparty/spirv-cross/shaders-no-opt/vert/pass-array-by-value.vert b/3rdparty/spirv-cross/shaders-no-opt/vert/pass-array-by-value.vert new file mode 100644 index 000000000..2c142a781 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-no-opt/vert/pass-array-by-value.vert @@ -0,0 +1,26 @@ +#version 310 es + +layout(location = 0) in int Index1; +layout(location = 1) in int Index2; + +vec4 consume_constant_arrays2(const vec4 positions[4], const vec4 positions2[4]) +{ + return positions[Index1] + positions2[Index2]; +} + +vec4 consume_constant_arrays(const vec4 positions[4], const vec4 positions2[4]) +{ + return consume_constant_arrays2(positions, positions2); +} + +const vec4 LUT1[] = vec4[](vec4(0.0), vec4(1.0), vec4(2.0), vec4(3.0)); + +void main() +{ + vec4 LUT2[4]; + LUT2[0] = vec4(10.0); + LUT2[1] = vec4(11.0); + LUT2[2] = vec4(12.0); + LUT2[3] = vec4(13.0); + gl_Position = consume_constant_arrays(LUT1, LUT2); +} diff --git a/3rdparty/spirv-cross/spirv_cfg.cpp b/3rdparty/spirv-cross/spirv_cfg.cpp index 27792e01b..4ca9ef568 100644 --- a/3rdparty/spirv-cross/spirv_cfg.cpp +++ b/3rdparty/spirv-cross/spirv_cfg.cpp @@ -27,11 +27,6 @@ CFG::CFG(Compiler &compiler_, const SPIRFunction &func_) : compiler(compiler_) , func(func_) { - preceding_edges.resize(compiler.get_current_id_bound()); - succeeding_edges.resize(compiler.get_current_id_bound()); - visit_order.resize(compiler.get_current_id_bound()); - immediate_dominators.resize(compiler.get_current_id_bound()); - build_post_order_visit_order(); build_immediate_dominators(); } @@ -40,10 +35,10 @@ uint32_t CFG::find_common_dominator(uint32_t a, uint32_t b) const { while (a != b) { - if (visit_order[a] < visit_order[b]) - a = immediate_dominators[a]; + if (get_visit_order(a) < get_visit_order(b)) + a = get_immediate_dominator(a); else - b = immediate_dominators[b]; + b = get_immediate_dominator(b); } return a; } @@ -51,7 +46,7 @@ uint32_t CFG::find_common_dominator(uint32_t a, uint32_t b) const void CFG::build_immediate_dominators() { // Traverse the post-order in reverse and build up the immediate dominator tree. - fill(begin(immediate_dominators), end(immediate_dominators), 0); + immediate_dominators.clear(); immediate_dominators[func.entry_block] = func.entry_block; for (auto i = post_order.size(); i; i--) @@ -78,7 +73,9 @@ bool CFG::is_back_edge(uint32_t to) const { // We have a back edge if the visit order is set with the temporary magic value 0. // Crossing edges will have already been recorded with a visit order. - return visit_order[to] == 0; + auto itr = visit_order.find(to); + assert(itr != end(visit_order)); + return itr->second.get() == 0; } bool CFG::post_order_visit(uint32_t block_id) @@ -86,11 +83,11 @@ bool CFG::post_order_visit(uint32_t block_id) // If we have already branched to this block (back edge), stop recursion. // If our branches are back-edges, we do not record them. // We have to record crossing edges however. - if (visit_order[block_id] >= 0) + if (visit_order[block_id].get() >= 0) return !is_back_edge(block_id); // Block back-edges from recursively revisiting ourselves. - visit_order[block_id] = 0; + visit_order[block_id].get() = 0; // First visit our branch targets. auto &block = compiler.get(block_id); @@ -130,7 +127,7 @@ bool CFG::post_order_visit(uint32_t block_id) add_branch(block_id, block.merge_block); // Then visit ourselves. Start counting at one, to let 0 be a magic value for testing back vs. crossing edges. - visit_order[block_id] = ++visit_count; + visit_order[block_id].get() = ++visit_count; post_order.push_back(block_id); return true; } @@ -139,7 +136,7 @@ void CFG::build_post_order_visit_order() { uint32_t block = func.entry_block; visit_count = 0; - fill(begin(visit_order), end(visit_order), -1); + visit_order.clear(); post_order.clear(); post_order_visit(block); } diff --git a/3rdparty/spirv-cross/spirv_cfg.hpp b/3rdparty/spirv-cross/spirv_cfg.hpp index d14cb2e47..5e8932041 100644 --- a/3rdparty/spirv-cross/spirv_cfg.hpp +++ b/3rdparty/spirv-cross/spirv_cfg.hpp @@ -45,12 +45,18 @@ public: uint32_t get_immediate_dominator(uint32_t block) const { - return immediate_dominators[block]; + auto itr = immediate_dominators.find(block); + if (itr != std::end(immediate_dominators)) + return itr->second; + else + return 0; } uint32_t get_visit_order(uint32_t block) const { - int v = visit_order[block]; + auto itr = visit_order.find(block); + assert(itr != std::end(visit_order)); + int v = itr->second.get(); assert(v > 0); return uint32_t(v); } @@ -59,12 +65,20 @@ public: const std::vector &get_preceding_edges(uint32_t block) const { - return preceding_edges[block]; + auto itr = preceding_edges.find(block); + if (itr != std::end(preceding_edges)) + return itr->second; + else + return empty_vector; } const std::vector &get_succeeding_edges(uint32_t block) const { - return succeeding_edges[block]; + auto itr = succeeding_edges.find(block); + if (itr != std::end(succeeding_edges)) + return itr->second; + else + return empty_vector; } template @@ -75,18 +89,34 @@ public: seen_blocks.insert(block); op(block); - for (auto b : succeeding_edges[block]) + for (auto b : get_succeeding_edges(block)) walk_from(seen_blocks, b, op); } private: + struct VisitOrder + { + int &get() + { + return v; + } + + const int &get() const + { + return v; + } + + int v = -1; + }; + Compiler &compiler; const SPIRFunction &func; - std::vector> preceding_edges; - std::vector> succeeding_edges; - std::vector immediate_dominators; - std::vector visit_order; + std::unordered_map> preceding_edges; + std::unordered_map> succeeding_edges; + std::unordered_map immediate_dominators; + std::unordered_map visit_order; std::vector post_order; + std::vector empty_vector; void add_branch(uint32_t from, uint32_t to); void build_post_order_visit_order(); diff --git a/3rdparty/spirv-cross/spirv_common.hpp b/3rdparty/spirv-cross/spirv_common.hpp index a62a1f870..57820d052 100644 --- a/3rdparty/spirv-cross/spirv_common.hpp +++ b/3rdparty/spirv-cross/spirv_common.hpp @@ -322,14 +322,14 @@ enum Types TypeConstant, TypeFunction, TypeFunctionPrototype, - TypePointer, TypeBlock, TypeExtension, TypeExpression, TypeConstantOp, TypeCombinedImageSampler, TypeAccessChain, - TypeUndef + TypeUndef, + TypeCount }; struct SPIRUndef : IVariant @@ -812,6 +812,11 @@ struct SPIRFunction : IVariant // Need to defer this, because they might rely on things which change during compilation. std::vector> fixup_hooks_in; + // On function entry, make sure to copy a constant array into thread addr space to work around + // the case where we are passing a constant array by value to a function on backends which do not + // consider arrays value types. + std::vector constant_arrays_needed_on_stack; + bool active = false; bool flush_undeclared = true; bool do_combined_parameters = true; @@ -1250,7 +1255,7 @@ public: return *this; } - void set(std::unique_ptr val, uint32_t new_type) + void set(std::unique_ptr val, Types new_type) { holder = std::move(val); if (!allow_type_rewrite && type != TypeNone && type != new_type) @@ -1264,7 +1269,7 @@ public: { if (!holder) SPIRV_CROSS_THROW("nullptr"); - if (T::type != type) + if (static_cast(T::type) != type) SPIRV_CROSS_THROW("Bad cast"); return *static_cast(holder.get()); } @@ -1274,12 +1279,12 @@ public: { if (!holder) SPIRV_CROSS_THROW("nullptr"); - if (T::type != type) + if (static_cast(T::type) != type) SPIRV_CROSS_THROW("Bad cast"); return *static_cast(holder.get()); } - uint32_t get_type() const + Types get_type() const { return type; } @@ -1307,7 +1312,7 @@ public: private: std::unique_ptr holder; - uint32_t type = TypeNone; + Types type = TypeNone; bool allow_type_rewrite = false; }; @@ -1328,7 +1333,7 @@ T &variant_set(Variant &var, P &&... args) { auto uptr = std::unique_ptr(new T(std::forward

(args)...)); auto ptr = uptr.get(); - var.set(std::move(uptr), T::type); + var.set(std::move(uptr), static_cast(T::type)); return *ptr; } diff --git a/3rdparty/spirv-cross/spirv_cross.cpp b/3rdparty/spirv-cross/spirv_cross.cpp index fc54f09db..ecddc056e 100644 --- a/3rdparty/spirv-cross/spirv_cross.cpp +++ b/3rdparty/spirv-cross/spirv_cross.cpp @@ -158,7 +158,7 @@ bool Compiler::block_is_pure(const SPIRBlock &block) string Compiler::to_name(uint32_t id, bool allow_alias) const { - if (allow_alias && ir.ids.at(id).get_type() == TypeType) + if (allow_alias && ir.ids[id].get_type() == TypeType) { // If this type is a simple alias, emit the // name of the original type instead. @@ -174,10 +174,11 @@ string Compiler::to_name(uint32_t id, bool allow_alias) const } } - if (ir.meta[id].decoration.alias.empty()) + auto &alias = ir.get_name(id); + if (alias.empty()) return join("_", id); else - return ir.meta[id].decoration.alias; + return alias; } bool Compiler::function_is_pure(const SPIRFunction &func) @@ -473,17 +474,22 @@ bool Compiler::is_hidden_variable(const SPIRVariable &var, bool include_builtins bool Compiler::is_builtin_type(const SPIRType &type) const { + auto *type_meta = ir.find_meta(type.self); + // We can have builtin structs as well. If one member of a struct is builtin, the struct must also be builtin. - for (auto &m : ir.meta[type.self].members) - if (m.builtin) - return true; + if (type_meta) + for (auto &m : type_meta->members) + if (m.builtin) + return true; return false; } bool Compiler::is_builtin_variable(const SPIRVariable &var) const { - if (var.compat_builtin || ir.meta[var.self].decoration.builtin) + auto *m = ir.find_meta(var.self); + + if (var.compat_builtin || (m && m->decoration.builtin)) return true; else return is_builtin_type(get(var.basetype)); @@ -491,12 +497,17 @@ bool Compiler::is_builtin_variable(const SPIRVariable &var) const bool Compiler::is_member_builtin(const SPIRType &type, uint32_t index, BuiltIn *builtin) const { - auto &memb = ir.meta[type.self].members; - if (index < memb.size() && memb[index].builtin) + auto *type_meta = ir.find_meta(type.self); + + if (type_meta) { - if (builtin) - *builtin = memb[index].builtin_type; - return true; + auto &memb = type_meta->members; + if (index < memb.size() && memb[index].builtin) + { + if (builtin) + *builtin = memb[index].builtin_type; + return true; + } } return false; @@ -707,55 +718,52 @@ ShaderResources Compiler::get_shader_resources(const unordered_set *ac { ShaderResources res; - for (auto &id : ir.ids) - { - if (id.get_type() != TypeVariable) - continue; - - auto &var = id.get(); - auto &type = get(var.basetype); + ir.for_each_typed_id([&](uint32_t, const SPIRVariable &var) { + auto &type = this->get(var.basetype); // It is possible for uniform storage classes to be passed as function parameters, so detect // that. To detect function parameters, check of StorageClass of variable is function scope. if (var.storage == StorageClassFunction || !type.pointer || is_builtin_variable(var)) - continue; + return; if (active_variables && active_variables->find(var.self) == end(*active_variables)) - continue; + return; // Input if (var.storage == StorageClassInput && interface_variable_exists_in_entry_point(var.self)) { - if (ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock)) + if (has_decoration(type.self, DecorationBlock)) + { res.stage_inputs.push_back( { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) }); + } else - res.stage_inputs.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.stage_inputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Subpass inputs else if (var.storage == StorageClassUniformConstant && type.image.dim == DimSubpassData) { - res.subpass_inputs.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.subpass_inputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Outputs else if (var.storage == StorageClassOutput && interface_variable_exists_in_entry_point(var.self)) { - if (ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock)) + if (has_decoration(type.self, DecorationBlock)) + { res.stage_outputs.push_back( { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) }); + } else - res.stage_outputs.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.stage_outputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // UBOs - else if (type.storage == StorageClassUniform && - (ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock))) + else if (type.storage == StorageClassUniform && has_decoration(type.self, DecorationBlock)) { res.uniform_buffers.push_back( { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) }); } // Old way to declare SSBOs. - else if (type.storage == StorageClassUniform && - (ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock))) + else if (type.storage == StorageClassUniform && has_decoration(type.self, DecorationBufferBlock)) { res.storage_buffers.push_back( { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) }); @@ -771,37 +779,36 @@ ShaderResources Compiler::get_shader_resources(const unordered_set *ac { // There can only be one push constant block, but keep the vector in case this restriction is lifted // in the future. - res.push_constant_buffers.push_back( - { var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.push_constant_buffers.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Images else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image && type.image.sampled == 2) { - res.storage_images.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.storage_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Separate images else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image && type.image.sampled == 1) { - res.separate_images.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.separate_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Separate samplers else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Sampler) { - res.separate_samplers.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.separate_samplers.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Textures else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::SampledImage) { - res.sampled_images.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.sampled_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } // Atomic counters else if (type.storage == StorageClassAtomicCounter) { - res.atomic_counters.push_back({ var.self, var.basetype, type.self, ir.meta[var.self].decoration.alias }); + res.atomic_counters.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } - } + }); return res; } @@ -829,52 +836,67 @@ void Compiler::fixup_type_alias() // Due to how some backends work, the "master" type of type_alias must be a block-like type if it exists. // FIXME: Multiple alias types which are both block-like will be awkward, for now, it's best to just drop the type // alias if the slave type is a block type. - for (auto &id : ir.ids) - { - if (id.get_type() != TypeType) - continue; - - auto &type = id.get(); - + ir.for_each_typed_id([&](uint32_t self, SPIRType &type) { if (type.type_alias && type_is_block_like(type)) { // Become the master. - for (auto &other_id : ir.ids) - { - if (other_id.get_type() != TypeType) - continue; - if (other_id.get_id() == type.self) - continue; + ir.for_each_typed_id([&](uint32_t other_id, SPIRType &other_type) { + if (other_id == type.self) + return; - auto &other_type = other_id.get(); if (other_type.type_alias == type.type_alias) other_type.type_alias = type.self; - } + }); - get(type.type_alias).type_alias = id.get_id(); + this->get(type.type_alias).type_alias = self; type.type_alias = 0; } - } + }); - for (auto &id : ir.ids) - { - if (id.get_type() != TypeType) - continue; - - auto &type = id.get(); + ir.for_each_typed_id([&](uint32_t, SPIRType &type) { if (type.type_alias && type_is_block_like(type)) { // This is not allowed, drop the type_alias. type.type_alias = 0; } + }); + + // Reorder declaration of types so that the master of the type alias is always emitted first. + // We need this in case a type B depends on type A (A must come before in the vector), but A is an alias of a type Abuffer, which + // means declaration of A doesn't happen (yet), and order would be B, ABuffer and not ABuffer, B. Fix this up here. + auto &type_ids = ir.ids_for_type[TypeType]; + for (auto alias_itr = begin(type_ids); alias_itr != end(type_ids); ++alias_itr) + { + auto &type = get(*alias_itr); + if (type.type_alias != 0 && !has_decoration(type.type_alias, DecorationCPacked)) + { + // We will skip declaring this type, so make sure the type_alias type comes before. + auto master_itr = find(begin(type_ids), end(type_ids), type.type_alias); + assert(master_itr != end(type_ids)); + + if (alias_itr < master_itr) + { + // Must also swap the type order for the constant-type joined array. + auto &joined_types = ir.ids_for_constant_or_type; + auto alt_alias_itr = find(begin(joined_types), end(joined_types), *alias_itr); + auto alt_master_itr = find(begin(joined_types), end(joined_types), *master_itr); + assert(alt_alias_itr != end(joined_types)); + assert(alt_master_itr != end(joined_types)); + + swap(*alias_itr, *master_itr); + swap(*alt_alias_itr, *alt_master_itr); + } + } } } void Compiler::parse_fixup() { // Figure out specialization constants for work group sizes. - for (auto &id : ir.ids) + for (auto id_ : ir.ids_for_constant_or_variable) { + auto &id = ir.ids[id_]; + if (id.get_type() == TypeConstant) { auto &c = id.get(); @@ -909,7 +931,7 @@ void Compiler::flatten_interface_block(uint32_t id) { auto &var = get(id); auto &type = get(var.basetype); - auto &flags = ir.meta.at(type.self).decoration.decoration_flags; + auto &flags = ir.meta[type.self].decoration.decoration_flags; if (!type.array.empty()) SPIRV_CROSS_THROW("Type is array of UBOs."); @@ -932,7 +954,7 @@ void Compiler::flatten_interface_block(uint32_t id) SPIRV_CROSS_THROW("Member type cannot be struct."); // Inherit variable name from interface block name. - ir.meta.at(var.self).decoration.alias = ir.meta.at(type.self).decoration.alias; + ir.meta[var.self].decoration.alias = ir.meta[type.self].decoration.alias; auto storage = var.storage; if (storage == StorageClassUniform) @@ -1095,19 +1117,17 @@ const std::string &Compiler::get_member_name(uint32_t id, uint32_t index) const void Compiler::set_member_qualified_name(uint32_t type_id, uint32_t index, const std::string &name) { - ir.meta.at(type_id).members.resize(max(ir.meta[type_id].members.size(), size_t(index) + 1)); - ir.meta.at(type_id).members[index].qualified_alias = name; + ir.meta[type_id].members.resize(max(ir.meta[type_id].members.size(), size_t(index) + 1)); + ir.meta[type_id].members[index].qualified_alias = name; } -const std::string &Compiler::get_member_qualified_name(uint32_t type_id, uint32_t index) const +const string &Compiler::get_member_qualified_name(uint32_t type_id, uint32_t index) const { - const static string empty; - - auto &m = ir.meta.at(type_id); - if (index < m.members.size()) - return m.members[index].qualified_alias; + auto *m = ir.find_meta(type_id); + if (m && index < m->members.size()) + return m->members[index].qualified_alias; else - return empty; + return ir.get_empty_string(); } uint32_t Compiler::get_member_decoration(uint32_t id, uint32_t index, Decoration decoration) const @@ -1152,7 +1172,7 @@ StorageClass Compiler::get_storage_class(uint32_t id) const const std::string &Compiler::get_name(uint32_t id) const { - return ir.meta.at(id).decoration.alias; + return ir.get_name(id); } const std::string Compiler::get_fallback_name(uint32_t id) const @@ -1206,7 +1226,11 @@ void Compiler::unset_decoration(uint32_t id, Decoration decoration) bool Compiler::get_binary_offset_for_decoration(uint32_t id, spv::Decoration decoration, uint32_t &word_offset) const { - auto &word_offsets = ir.meta.at(id).decoration_word_offset; + auto *m = ir.find_meta(id); + if (!m) + return false; + + auto &word_offsets = m->decoration_word_offset; auto itr = word_offsets.find(decoration); if (itr == end(word_offsets)) return false; @@ -1435,32 +1459,50 @@ bool Compiler::traverse_all_reachable_opcodes(const SPIRFunction &func, OpcodeHa uint32_t Compiler::type_struct_member_offset(const SPIRType &type, uint32_t index) const { - // Decoration must be set in valid SPIR-V, otherwise throw. - auto &dec = ir.meta[type.self].members.at(index); - if (dec.decoration_flags.get(DecorationOffset)) - return dec.offset; + auto *type_meta = ir.find_meta(type.self); + if (type_meta) + { + // Decoration must be set in valid SPIR-V, otherwise throw. + auto &dec = type_meta->members[index]; + if (dec.decoration_flags.get(DecorationOffset)) + return dec.offset; + else + SPIRV_CROSS_THROW("Struct member does not have Offset set."); + } else SPIRV_CROSS_THROW("Struct member does not have Offset set."); } uint32_t Compiler::type_struct_member_array_stride(const SPIRType &type, uint32_t index) const { - // Decoration must be set in valid SPIR-V, otherwise throw. - // ArrayStride is part of the array type not OpMemberDecorate. - auto &dec = ir.meta[type.member_types[index]].decoration; - if (dec.decoration_flags.get(DecorationArrayStride)) - return dec.array_stride; + auto *type_meta = ir.find_meta(type.member_types[index]); + if (type_meta) + { + // Decoration must be set in valid SPIR-V, otherwise throw. + // ArrayStride is part of the array type not OpMemberDecorate. + auto &dec = type_meta->decoration; + if (dec.decoration_flags.get(DecorationArrayStride)) + return dec.array_stride; + else + SPIRV_CROSS_THROW("Struct member does not have ArrayStride set."); + } else - SPIRV_CROSS_THROW("Struct member does not have ArrayStride set."); + SPIRV_CROSS_THROW("Struct member does not have Offset set."); } uint32_t Compiler::type_struct_member_matrix_stride(const SPIRType &type, uint32_t index) const { - // Decoration must be set in valid SPIR-V, otherwise throw. - // MatrixStride is part of OpMemberDecorate. - auto &dec = ir.meta[type.self].members[index]; - if (dec.decoration_flags.get(DecorationMatrixStride)) - return dec.matrix_stride; + auto *type_meta = ir.find_meta(type.self); + if (type_meta) + { + // Decoration must be set in valid SPIR-V, otherwise throw. + // MatrixStride is part of OpMemberDecorate. + auto &dec = type_meta->members[index]; + if (dec.decoration_flags.get(DecorationMatrixStride)) + return dec.matrix_stride; + else + SPIRV_CROSS_THROW("Struct member does not have MatrixStride set."); + } else SPIRV_CROSS_THROW("Struct member does not have MatrixStride set."); } @@ -1557,7 +1599,7 @@ bool Compiler::BufferAccessHandler::handle(Op opcode, const uint32_t *args, uint bool ptr_chain = (opcode == OpPtrAccessChain); // Invalid SPIR-V. - if (length < (ptr_chain ? 5 : 4)) + if (length < (ptr_chain ? 5u : 4u)) return false; if (args[2] != id) @@ -2433,16 +2475,11 @@ uint32_t Compiler::build_dummy_sampler_for_combined_images() void Compiler::build_combined_image_samplers() { - for (auto &id : ir.ids) - { - if (id.get_type() == TypeFunction) - { - auto &func = id.get(); - func.combined_parameters.clear(); - func.shadow_arguments.clear(); - func.do_combined_parameters = true; - } - } + ir.for_each_typed_id([&](uint32_t, SPIRFunction &func) { + func.combined_parameters.clear(); + func.shadow_arguments.clear(); + func.do_combined_parameters = true; + }); combined_image_samplers.clear(); CombinedImageSamplerHandler handler(*this); @@ -2452,15 +2489,10 @@ void Compiler::build_combined_image_samplers() vector Compiler::get_specialization_constants() const { vector spec_consts; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeConstant) - { - auto &c = id.get(); - if (c.specialization && has_decoration(c.self, DecorationSpecId)) - spec_consts.push_back({ c.self, get_decoration(c.self, DecorationSpecId) }); - } - } + ir.for_each_typed_id([&](uint32_t, const SPIRConstant &c) { + if (c.specialization && has_decoration(c.self, DecorationSpecId)) + spec_consts.push_back({ c.self, get_decoration(c.self, DecorationSpecId) }); + }); return spec_consts; } @@ -2892,12 +2924,6 @@ void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariab if (type.array.empty()) continue; - // HACK: Do not consider structs. This is a quirk with how types are currently being emitted. - // Structs are emitted after specialization constants and composite constants. - // FIXME: Fix declaration order so declared constants can have struct types. - if (type.basetype == SPIRType::Struct) - continue; - // If the variable has an initializer, make sure it is a constant expression. uint32_t static_constant_expression = 0; if (var.initializer) @@ -3616,15 +3642,18 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_ bool Compiler::buffer_is_hlsl_counter_buffer(uint32_t id) const { - return ir.meta.at(id).hlsl_is_magic_counter_buffer; + auto *m = ir.find_meta(id); + return m && m->hlsl_is_magic_counter_buffer; } bool Compiler::buffer_get_hlsl_counter_buffer(uint32_t id, uint32_t &counter_id) const { + auto *m = ir.find_meta(id); + // First, check for the proper decoration. - if (ir.meta[id].hlsl_magic_counter_buffer != 0) + if (m && m->hlsl_magic_counter_buffer != 0) { - counter_id = ir.meta[id].hlsl_magic_counter_buffer; + counter_id = m->hlsl_magic_counter_buffer; return true; } else @@ -3691,8 +3720,10 @@ std::string Compiler::get_remapped_declared_block_name(uint32_t id) const { auto &var = get(id); auto &type = get(var.basetype); - auto &block_name = ir.meta[type.self].decoration.alias; - return block_name.empty() ? get_block_fallback_name(id) : block_name; + + auto *type_meta = ir.find_meta(type.self); + auto *block_name = type_meta ? &type_meta->decoration.alias : nullptr; + return (!block_name || block_name->empty()) ? get_block_fallback_name(id) : *block_name; } } @@ -3739,15 +3770,20 @@ bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &resul Bitset Compiler::combined_decoration_for_member(const SPIRType &type, uint32_t index) const { Bitset flags; - auto &memb = ir.meta[type.self].members; - if (index >= memb.size()) - return flags; - auto &dec = memb[index]; + auto *type_meta = ir.find_meta(type.self); - // If our type is a struct, traverse all the members as well recursively. - flags.merge_or(dec.decoration_flags); - for (uint32_t i = 0; i < type.member_types.size(); i++) - flags.merge_or(combined_decoration_for_member(get(type.member_types[i]), i)); + if (type_meta) + { + auto &memb = type_meta->members; + if (index >= memb.size()) + return flags; + auto &dec = memb[index]; + + // If our type is a struct, traverse all the members as well recursively. + flags.merge_or(dec.decoration_flags); + for (uint32_t i = 0; i < type.member_types.size(); i++) + flags.merge_or(combined_decoration_for_member(get(type.member_types[i]), i)); + } return flags; } diff --git a/3rdparty/spirv-cross/spirv_cross.hpp b/3rdparty/spirv-cross/spirv_cross.hpp index 8441b82b9..82e2e3331 100644 --- a/3rdparty/spirv-cross/spirv_cross.hpp +++ b/3rdparty/spirv-cross/spirv_cross.hpp @@ -561,7 +561,8 @@ protected: template T &set(uint32_t id, P &&... args) { - auto &var = variant_set(ir.ids.at(id), std::forward

(args)...); + ir.add_typed_id(static_cast(T::type), id); + auto &var = variant_set(ir.ids[id], std::forward

(args)...); var.self = id; return var; } @@ -569,13 +570,13 @@ protected: template T &get(uint32_t id) { - return variant_get(ir.ids.at(id)); + return variant_get(ir.ids[id]); } template T *maybe_get(uint32_t id) { - if (ir.ids.at(id).get_type() == T::type) + if (ir.ids[id].get_type() == static_cast(T::type)) return &get(id); else return nullptr; @@ -584,13 +585,13 @@ protected: template const T &get(uint32_t id) const { - return variant_get(ir.ids.at(id)); + return variant_get(ir.ids[id]); } template const T *maybe_get(uint32_t id) const { - if (ir.ids.at(id).get_type() == T::type) + if (ir.ids[id].get_type() == static_cast(T::type)) return &get(id); else return nullptr; diff --git a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp index a18042333..f17c2bec6 100644 --- a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp +++ b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp @@ -15,6 +15,7 @@ */ #include "spirv_cross_parsed_ir.hpp" +#include #include using namespace std; @@ -25,7 +26,6 @@ namespace spirv_cross void ParsedIR::set_id_bounds(uint32_t bounds) { ids.resize(bounds); - meta.resize(bounds); block_meta.resize(bounds); } @@ -65,19 +65,24 @@ static string ensure_valid_identifier(const string &name, bool member) const string &ParsedIR::get_name(uint32_t id) const { - return meta[id].decoration.alias; + auto *m = find_meta(id); + if (m) + return m->decoration.alias; + else + return empty_string; } const string &ParsedIR::get_member_name(uint32_t id, uint32_t index) const { - auto &m = meta[id]; - if (index >= m.members.size()) + auto *m = find_meta(id); + if (m) { - static string empty; - return empty; + if (index >= m->members.size()) + return empty_string; + return m->members[index].alias; } - - return m.members[index].alias; + else + return empty_string; } void ParsedIR::set_name(uint32_t id, const string &name) @@ -273,7 +278,10 @@ Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const // Some flags like non-writable, non-readable are actually found // as member decorations. If all members have a decoration set, propagate // the decoration up as a regular variable decoration. - Bitset base_flags = meta[var.self].decoration.decoration_flags; + Bitset base_flags; + auto *m = find_meta(var.self); + if (m) + base_flags = m->decoration.decoration_flags; if (type.member_types.empty()) return base_flags; @@ -288,14 +296,15 @@ Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const const Bitset &ParsedIR::get_member_decoration_bitset(uint32_t id, uint32_t index) const { - auto &m = meta[id]; - if (index >= m.members.size()) + auto *m = find_meta(id); + if (m) { - static const Bitset cleared = {}; - return cleared; + if (index >= m->members.size()) + return cleared_bitset; + return m->members[index].decoration_flags; } - - return m.members[index].decoration_flags; + else + return cleared_bitset; } bool ParsedIR::has_decoration(uint32_t id, Decoration decoration) const @@ -305,7 +314,11 @@ bool ParsedIR::has_decoration(uint32_t id, Decoration decoration) const uint32_t ParsedIR::get_decoration(uint32_t id, Decoration decoration) const { - auto &dec = meta[id].decoration; + auto *m = find_meta(id); + if (!m) + return 0; + + auto &dec = m->decoration; if (!dec.decoration_flags.get(decoration)) return 0; @@ -342,11 +355,14 @@ uint32_t ParsedIR::get_decoration(uint32_t id, Decoration decoration) const const string &ParsedIR::get_decoration_string(uint32_t id, Decoration decoration) const { - auto &dec = meta[id].decoration; - static const string empty; + auto *m = find_meta(id); + if (!m) + return empty_string; + + auto &dec = m->decoration; if (!dec.decoration_flags.get(decoration)) - return empty; + return empty_string; switch (decoration) { @@ -354,7 +370,7 @@ const string &ParsedIR::get_decoration_string(uint32_t id, Decoration decoration return dec.hlsl_semantic; default: - return empty; + return empty_string; } } @@ -427,11 +443,14 @@ bool ParsedIR::has_member_decoration(uint32_t id, uint32_t index, Decoration dec uint32_t ParsedIR::get_member_decoration(uint32_t id, uint32_t index, Decoration decoration) const { - auto &m = meta[id]; - if (index >= m.members.size()) + auto *m = find_meta(id); + if (!m) return 0; - auto &dec = m.members[index]; + if (index >= m->members.size()) + return 0; + + auto &dec = m->members[index]; if (!dec.decoration_flags.get(decoration)) return 0; @@ -458,8 +477,14 @@ uint32_t ParsedIR::get_member_decoration(uint32_t id, uint32_t index, Decoration const Bitset &ParsedIR::get_decoration_bitset(uint32_t id) const { - auto &dec = meta[id].decoration; - return dec.decoration_flags; + auto *m = find_meta(id); + if (m) + { + auto &dec = m->decoration; + return dec.decoration_flags; + } + else + return cleared_bitset; } void ParsedIR::set_member_decoration_string(uint32_t id, uint32_t index, Decoration decoration, const string &argument) @@ -481,22 +506,25 @@ void ParsedIR::set_member_decoration_string(uint32_t id, uint32_t index, Decorat const string &ParsedIR::get_member_decoration_string(uint32_t id, uint32_t index, Decoration decoration) const { - static const string empty; - auto &m = meta[id]; - - if (!has_member_decoration(id, index, decoration)) - return empty; - - auto &dec = m.members[index]; - - switch (decoration) + auto *m = find_meta(id); + if (m) { - case DecorationHlslSemanticGOOGLE: - return dec.hlsl_semantic; + if (!has_member_decoration(id, index, decoration)) + return empty_string; - default: - return empty; + auto &dec = m->members[index]; + + switch (decoration) + { + case DecorationHlslSemanticGOOGLE: + return dec.hlsl_semantic; + + default: + return empty_string; + } } + else + return empty_string; } void ParsedIR::unset_member_decoration(uint32_t id, uint32_t index, Decoration decoration) @@ -544,9 +572,77 @@ uint32_t ParsedIR::increase_bound_by(uint32_t incr_amount) auto curr_bound = ids.size(); auto new_bound = curr_bound + incr_amount; ids.resize(new_bound); - meta.resize(new_bound); block_meta.resize(new_bound); return uint32_t(curr_bound); } +void ParsedIR::remove_typed_id(Types type, uint32_t id) +{ + auto &type_ids = ids_for_type[type]; + type_ids.erase(remove(begin(type_ids), end(type_ids), id), end(type_ids)); +} + +void ParsedIR::reset_all_of_type(Types type) +{ + for (auto &id : ids_for_type[type]) + if (ids[id].get_type() == type) + ids[id].reset(); + + ids_for_type[type].clear(); +} + +void ParsedIR::add_typed_id(Types type, uint32_t id) +{ + if (loop_iteration_depth) + SPIRV_CROSS_THROW("Cannot add typed ID while looping over it."); + + switch (type) + { + case TypeConstant: + ids_for_constant_or_variable.push_back(id); + ids_for_constant_or_type.push_back(id); + break; + + case TypeVariable: + ids_for_constant_or_variable.push_back(id); + break; + + case TypeType: + case TypeConstantOp: + ids_for_constant_or_type.push_back(id); + break; + + default: + break; + } + + if (ids[id].empty()) + { + ids_for_type[type].push_back(id); + } + else if (ids[id].get_type() != type) + { + remove_typed_id(ids[id].get_type(), id); + ids_for_type[type].push_back(id); + } +} + +const Meta *ParsedIR::find_meta(uint32_t id) const +{ + auto itr = meta.find(id); + if (itr != end(meta)) + return &itr->second; + else + return nullptr; +} + +Meta *ParsedIR::find_meta(uint32_t id) +{ + auto itr = meta.find(id); + if (itr != end(meta)) + return &itr->second; + else + return nullptr; +} + } // namespace spirv_cross diff --git a/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp b/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp index f363b0075..c3c4612eb 100644 --- a/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp +++ b/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp @@ -43,7 +43,19 @@ public: std::vector ids; // Various meta data for IDs, decorations, names, etc. - std::vector meta; + std::unordered_map meta; + + // Holds all IDs which have a certain type. + // This is needed so we can iterate through a specific kind of resource quickly, + // and in-order of module declaration. + std::vector ids_for_type[TypeCount]; + + // Special purpose lists which contain a union of types. + // This is needed so we can declare specialization constants and structs in an interleaved fashion, + // among other things. + // Constants can be of struct type, and struct array sizes can use specialization constants. + std::vector ids_for_constant_or_type; + std::vector ids_for_constant_or_variable; // Declared capabilities and extensions in the SPIR-V module. // Not really used except for reflection at the moment. @@ -111,6 +123,47 @@ public: uint32_t increase_bound_by(uint32_t count); Bitset get_buffer_block_flags(const SPIRVariable &var) const; + void add_typed_id(Types type, uint32_t id); + void remove_typed_id(Types type, uint32_t id); + + template + void for_each_typed_id(const Op &op) + { + loop_iteration_depth++; + for (auto &id : ids_for_type[T::type]) + { + if (ids[id].get_type() == static_cast(T::type)) + op(id, get(id)); + } + loop_iteration_depth--; + } + + template + void for_each_typed_id(const Op &op) const + { + for (auto &id : ids_for_type[T::type]) + { + if (ids[id].get_type() == static_cast(T::type)) + op(id, get(id)); + } + } + + template + void reset_all_of_type() + { + reset_all_of_type(static_cast(T::type)); + } + + void reset_all_of_type(Types type); + + Meta *find_meta(uint32_t id); + const Meta *find_meta(uint32_t id) const; + + const std::string &get_empty_string() const + { + return empty_string; + } + private: template T &get(uint32_t id) @@ -123,6 +176,10 @@ private: { return variant_get(ids[id]); } + + uint32_t loop_iteration_depth = 0; + std::string empty_string; + Bitset cleared_bitset; }; } // namespace spirv_cross diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index e3b7f4080..1a3f08cd4 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -291,25 +291,15 @@ void CompilerGLSL::reset() block_names.clear(); function_overloads.clear(); - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) - { - // Clear unflushed dependees. - id.get().dependees.clear(); - } - else if (id.get_type() == TypeExpression) - { - // And remove all expressions. - id.reset(); - } - else if (id.get_type() == TypeFunction) - { - // Reset active state for all functions. - id.get().active = false; - id.get().flush_undeclared = true; - } - } + ir.for_each_typed_id([&](uint32_t, SPIRFunction &func) { + func.active = false; + func.flush_undeclared = true; + }); + + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { var.dependees.clear(); }); + + ir.reset_all_of_type(); + ir.reset_all_of_type(); statement_count = 0; indent = 0; @@ -344,37 +334,32 @@ void CompilerGLSL::remap_pls_variables() void CompilerGLSL::find_static_extensions() { - for (auto &id : ir.ids) - { - if (id.get_type() == TypeType) + ir.for_each_typed_id([&](uint32_t, const SPIRType &type) { + if (type.basetype == SPIRType::Double) { - auto &type = id.get(); - if (type.basetype == SPIRType::Double) - { - if (options.es) - SPIRV_CROSS_THROW("FP64 not supported in ES profile."); - if (!options.es && options.version < 400) - require_extension_internal("GL_ARB_gpu_shader_fp64"); - } - - if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64) - { - if (options.es) - SPIRV_CROSS_THROW("64-bit integers not supported in ES profile."); - if (!options.es) - require_extension_internal("GL_ARB_gpu_shader_int64"); - } - - if (type.basetype == SPIRType::Half) - require_extension_internal("GL_AMD_gpu_shader_half_float"); - - if (type.basetype == SPIRType::SByte || type.basetype == SPIRType::UByte) - require_extension_internal("GL_EXT_shader_8bit_storage"); - - if (type.basetype == SPIRType::Short || type.basetype == SPIRType::UShort) - require_extension_internal("GL_AMD_gpu_shader_int16"); + if (options.es) + SPIRV_CROSS_THROW("FP64 not supported in ES profile."); + if (!options.es && options.version < 400) + require_extension_internal("GL_ARB_gpu_shader_fp64"); } - } + + if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64) + { + if (options.es) + SPIRV_CROSS_THROW("64-bit integers not supported in ES profile."); + if (!options.es) + require_extension_internal("GL_ARB_gpu_shader_int64"); + } + + if (type.basetype == SPIRType::Half) + require_extension_internal("GL_AMD_gpu_shader_half_float"); + + if (type.basetype == SPIRType::SByte || type.basetype == SPIRType::UByte) + require_extension_internal("GL_EXT_shader_8bit_storage"); + + if (type.basetype == SPIRType::Short || type.basetype == SPIRType::UShort) + require_extension_internal("GL_AMD_gpu_shader_int16"); + }); auto &execution = get_entry_point(); switch (execution.model) @@ -978,7 +963,7 @@ uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bits uint32_t alignment = 0; for (uint32_t i = 0; i < type.member_types.size(); i++) { - auto member_flags = ir.meta[type.self].members.at(i).decoration_flags; + auto member_flags = ir.meta[type.self].members[i].decoration_flags; alignment = max(alignment, type_to_packed_alignment(get(type.member_types[i]), member_flags, packing)); } @@ -1082,7 +1067,7 @@ uint32_t CompilerGLSL::type_to_packed_size(const SPIRType &type, const Bitset &f for (uint32_t i = 0; i < type.member_types.size(); i++) { - auto member_flags = ir.meta[type.self].members.at(i).decoration_flags; + auto member_flags = ir.meta[type.self].members[i].decoration_flags; auto &member_type = get(type.member_types[i]); uint32_t packed_alignment = type_to_packed_alignment(member_type, member_flags, packing); @@ -1155,7 +1140,7 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin for (uint32_t i = 0; i < type.member_types.size(); i++) { auto &memb_type = get(type.member_types[i]); - auto member_flags = ir.meta[type.self].members.at(i).decoration_flags; + auto member_flags = ir.meta[type.self].members[i].decoration_flags; // Verify alignment rules. uint32_t packed_alignment = type_to_packed_alignment(memb_type, member_flags, packing); @@ -1902,19 +1887,14 @@ void CompilerGLSL::replace_illegal_names() }; // clang-format on - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, const SPIRVariable &var) { + if (!is_hidden_variable(var)) { - auto &var = id.get(); - if (!is_hidden_variable(var)) - { - auto &m = ir.meta[var.self].decoration; - if (m.alias.compare(0, 3, "gl_") == 0 || keywords.find(m.alias) != end(keywords)) - m.alias = join("_", m.alias); - } + auto &m = ir.meta[var.self].decoration; + if (m.alias.compare(0, 3, "gl_") == 0 || keywords.find(m.alias) != end(keywords)) + m.alias = join("_", m.alias); } - } + }); } void CompilerGLSL::replace_fragment_output(SPIRVariable &var) @@ -1957,18 +1937,12 @@ void CompilerGLSL::replace_fragment_output(SPIRVariable &var) void CompilerGLSL::replace_fragment_outputs() { - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) - { - auto &var = id.get(); - auto &type = get(var.basetype); + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); - if (!is_builtin_variable(var) && !var.remapped_variable && type.pointer && - var.storage == StorageClassOutput) - replace_fragment_output(var); - } - } + if (!is_builtin_variable(var) && !var.remapped_variable && type.pointer && var.storage == StorageClassOutput) + replace_fragment_output(var); + }); } string CompilerGLSL::remap_swizzle(const SPIRType &out_type, uint32_t input_components, const string &expr) @@ -2027,12 +2001,7 @@ void CompilerGLSL::emit_pls() void CompilerGLSL::fixup_image_load_store_access() { - for (auto &id : ir.ids) - { - if (id.get_type() != TypeVariable) - continue; - - uint32_t var = id.get().self; + ir.for_each_typed_id([&](uint32_t var, const SPIRVariable &) { auto &vartype = expression_type(var); if (vartype.basetype == SPIRType::Image) { @@ -2040,14 +2009,14 @@ void CompilerGLSL::fixup_image_load_store_access() // Solve this by making the image access as restricted as possible and loosen up if we need to. // If any no-read/no-write flags are actually set, assume that the compiler knows what it's doing. - auto &flags = ir.meta.at(var).decoration.decoration_flags; + auto &flags = ir.meta[var].decoration.decoration_flags; if (!flags.get(DecorationNonWritable) && !flags.get(DecorationNonReadable)) { flags.set(DecorationNonWritable); flags.set(DecorationNonReadable); } } - } + }); } void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionModel model) @@ -2063,13 +2032,8 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo uint32_t cull_distance_size = 0; uint32_t clip_distance_size = 0; - for (auto &id : ir.ids) - { - if (id.get_type() != TypeVariable) - continue; - - auto &var = id.get(); - auto &type = get(var.basetype); + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); bool block = has_decoration(type.self, DecorationBlock); Bitset builtins; @@ -2082,9 +2046,9 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo { builtins.set(m.builtin_type); if (m.builtin_type == BuiltInCullDistance) - cull_distance_size = get(type.member_types[index]).array.front(); + cull_distance_size = this->get(type.member_types[index]).array.front(); else if (m.builtin_type == BuiltInClipDistance) - clip_distance_size = get(type.member_types[index]).array.front(); + clip_distance_size = this->get(type.member_types[index]).array.front(); } index++; } @@ -2104,7 +2068,7 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo } if (builtins.empty()) - continue; + return; if (emitted_block) SPIRV_CROSS_THROW("Cannot use more than one builtin I/O block."); @@ -2113,7 +2077,7 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo emitted_block = true; builtin_array = !type.array.empty(); block_var = &var; - } + }); global_builtins = Bitset(global_builtins.get_lower() & ((1ull << BuiltInPosition) | (1ull << BuiltInPointSize) | @@ -2164,15 +2128,10 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo void CompilerGLSL::declare_undefined_values() { bool emitted = false; - for (auto &id : ir.ids) - { - if (id.get_type() != TypeUndef) - continue; - - auto &undef = id.get(); - statement(variable_decl(get(undef.basetype), to_name(undef.self), undef.self), ";"); + ir.for_each_typed_id([&](uint32_t, const SPIRUndef &undef) { + statement(variable_decl(this->get(undef.basetype), to_name(undef.self), undef.self), ";"); emitted = true; - } + }); if (emitted) statement(""); @@ -2238,10 +2197,10 @@ void CompilerGLSL::emit_resources() // emit specialization constants as actual floats, // spec op expressions will redirect to the constant name. // - // TODO: If we have the fringe case that we create a spec constant which depends on a struct type, - // we'll have to deal with that, but there's currently no known way to express that. - for (auto &id : ir.ids) + for (auto &id_ : ir.ids_for_constant_or_type) { + auto &id = ir.ids[id_]; + if (id.get_type() == TypeConstant) { auto &c = id.get(); @@ -2264,6 +2223,20 @@ void CompilerGLSL::emit_resources() emit_specialization_constant_op(id.get()); emitted = true; } + else if (id.get_type() == TypeType) + { + auto &type = id.get(); + if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer && + (!ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) && + !ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock))) + { + if (emitted) + statement(""); + emitted = false; + + emit_struct(type); + } + } } if (emitted) @@ -2289,120 +2262,84 @@ void CompilerGLSL::emit_resources() emitted = false; - // Output all basic struct types which are not Block or BufferBlock as these are declared inplace - // when such variables are instantiated. - for (auto &id : ir.ids) - { - if (id.get_type() == TypeType) - { - auto &type = id.get(); - if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer && - (!ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) && - !ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock))) - { - emit_struct(type); - } - } - } - // Output UBOs and SSBOs - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + + bool is_block_storage = type.storage == StorageClassStorageBuffer || type.storage == StorageClassUniform; + bool has_block_flags = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) || + ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); + + if (var.storage != StorageClassFunction && type.pointer && is_block_storage && !is_hidden_variable(var) && + has_block_flags) { - auto &var = id.get(); - auto &type = get(var.basetype); - - bool is_block_storage = type.storage == StorageClassStorageBuffer || type.storage == StorageClassUniform; - bool has_block_flags = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) || - ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); - - if (var.storage != StorageClassFunction && type.pointer && is_block_storage && !is_hidden_variable(var) && - has_block_flags) - { - emit_buffer_block(var); - } + emit_buffer_block(var); } - } + }); // Output push constant blocks - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + if (var.storage != StorageClassFunction && type.pointer && type.storage == StorageClassPushConstant && + !is_hidden_variable(var)) { - auto &var = id.get(); - auto &type = get(var.basetype); - if (var.storage != StorageClassFunction && type.pointer && type.storage == StorageClassPushConstant && - !is_hidden_variable(var)) - { - emit_push_constant_block(var); - } + emit_push_constant_block(var); } - } + }); bool skip_separate_image_sampler = !combined_image_samplers.empty() || !options.vulkan_semantics; // Output Uniform Constants (values, samplers, images, etc). - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + + // If we're remapping separate samplers and images, only emit the combined samplers. + if (skip_separate_image_sampler) { - auto &var = id.get(); - auto &type = get(var.basetype); - - // If we're remapping separate samplers and images, only emit the combined samplers. - if (skip_separate_image_sampler) - { - // Sampler buffers are always used without a sampler, and they will also work in regular GL. - bool sampler_buffer = type.basetype == SPIRType::Image && type.image.dim == DimBuffer; - bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1; - bool separate_sampler = type.basetype == SPIRType::Sampler; - if (!sampler_buffer && (separate_image || separate_sampler)) - continue; - } - - if (var.storage != StorageClassFunction && type.pointer && - (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter) && - !is_hidden_variable(var)) - { - emit_uniform(var); - emitted = true; - } + // Sampler buffers are always used without a sampler, and they will also work in regular GL. + bool sampler_buffer = type.basetype == SPIRType::Image && type.image.dim == DimBuffer; + bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1; + bool separate_sampler = type.basetype == SPIRType::Sampler; + if (!sampler_buffer && (separate_image || separate_sampler)) + return; } - } + + if (var.storage != StorageClassFunction && type.pointer && + (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter) && + !is_hidden_variable(var)) + { + emit_uniform(var); + emitted = true; + } + }); if (emitted) statement(""); emitted = false; // Output in/out interfaces. - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) - { - auto &var = id.get(); - auto &type = get(var.basetype); + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); - if (var.storage != StorageClassFunction && type.pointer && - (var.storage == StorageClassInput || var.storage == StorageClassOutput) && - interface_variable_exists_in_entry_point(var.self) && !is_hidden_variable(var)) + if (var.storage != StorageClassFunction && type.pointer && + (var.storage == StorageClassInput || var.storage == StorageClassOutput) && + interface_variable_exists_in_entry_point(var.self) && !is_hidden_variable(var)) + { + emit_interface_block(var); + emitted = true; + } + else if (is_builtin_variable(var)) + { + // For gl_InstanceIndex emulation on GLES, the API user needs to + // supply this uniform. + if (options.vertex.support_nonzero_base_instance && + ir.meta[var.self].decoration.builtin_type == BuiltInInstanceIndex && !options.vulkan_semantics) { - emit_interface_block(var); + statement("uniform int SPIRV_Cross_BaseInstance;"); emitted = true; } - else if (is_builtin_variable(var)) - { - // For gl_InstanceIndex emulation on GLES, the API user needs to - // supply this uniform. - if (options.vertex.support_nonzero_base_instance && - ir.meta[var.self].decoration.builtin_type == BuiltInInstanceIndex && !options.vulkan_semantics) - { - statement("uniform int SPIRV_Cross_BaseInstance;"); - emitted = true; - } - } } - } + }); // Global variables. for (auto global : global_variables) @@ -2526,7 +2463,7 @@ string CompilerGLSL::dereference_expression(const std::string &expr) // If this expression starts with an address-of operator ('&'), then // just return the part after the operator. // TODO: Strip parens if unnecessary? - if (expr.at(0) == '&') + if (expr.front() == '&') return expr.substr(1); else return join('*', expr); @@ -2537,7 +2474,7 @@ string CompilerGLSL::address_of_expression(const std::string &expr) // If this expression starts with a dereference operator ('*'), then // just return the part after the operator. // TODO: Strip parens if unnecessary? - if (expr.at(0) == '*') + if (expr.front() == '*') return expr.substr(1); else return join('&', expr); @@ -8135,7 +8072,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto *var = maybe_get_backing_variable(ops[2]); if (var) { - auto &flags = ir.meta.at(var->self).decoration.decoration_flags; + auto &flags = ir.meta[var->self].decoration.decoration_flags; if (flags.get(DecorationNonReadable)) { flags.clear(DecorationNonReadable); @@ -8283,7 +8220,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto *var = maybe_get_backing_variable(ops[0]); if (var) { - auto &flags = ir.meta.at(var->self).decoration.decoration_flags; + auto &flags = ir.meta[var->self].decoration.decoration_flags; if (flags.get(DecorationNonWritable)) { flags.clear(DecorationNonWritable); @@ -9473,7 +9410,7 @@ void CompilerGLSL::flatten_buffer_block(uint32_t id) auto &var = get(id); auto &type = get(var.basetype); auto name = to_name(type.self, false); - auto &flags = ir.meta.at(type.self).decoration.decoration_flags; + auto &flags = ir.meta[type.self].decoration.decoration_flags; if (!type.array.empty()) SPIRV_CROSS_THROW(name + " is an array of UBOs."); @@ -9498,7 +9435,7 @@ bool CompilerGLSL::check_atomic_image(uint32_t id) auto *var = maybe_get_backing_variable(id); if (var) { - auto &flags = ir.meta.at(var->self).decoration.decoration_flags; + auto &flags = ir.meta[var->self].decoration.decoration_flags; if (flags.get(DecorationNonWritable) || flags.get(DecorationNonReadable)) { flags.clear(DecorationNonWritable); @@ -9668,6 +9605,14 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags) current_function = &func; auto &entry_block = get(func.entry_block); + sort(begin(func.constant_arrays_needed_on_stack), end(func.constant_arrays_needed_on_stack)); + for (auto &array : func.constant_arrays_needed_on_stack) + { + auto &c = get(array); + auto &type = get(c.constant_type); + statement(variable_decl(type, join("_", array, "_array_copy")), " = ", constant_expression(c), ";"); + } + for (auto &v : func.local_variables) { auto &var = get(v); @@ -10607,7 +10552,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) { // If we cannot return arrays, we will have a special out argument we can write to instead. // The backend is responsible for setting this up, and redirection the return values as appropriate. - if (ir.ids.at(block.return_value).get_type() != TypeUndef) + if (ir.ids[block.return_value].get_type() != TypeUndef) emit_array_copy("SPIRV_Cross_return_value", block.return_value); if (!block_is_outside_flow_control_from_block(get(current_function->entry_block), block) || @@ -10619,7 +10564,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) else { // OpReturnValue can return Undef, so don't emit anything for this case. - if (ir.ids.at(block.return_value).get_type() != TypeUndef) + if (ir.ids[block.return_value].get_type() != TypeUndef) statement("return ", to_expression(block.return_value), ";"); } } diff --git a/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/spirv-cross/spirv_glsl.hpp index f42e98d37..6192e7a49 100644 --- a/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/3rdparty/spirv-cross/spirv_glsl.hpp @@ -105,6 +105,7 @@ public: // Inverts gl_Position.y or equivalent. bool flip_vert_y = false; + // GLSL only, for HLSL version of this option, see CompilerHLSL. // If true, the backend will assume that InstanceIndex will need to apply // a base instance offset. Set to false if you know you will never use base instance // functionality as it might remove some internal uniforms. diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index 486fec540..dc2e03087 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -805,7 +805,14 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord bool legacy = hlsl_options.shader_model <= 30; if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput) { - binding = join(legacy ? "COLOR" : "SV_Target", get_decoration(var.self, DecorationLocation)); + // Dual-source blending is achieved in HLSL by emitting to SV_Target0 and 1. + uint32_t index = get_decoration(var.self, DecorationIndex); + uint32_t location = get_decoration(var.self, DecorationLocation); + + if (index != 0 && location != 0) + SPIRV_CROSS_THROW("Dual-source blending is only supported on MRT #0 in HLSL."); + + binding = join(legacy ? "COLOR" : "SV_Target", location + index); use_location_number = false; if (legacy) // COLOR must be a four-component vector on legacy shader model targets (HLSL ERR_COLOR_4COMP) type.vecsize = 4; @@ -902,6 +909,8 @@ void CompilerHLSL::emit_builtin_variables() Bitset builtins = active_input_builtins; builtins.merge_or(active_output_builtins); + bool need_base_vertex_info = false; + // Emit global variables for the interface variables which are statically used by the shader. builtins.for_each_bit([&](uint32_t i) { const char *type = nullptr; @@ -921,8 +930,13 @@ void CompilerHLSL::emit_builtin_variables() case BuiltInVertexId: case BuiltInVertexIndex: - case BuiltInInstanceId: case BuiltInInstanceIndex: + type = "int"; + if (hlsl_options.support_nonzero_base_vertex_base_instance) + need_base_vertex_info = true; + break; + + case BuiltInInstanceId: case BuiltInSampleId: type = "int"; break; @@ -998,6 +1012,16 @@ void CompilerHLSL::emit_builtin_variables() statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";"); } }); + + if (need_base_vertex_info) + { + statement("cbuffer SPIRV_Cross_VertexInfo"); + begin_scope(); + statement("int SPIRV_Cross_BaseVertex;"); + statement("int SPIRV_Cross_BaseInstance;"); + end_scope_decl(); + statement(""); + } } void CompilerHLSL::emit_composite_constants() @@ -1006,36 +1030,33 @@ void CompilerHLSL::emit_composite_constants() // global constants directly. bool emitted = false; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeConstant) - { - auto &c = id.get(); - if (c.specialization) - continue; + ir.for_each_typed_id([&](uint32_t, SPIRConstant &c) { + if (c.specialization) + return; - auto &type = get(c.constant_type); - if (type.basetype == SPIRType::Struct || !type.array.empty()) - { - auto name = to_name(c.self); - statement("static const ", variable_decl(type, name), " = ", constant_expression(c), ";"); - emitted = true; - } + auto &type = this->get(c.constant_type); + if (type.basetype == SPIRType::Struct || !type.array.empty()) + { + auto name = to_name(c.self); + statement("static const ", variable_decl(type, name), " = ", constant_expression(c), ";"); + emitted = true; } - } + }); if (emitted) statement(""); } -void CompilerHLSL::emit_specialization_constants() +void CompilerHLSL::emit_specialization_constants_and_structs() { bool emitted = false; SpecializationConstant wg_x, wg_y, wg_z; uint32_t workgroup_size_id = get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); - for (auto &id : ir.ids) + for (auto &id_ : ir.ids_for_constant_or_type) { + auto &id = ir.ids[id_]; + if (id.get_type() == TypeConstant) { auto &c = id.get(); @@ -1070,6 +1091,20 @@ void CompilerHLSL::emit_specialization_constants() statement("static const ", variable_decl(type, name), " = ", constant_op_expression(c), ";"); emitted = true; } + else if (id.get_type() == TypeType) + { + auto &type = id.get(); + if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer && + (!ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) && + !ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock))) + { + if (emitted) + statement(""); + emitted = false; + + emit_struct(type); + } + } } if (emitted) @@ -1083,19 +1118,14 @@ void CompilerHLSL::replace_illegal_names() "line", "linear", "matrix", "point", "row_major", "sampler", }; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + if (!is_hidden_variable(var)) { - auto &var = id.get(); - if (!is_hidden_variable(var)) - { - auto &m = ir.meta[var.self].decoration; - if (keywords.find(m.alias) != end(keywords)) - m.alias = join("_", m.alias); - } + auto &m = ir.meta[var.self].decoration; + if (keywords.find(m.alias) != end(keywords)) + m.alias = join("_", m.alias); } - } + }); CompilerGLSL::replace_illegal_names(); } @@ -1106,64 +1136,37 @@ void CompilerHLSL::emit_resources() replace_illegal_names(); - emit_specialization_constants(); - - // Output all basic struct types which are not Block or BufferBlock as these are declared inplace - // when such variables are instantiated. - for (auto &id : ir.ids) - { - if (id.get_type() == TypeType) - { - auto &type = id.get(); - if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer && - (!ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) && - !ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock))) - { - emit_struct(type); - } - } - } - + emit_specialization_constants_and_structs(); emit_composite_constants(); bool emitted = false; // Output UBOs and SSBOs - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + + bool is_block_storage = type.storage == StorageClassStorageBuffer || type.storage == StorageClassUniform; + bool has_block_flags = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) || + ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); + + if (var.storage != StorageClassFunction && type.pointer && is_block_storage && !is_hidden_variable(var) && + has_block_flags) { - auto &var = id.get(); - auto &type = get(var.basetype); - - bool is_block_storage = type.storage == StorageClassStorageBuffer || type.storage == StorageClassUniform; - bool has_block_flags = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) || - ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); - - if (var.storage != StorageClassFunction && type.pointer && is_block_storage && !is_hidden_variable(var) && - has_block_flags) - { - emit_buffer_block(var); - emitted = true; - } + emit_buffer_block(var); + emitted = true; } - } + }); // Output push constant blocks - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + if (var.storage != StorageClassFunction && type.pointer && type.storage == StorageClassPushConstant && + !is_hidden_variable(var)) { - auto &var = id.get(); - auto &type = get(var.basetype); - if (var.storage != StorageClassFunction && type.pointer && type.storage == StorageClassPushConstant && - !is_hidden_variable(var)) - { - emit_push_constant_block(var); - emitted = true; - } + emit_push_constant_block(var); + emitted = true; } - } + }); if (execution.model == ExecutionModelVertex && hlsl_options.shader_model <= 30) { @@ -1174,33 +1177,27 @@ void CompilerHLSL::emit_resources() bool skip_separate_image_sampler = !combined_image_samplers.empty() || hlsl_options.shader_model <= 30; // Output Uniform Constants (values, samplers, images, etc). - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + + // If we're remapping separate samplers and images, only emit the combined samplers. + if (skip_separate_image_sampler) { - auto &var = id.get(); - auto &type = get(var.basetype); - - // If we're remapping separate samplers and images, only emit the combined samplers. - if (skip_separate_image_sampler) - { - // Sampler buffers are always used without a sampler, and they will also work in regular D3D. - bool sampler_buffer = type.basetype == SPIRType::Image && type.image.dim == DimBuffer; - bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1; - bool separate_sampler = type.basetype == SPIRType::Sampler; - if (!sampler_buffer && (separate_image || separate_sampler)) - continue; - } - - if (var.storage != StorageClassFunction && !is_builtin_variable(var) && !var.remapped_variable && - type.pointer && - (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter)) - { - emit_uniform(var); - emitted = true; - } + // Sampler buffers are always used without a sampler, and they will also work in regular D3D. + bool sampler_buffer = type.basetype == SPIRType::Image && type.image.dim == DimBuffer; + bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1; + bool separate_sampler = type.basetype == SPIRType::Sampler; + if (!sampler_buffer && (separate_image || separate_sampler)) + return; } - } + + if (var.storage != StorageClassFunction && !is_builtin_variable(var) && !var.remapped_variable && + type.pointer && (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter)) + { + emit_uniform(var); + emitted = true; + } + }); if (emitted) statement(""); @@ -1209,27 +1206,22 @@ void CompilerHLSL::emit_resources() // Emit builtin input and output variables here. emit_builtin_variables(); - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) - { - auto &var = id.get(); - auto &type = get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - // Do not emit I/O blocks here. - // I/O blocks can be arrayed, so we must deal with them separately to support geometry shaders - // and tessellation down the line. - if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && - (var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) - { - // Only emit non-builtins which are not blocks here. Builtin variables are handled separately. - emit_interface_block_globally(var); - emitted = true; - } + // Do not emit I/O blocks here. + // I/O blocks can be arrayed, so we must deal with them separately to support geometry shaders + // and tessellation down the line. + if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && + (var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) && + interface_variable_exists_in_entry_point(var.self)) + { + // Only emit non-builtins which are not blocks here. Builtin variables are handled separately. + emit_interface_block_globally(var); + emitted = true; } - } + }); if (emitted) statement(""); @@ -1241,47 +1233,42 @@ void CompilerHLSL::emit_resources() unordered_set active_outputs; vector input_variables; vector output_variables; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + + if (var.storage != StorageClassInput && var.storage != StorageClassOutput) + return; + + // Do not emit I/O blocks here. + // I/O blocks can be arrayed, so we must deal with them separately to support geometry shaders + // and tessellation down the line. + if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) && + interface_variable_exists_in_entry_point(var.self)) { - auto &var = id.get(); - auto &type = get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - - if (var.storage != StorageClassInput && var.storage != StorageClassOutput) - continue; - - // Do not emit I/O blocks here. - // I/O blocks can be arrayed, so we must deal with them separately to support geometry shaders - // and tessellation down the line. - if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) - { - if (var.storage == StorageClassInput) - input_variables.push_back(&var); - else - output_variables.push_back(&var); - } - - // Reserve input and output locations for block variables as necessary. - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) - { - auto &active = var.storage == StorageClassInput ? active_inputs : active_outputs; - for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) - { - if (has_member_decoration(type.self, i, DecorationLocation)) - { - uint32_t location = get_member_decoration(type.self, i, DecorationLocation); - active.insert(location); - } - } - - // Emit the block struct and a global variable here. - emit_io_block(var); - } + if (var.storage == StorageClassInput) + input_variables.push_back(&var); + else + output_variables.push_back(&var); } - } + + // Reserve input and output locations for block variables as necessary. + if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) + { + auto &active = var.storage == StorageClassInput ? active_inputs : active_outputs; + for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) + { + if (has_member_decoration(type.self, i, DecorationLocation)) + { + uint32_t location = get_member_decoration(type.self, i, DecorationLocation); + active.insert(location); + } + } + + // Emit the block struct and a global variable here. + emit_io_block(var); + } + }); const auto variable_compare = [&](const SPIRVariable *a, const SPIRVariable *b) -> bool { // Sort input and output variables based on, from more robust to less robust: @@ -2169,30 +2156,25 @@ void CompilerHLSL::emit_hlsl_entry_point() arguments.push_back("SPIRV_Cross_Input stage_input"); // Add I/O blocks as separate arguments with appropriate storage qualifier. - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + + if (var.storage != StorageClassInput && var.storage != StorageClassOutput) + return; + + if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) { - auto &var = id.get(); - auto &type = get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - - if (var.storage != StorageClassInput && var.storage != StorageClassOutput) - continue; - - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) + if (var.storage == StorageClassInput) { - if (var.storage == StorageClassInput) - { - arguments.push_back(join("in ", variable_decl(type, join("stage_input", to_name(var.self))))); - } - else if (var.storage == StorageClassOutput) - { - arguments.push_back(join("out ", variable_decl(type, join("stage_output", to_name(var.self))))); - } + arguments.push_back(join("in ", variable_decl(type, join("stage_input", to_name(var.self))))); + } + else if (var.storage == StorageClassOutput) + { + arguments.push_back(join("out ", variable_decl(type, join("stage_output", to_name(var.self))))); } } - } + }); auto &execution = get_entry_point(); @@ -2243,8 +2225,20 @@ void CompilerHLSL::emit_hlsl_entry_point() case BuiltInVertexId: case BuiltInVertexIndex: - case BuiltInInstanceId: case BuiltInInstanceIndex: + // D3D semantics are uint, but shader wants int. + if (hlsl_options.support_nonzero_base_vertex_base_instance) + { + if (static_cast(i) == BuiltInInstanceIndex) + statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseInstance;"); + else + statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseVertex;"); + } + else + statement(builtin, " = int(stage_input.", builtin, ");"); + break; + + case BuiltInInstanceId: // D3D semantics are uint, but shader wants int. statement(builtin, " = int(stage_input.", builtin, ");"); break; @@ -2336,44 +2330,39 @@ void CompilerHLSL::emit_hlsl_entry_point() }); // Copy from stage input struct to globals. - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + + if (var.storage != StorageClassInput) + return; + + bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex; + + if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) && + interface_variable_exists_in_entry_point(var.self)) { - auto &var = id.get(); - auto &type = get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - - if (var.storage != StorageClassInput) - continue; - - bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex; - - if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) + auto name = to_name(var.self); + auto &mtype = this->get(var.basetype); + if (need_matrix_unroll && mtype.columns > 1) { - auto name = to_name(var.self); - auto &mtype = get(var.basetype); - if (need_matrix_unroll && mtype.columns > 1) - { - // Unroll matrices. - for (uint32_t col = 0; col < mtype.columns; col++) - statement(name, "[", col, "] = stage_input.", name, "_", col, ";"); - } - else - { - statement(name, " = stage_input.", name, ";"); - } + // Unroll matrices. + for (uint32_t col = 0; col < mtype.columns; col++) + statement(name, "[", col, "] = stage_input.", name, "_", col, ";"); } - - // I/O blocks don't use the common stage input/output struct, but separate outputs. - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) + else { - auto name = to_name(var.self); - statement(name, " = stage_input", name, ";"); + statement(name, " = stage_input.", name, ";"); } } - } + + // I/O blocks don't use the common stage input/output struct, but separate outputs. + if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) + { + auto name = to_name(var.self); + statement(name, " = stage_input", name, ";"); + } + }); // Run the shader. if (execution.model == ExecutionModelVertex) @@ -2386,25 +2375,20 @@ void CompilerHLSL::emit_hlsl_entry_point() SPIRV_CROSS_THROW("Unsupported shader stage."); // Copy block outputs. - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + + if (var.storage != StorageClassOutput) + return; + + // I/O blocks don't use the common stage input/output struct, but separate outputs. + if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) { - auto &var = id.get(); - auto &type = get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - - if (var.storage != StorageClassOutput) - continue; - - // I/O blocks don't use the common stage input/output struct, but separate outputs. - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) - { - auto name = to_name(var.self); - statement("stage_output", name, " = ", name, ";"); - } + auto name = to_name(var.self); + statement("stage_output", name, " = ", name, ";"); } - } + }); // Copy stage outputs. if (require_output) @@ -2440,37 +2424,32 @@ void CompilerHLSL::emit_hlsl_entry_point() } }); - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + + if (var.storage != StorageClassOutput) + return; + + if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && + !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) { - auto &var = id.get(); - auto &type = get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + auto name = to_name(var.self); - if (var.storage != StorageClassOutput) - continue; - - if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && - !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) + if (legacy && execution.model == ExecutionModelFragment) { - auto name = to_name(var.self); + string output_filler; + for (uint32_t size = type.vecsize; size < 4; ++size) + output_filler += ", 0.0"; - if (legacy && execution.model == ExecutionModelFragment) - { - string output_filler; - for (uint32_t size = type.vecsize; size < 4; ++size) - output_filler += ", 0.0"; - - statement("stage_output.", name, " = float4(", name, output_filler, ");"); - } - else - { - statement("stage_output.", name, " = ", name, ";"); - } + statement("stage_output.", name, " = float4(", name, output_filler, ");"); + } + else + { + statement("stage_output.", name, " = ", name, ";"); } } - } + }); statement("return stage_output;"); } diff --git a/3rdparty/spirv-cross/spirv_hlsl.hpp b/3rdparty/spirv-cross/spirv_hlsl.hpp index 672436376..d06229cde 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.hpp +++ b/3rdparty/spirv-cross/spirv_hlsl.hpp @@ -54,6 +54,12 @@ public: // Allows the PointCoord builtin, returns float2(0.5, 0.5), as PointCoord is not supported in HLSL. bool point_coord_compat = false; + + // If true, the backend will assume that VertexIndex and InstanceIndex will need to apply + // a base offset, and you will need to fill in a cbuffer with offsets. + // Set to false if you know you will never use base instance or base vertex + // functionality as it might remove an internal cbuffer. + bool support_nonzero_base_vertex_base_instance = false; }; explicit CompilerHLSL(std::vector spirv_) @@ -148,7 +154,7 @@ private: void emit_uniform(const SPIRVariable &var) override; void emit_modern_uniform(const SPIRVariable &var); void emit_legacy_uniform(const SPIRVariable &var); - void emit_specialization_constants(); + void emit_specialization_constants_and_structs(); void emit_composite_constants(); void emit_fixup() override; std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override; diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 21647198b..4f81ae388 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -82,6 +82,11 @@ CompilerMSL::CompilerMSL(ParsedIR &&ir_, MSLVertexAttr *p_vtx_attrs, size_t vtx_ resource_bindings.push_back(&p_res_bindings[i]); } +void CompilerMSL::set_fragment_output_components(uint32_t location, uint32_t components) +{ + fragment_output_components[location] = components; +} + void CompilerMSL::build_implicit_builtins() { bool need_sample_pos = active_input_builtins.get(BuiltInSamplePosition); @@ -90,19 +95,12 @@ void CompilerMSL::build_implicit_builtins() bool has_frag_coord = false; bool has_sample_id = false; - for (auto &id : ir.ids) - { - if (id.get_type() != TypeVariable) - continue; - - auto &var = id.get(); - + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { if (need_subpass_input && var.storage == StorageClassInput && ir.meta[var.self].decoration.builtin && ir.meta[var.self].decoration.builtin_type == BuiltInFragCoord) { builtin_frag_coord_id = var.self; has_frag_coord = true; - break; } if (need_sample_pos && var.storage == StorageClassInput && ir.meta[var.self].decoration.builtin && @@ -110,9 +108,8 @@ void CompilerMSL::build_implicit_builtins() { builtin_sample_id_id = var.self; has_sample_id = true; - break; } - } + }); if (!has_frag_coord && need_subpass_input) { @@ -464,7 +461,7 @@ string CompilerMSL::compile() buffer = unique_ptr(new ostringstream()); emit_header(); - emit_specialization_constants(); + emit_specialization_constants_and_structs(); emit_resources(); emit_custom_functions(); emit_function(get(ir.default_entry_point), Bitset()); @@ -547,19 +544,14 @@ void CompilerMSL::extract_global_variables_from_functions() { // Uniforms unordered_set global_var_ids; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + if (var.storage == StorageClassInput || var.storage == StorageClassOutput || + var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || + var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) { - auto &var = id.get(); - if (var.storage == StorageClassInput || var.storage == StorageClassOutput || - var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || - var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) - { - global_var_ids.insert(var.self); - } + global_var_ids.insert(var.self); } - } + }); // Local vars that are declared in the main function and accessed directly by a function auto &entry_func = get(ir.default_entry_point); @@ -739,22 +731,17 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: // that are recursively contained within the type referenced by that variable should be packed tightly. void CompilerMSL::mark_packable_structs() { - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + if (var.storage != StorageClassFunction && !is_hidden_variable(var)) { - auto &var = id.get(); - if (var.storage != StorageClassFunction && !is_hidden_variable(var)) - { - auto &type = get(var.basetype); - if (type.pointer && - (type.storage == StorageClassUniform || type.storage == StorageClassUniformConstant || - type.storage == StorageClassPushConstant || type.storage == StorageClassStorageBuffer) && - (has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock))) - mark_as_packable(type); - } + auto &type = this->get(var.basetype); + if (type.pointer && + (type.storage == StorageClassUniform || type.storage == StorageClassUniformConstant || + type.storage == StorageClassPushConstant || type.storage == StorageClassStorageBuffer) && + (has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock))) + mark_as_packable(type); } - } + }); } // If the specified type is a struct, it and any nested structs @@ -797,6 +784,27 @@ void CompilerMSL::mark_location_as_used_by_shader(uint32_t location, StorageClas p_va->used_by_shader = true; } +uint32_t CompilerMSL::get_target_components_for_fragment_location(uint32_t location) const +{ + auto itr = fragment_output_components.find(location); + if (itr == end(fragment_output_components)) + return 4; + else + return itr->second; +} + +uint32_t CompilerMSL::build_extended_vector_type(uint32_t type_id, uint32_t components) +{ + uint32_t new_type_id = ir.increase_bound_by(1); + auto &type = set(new_type_id, get(type_id)); + type.vecsize = components; + type.self = new_type_id; + type.parent_type = 0; + type.pointer = false; + + return new_type_id; +} + void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, const string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var) { @@ -811,6 +819,26 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size()); uint32_t type_id = ensure_correct_builtin_type(var.basetype, builtin); var.basetype = type_id; + + auto &type = get(type_id); + uint32_t target_components = 0; + uint32_t type_components = type.vecsize; + bool padded_output = false; + + // Check if we need to pad fragment output to match a certain number of components. + if (get_decoration_bitset(var.self).get(DecorationLocation) && msl_options.pad_fragment_output_components && + get_entry_point().model == ExecutionModelFragment && storage == StorageClassOutput) + { + uint32_t locn = get_decoration(var.self, DecorationLocation); + target_components = get_target_components_for_fragment_location(locn); + if (type_components < target_components) + { + // Make a new type here. + type_id = build_extended_vector_type(type_id, target_components); + padded_output = true; + } + } + ib_type.member_types.push_back(get_pointee_type_id(type_id)); // Give the member a name @@ -819,7 +847,20 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co // Update the original variable reference to include the structure reference string qual_var_name = ib_var_ref + "." + mbr_name; - ir.meta[var.self].decoration.qualified_alias = qual_var_name; + + if (padded_output) + { + auto &entry_func = get(ir.default_entry_point); + entry_func.add_local_variable(var.self); + vars_needing_early_declaration.push_back(var.self); + + entry_func.fixup_hooks_out.push_back([=, &var]() { + SPIRType &padded_type = this->get(type_id); + statement(qual_var_name, " = ", remap_swizzle(padded_type, type_components, to_name(var.self)), ";"); + }); + } + else + ir.meta[var.self].decoration.qualified_alias = qual_var_name; // Copy the variable location from the original variable to the member if (get_decoration_bitset(var.self).get(DecorationLocation)) @@ -908,7 +949,26 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage { // Add a reference to the variable type to the interface struct. uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size()); - ib_type.member_types.push_back(usable_type->self); + + uint32_t target_components = 0; + bool padded_output = false; + uint32_t type_id = usable_type->self; + + // Check if we need to pad fragment output to match a certain number of components. + if (get_decoration_bitset(var.self).get(DecorationLocation) && msl_options.pad_fragment_output_components && + get_entry_point().model == ExecutionModelFragment && storage == StorageClassOutput) + { + uint32_t locn = get_decoration(var.self, DecorationLocation) + i; + target_components = get_target_components_for_fragment_location(locn); + if (usable_type->vecsize < target_components) + { + // Make a new type here. + type_id = build_extended_vector_type(usable_type->self, target_components); + padded_output = true; + } + } + + ib_type.member_types.push_back(get_pointee_type_id(type_id)); // Give the member a name string mbr_name = ensure_valid_name(join(to_expression(var.self), "_", i), "m"); @@ -948,12 +1008,21 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage { case StorageClassInput: entry_func.fixup_hooks_in.push_back( - [=]() { statement(to_name(var.self), "[", i, "] = ", ib_var_ref, ".", mbr_name, ";"); }); + [=, &var]() { statement(to_name(var.self), "[", i, "] = ", ib_var_ref, ".", mbr_name, ";"); }); break; case StorageClassOutput: - entry_func.fixup_hooks_out.push_back( - [=]() { statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), "[", i, "];"); }); + entry_func.fixup_hooks_out.push_back([=, &var]() { + if (padded_output) + { + auto &padded_type = this->get(type_id); + statement(ib_var_ref, ".", mbr_name, " = ", + remap_swizzle(padded_type, usable_type->vecsize, join(to_name(var.self), "[", i, "]")), + ";"); + } + else + statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), "[", i, "];"); + }); break; default: @@ -1071,14 +1140,14 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass switch (storage) { case StorageClassInput: - entry_func.fixup_hooks_in.push_back([=]() { + entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() { statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref, ".", mbr_name, ";"); }); break; case StorageClassOutput: - entry_func.fixup_hooks_out.push_back([=]() { + entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() { statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "];"); }); @@ -1133,13 +1202,13 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor switch (storage) { case StorageClassInput: - entry_func.fixup_hooks_in.push_back([=]() { + entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() { statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), " = ", qual_var_name, ";"); }); break; case StorageClassOutput: - entry_func.fixup_hooks_out.push_back([=]() { + entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() { statement(qual_var_name, " = ", to_name(var.self), ".", to_member_name(var_type, mbr_idx), ";"); }); break; @@ -1273,19 +1342,15 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage) // Accumulate the variables that should appear in the interface struct vector vars; bool incl_builtins = (storage == StorageClassOutput); - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + if (var.storage == storage && interface_variable_exists_in_entry_point(var.self) && + !is_hidden_variable(var, incl_builtins) && type.pointer) { - auto &var = id.get(); - auto &type = get(var.basetype); - if (var.storage == storage && interface_variable_exists_in_entry_point(var.self) && - !is_hidden_variable(var, incl_builtins) && type.pointer) - { - vars.push_back(&var); - } + vars.push_back(&var); } - } + }); // If no variables qualify, leave if (vars.empty()) @@ -2044,7 +2109,7 @@ void CompilerMSL::emit_custom_functions() statement(""); statement("// Wrapper function that swizzles texture gathers."); statement("template"); - statement("inline vec spvGatherSwizzle(sampler s, thread Tex& t, Ts... params, component c, uint sw) " + statement("inline vec spvGatherSwizzle(sampler s, const thread Tex& t, Ts... params, component c, uint sw) " "METAL_CONST_ARG(c)"); begin_scope(); statement("if (sw)"); @@ -2084,7 +2149,7 @@ void CompilerMSL::emit_custom_functions() statement(""); statement("// Wrapper function that swizzles depth texture gathers."); statement("template"); - statement("inline vec spvGatherCompareSwizzle(sampler s, thread Tex& t, Ts... params, uint sw) "); + statement("inline vec spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... params, uint sw) "); begin_scope(); statement("if (sw)"); begin_scope(); @@ -2117,16 +2182,11 @@ void CompilerMSL::emit_custom_functions() void CompilerMSL::declare_undefined_values() { bool emitted = false; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeUndef) - { - auto &undef = id.get(); - auto &type = get(undef.basetype); - statement("constant ", variable_decl(type, to_name(undef.self), undef.self), " = {};"); - emitted = true; - } - } + ir.for_each_typed_id([&](uint32_t, SPIRUndef &undef) { + auto &type = this->get(undef.basetype); + statement("constant ", variable_decl(type, to_name(undef.self), undef.self), " = {};"); + emitted = true; + }); if (emitted) statement(""); @@ -2138,23 +2198,18 @@ void CompilerMSL::declare_constant_arrays() // global constants directly, so we are able to use constants as variable expressions. bool emitted = false; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeConstant) - { - auto &c = id.get(); - if (c.specialization) - continue; + ir.for_each_typed_id([&](uint32_t, SPIRConstant &c) { + if (c.specialization) + return; - auto &type = get(c.constant_type); - if (!type.array.empty()) - { - auto name = to_name(c.self); - statement("constant ", variable_decl(type, name), " = ", constant_expression(c), ";"); - emitted = true; - } + auto &type = this->get(c.constant_type); + if (!type.array.empty()) + { + auto name = to_name(c.self); + statement("constant ", variable_decl(type, name), " = ", constant_expression(c), ";"); + emitted = true; } - } + }); if (emitted) statement(""); @@ -2162,42 +2217,6 @@ void CompilerMSL::declare_constant_arrays() void CompilerMSL::emit_resources() { - // Output non-builtin interface structs. These include local function structs - // and structs nested within uniform and read-write buffers. - unordered_set declared_structs; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeType) - { - auto &type = id.get(); - uint32_t type_id = type.self; - - bool is_struct = (type.basetype == SPIRType::Struct) && type.array.empty(); - bool is_block = - has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock); - - bool is_builtin_block = is_block && is_builtin_type(type); - bool is_declarable_struct = is_struct && !is_builtin_block; - - // We'll declare this later. - if (stage_out_var_id && get(stage_out_var_id).basetype == type_id) - is_declarable_struct = false; - if (stage_in_var_id && get(stage_in_var_id).basetype == type_id) - is_declarable_struct = false; - - // Align and emit declarable structs...but avoid declaring each more than once. - if (is_declarable_struct && declared_structs.count(type_id) == 0) - { - declared_structs.insert(type_id); - - if (has_decoration(type_id, DecorationCPacked)) - align_struct(type); - - emit_struct(type); - } - } - } - declare_constant_arrays(); declare_undefined_values(); @@ -2207,14 +2226,18 @@ void CompilerMSL::emit_resources() } // Emit declarations for the specialization Metal function constants -void CompilerMSL::emit_specialization_constants() +void CompilerMSL::emit_specialization_constants_and_structs() { SpecializationConstant wg_x, wg_y, wg_z; uint32_t workgroup_size_id = get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); bool emitted = false; - for (auto &id : ir.ids) + unordered_set declared_structs; + + for (auto &id_ : ir.ids_for_constant_or_type) { + auto &id = ir.ids[id_]; + if (id.get_type() == TypeConstant) { auto &c = id.get(); @@ -2278,6 +2301,42 @@ void CompilerMSL::emit_specialization_constants() statement("constant ", variable_decl(type, name), " = ", constant_op_expression(c), ";"); emitted = true; } + else if (id.get_type() == TypeType) + { + // Output non-builtin interface structs. These include local function structs + // and structs nested within uniform and read-write buffers. + auto &type = id.get(); + uint32_t type_id = type.self; + + bool is_struct = (type.basetype == SPIRType::Struct) && type.array.empty(); + bool is_block = + has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock); + + bool is_builtin_block = is_block && is_builtin_type(type); + bool is_declarable_struct = is_struct && !is_builtin_block; + + // We'll declare this later. + if (stage_out_var_id && get(stage_out_var_id).basetype == type_id) + is_declarable_struct = false; + if (stage_in_var_id && get(stage_in_var_id).basetype == type_id) + is_declarable_struct = false; + + // Align and emit declarable structs...but avoid declaring each more than once. + if (is_declarable_struct && declared_structs.count(type_id) == 0) + { + if (emitted) + statement(""); + emitted = false; + + declared_structs.insert(type_id); + + if (has_decoration(type_id, DecorationCPacked)) + align_struct(type); + + // Make sure we declare the underlying struct type, and not the "decorated" type with pointers, etc. + emit_struct(get(type_id)); + } + } } if (emitted) @@ -3279,6 +3338,10 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &) if (arg_type.basetype == SPIRType::SampledImage && arg_type.image.dim != DimBuffer) decl += join(", thread const ", sampler_type(arg_type), " ", to_sampler_expression(arg.id)); + // Manufacture automatic swizzle arg. + if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(arg_type)) + decl += join(", constant uint32_t& ", to_swizzle_expression(arg.id)); + if (&arg != &func.arguments.back()) decl += ", "; } @@ -3654,22 +3717,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool // 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; - - auto *combined = maybe_get(img_var); - if (combined) - img_var = combined->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(img_var), SPIRType::Image)) + "]"; + farg_str += ", " + to_swizzle_expression(img); used_aux_buffer = true; } @@ -3723,12 +3771,38 @@ void CompilerMSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_id // Manufacture automatic sampler arg for SampledImage texture. string CompilerMSL::to_func_call_arg(uint32_t id) { - string arg_str = CompilerGLSL::to_func_call_arg(id); + string arg_str; + + auto *c = maybe_get(id); + if (c && !get(c->constant_type).array.empty()) + { + // If we are passing a constant array directly to a function for some reason, + // the callee will expect an argument in thread const address space + // (since we can only bind to arrays with references in MSL). + // To resolve this, we must emit a copy in this address space. + // This kind of code gen should be rare enough that performance is not a real concern. + // Inline the SPIR-V to avoid this kind of suboptimal codegen. + // + // We risk calling this inside a continue block (invalid code), + // so just create a thread local copy in the current function. + arg_str = join("_", id, "_array_copy"); + auto &constants = current_function->constant_arrays_needed_on_stack; + auto itr = find(begin(constants), end(constants), id); + if (itr == end(constants)) + { + force_recompile = true; + constants.push_back(id); + } + } + else + arg_str = CompilerGLSL::to_func_call_arg(id); // Manufacture automatic sampler arg if the arg is a SampledImage texture. auto &type = expression_type(id); if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer) arg_str += ", " + to_sampler_expression(id); + if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(type)) + arg_str += ", " + to_swizzle_expression(id); return arg_str; } @@ -3756,6 +3830,22 @@ string CompilerMSL::to_sampler_expression(uint32_t id) } } +string CompilerMSL::to_swizzle_expression(uint32_t id) +{ + auto *combined = maybe_get(id); + auto expr = to_expression(combined ? combined->image : id); + auto index = expr.find_first_of('['); + + if (index == string::npos) + return expr + swizzle_name_suffix; + else + { + auto image_expr = expr.substr(0, index); + auto array_expr = expr.substr(index); + return image_expr + swizzle_name_suffix + array_expr; + } +} + // Checks whether the ID is a row_major matrix that requires conversion before use bool CompilerMSL::is_non_native_row_major_matrix(uint32_t id) { @@ -4099,7 +4189,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in // index as the location. uint32_t CompilerMSL::get_ordered_member_location(uint32_t type_id, uint32_t index, uint32_t *comp) { - auto &m = ir.meta.at(type_id); + auto &m = ir.meta[type_id]; if (index < m.members.size()) { auto &dec = m.members[index]; @@ -4270,39 +4360,46 @@ string CompilerMSL::entry_point_args(bool append_comma) vector resources; - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t self, SPIRVariable &var) { + auto &id = ir.ids[self]; + auto &type = get_variable_data_type(var); + + uint32_t var_id = var.self; + + if ((var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || + var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) && + !is_hidden_variable(var)) { - auto &var = id.get(); - auto &type = get_variable_data_type(var); - - uint32_t var_id = var.self; - - if ((var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || - var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) && - !is_hidden_variable(var)) + if (type.basetype == SPIRType::SampledImage) { - if (type.basetype == SPIRType::SampledImage) - { - resources.push_back( - { &id, to_name(var_id), SPIRType::Image, get_metal_resource_index(var, SPIRType::Image) }); + resources.push_back( + { &id, to_name(var_id), SPIRType::Image, get_metal_resource_index(var, SPIRType::Image) }); - if (type.image.dim != DimBuffer && constexpr_samplers.count(var_id) == 0) - { - resources.push_back({ &id, to_sampler_expression(var_id), SPIRType::Sampler, - get_metal_resource_index(var, SPIRType::Sampler) }); - } - } - else if (constexpr_samplers.count(var_id) == 0) + if (type.image.dim != DimBuffer && constexpr_samplers.count(var_id) == 0) { - // constexpr samplers are not declared as resources. - resources.push_back( - { &id, to_name(var_id), type.basetype, get_metal_resource_index(var, type.basetype) }); + resources.push_back({ &id, to_sampler_expression(var_id), SPIRType::Sampler, + get_metal_resource_index(var, SPIRType::Sampler) }); } } + else if (constexpr_samplers.count(var_id) == 0) + { + // constexpr samplers are not declared as resources. + resources.push_back( + { &id, to_name(var_id), type.basetype, get_metal_resource_index(var, type.basetype) }); + } + + if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(type)) + { + auto &entry_func = this->get(ir.default_entry_point); + entry_func.fixup_hooks_in.push_back([this, &var, var_id]() { + auto &aux_type = expression_type(aux_buffer_id); + statement("constant uint32_t& ", to_swizzle_expression(var_id), " = ", to_name(aux_buffer_id), ".", + to_member_name(aux_type, k_aux_mbr_idx_swizzle_const), "[", + convert_to_string(get_metal_resource_index(var, SPIRType::Image)), "];"); + }); + } } - } + }); std::sort(resources.begin(), resources.end(), [](const Resource &lhs, const Resource &rhs) { return tie(lhs.basetype, lhs.index) < tie(rhs.basetype, rhs.index); @@ -4319,7 +4416,7 @@ string CompilerMSL::entry_point_args(bool append_comma) { case SPIRType::Struct: { - auto &m = ir.meta.at(type.self); + auto &m = ir.meta[type.self]; if (m.members.size() == 0) break; if (!type.array.empty()) @@ -4373,51 +4470,44 @@ string CompilerMSL::entry_point_args(bool append_comma) } // Builtin variables - for (auto &id : ir.ids) - { - if (id.get_type() == TypeVariable) + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + uint32_t var_id = var.self; + BuiltIn bi_type = ir.meta[var_id].decoration.builtin_type; + + // Don't emit SamplePosition as a separate parameter. In the entry + // point, we get that by calling get_sample_position() on the sample ID. + if (var.storage == StorageClassInput && is_builtin_variable(var)) { - auto &var = id.get(); - - uint32_t var_id = var.self; - BuiltIn bi_type = ir.meta[var_id].decoration.builtin_type; - - // Don't emit SamplePosition as a separate parameter. In the entry - // point, we get that by calling get_sample_position() on the sample ID. - if (var.storage == StorageClassInput && is_builtin_variable(var)) + if (bi_type == BuiltInSamplePosition) { - if (bi_type == BuiltInSamplePosition) - { - auto &entry_func = get(ir.default_entry_point); - entry_func.fixup_hooks_in.push_back([=]() { - statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = get_sample_position(", - to_expression(builtin_sample_id_id), ");"); - }); - } - else if (bi_type == BuiltInHelperInvocation) - { - if (msl_options.is_ios()) - SPIRV_CROSS_THROW("simd_is_helper_thread() is only supported on macOS."); - else if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 1)) - SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.1 on macOS."); + auto &entry_func = this->get(ir.default_entry_point); + entry_func.fixup_hooks_in.push_back([=]() { + statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = get_sample_position(", + to_expression(builtin_sample_id_id), ");"); + }); + } + else if (bi_type == BuiltInHelperInvocation) + { + if (msl_options.is_ios()) + SPIRV_CROSS_THROW("simd_is_helper_thread() is only supported on macOS."); + else if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 1)) + SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.1 on macOS."); - auto &entry_func = get(ir.default_entry_point); - entry_func.fixup_hooks_in.push_back([=]() { - statement(builtin_type_decl(bi_type), " ", to_expression(var_id), - " = simd_is_helper_thread();"); - }); - } - else - { - if (!ep_args.empty()) - ep_args += ", "; + auto &entry_func = this->get(ir.default_entry_point); + entry_func.fixup_hooks_in.push_back([=]() { + statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = simd_is_helper_thread();"); + }); + } + else + { + if (!ep_args.empty()) + ep_args += ", "; - ep_args += builtin_type_decl(bi_type) + " " + to_expression(var_id); - ep_args += " [[" + builtin_qualifier(bi_type) + "]]"; - } + ep_args += builtin_type_decl(bi_type) + " " + to_expression(var_id); + ep_args += " [[" + builtin_qualifier(bi_type) + "]]"; } } - } + }); // Vertex and instance index built-ins if (needs_vertex_idx_arg) @@ -4535,8 +4625,26 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) (storage == StorageClassFunction || storage == StorageClassGeneric)) { // If the argument is a pure value and not an opaque type, we will pass by value. - decl += " "; - decl += to_expression(name_id); + if (is_array(type)) + { + // We are receiving an array by value. This is problematic. + // We cannot be sure of the target address space since we are supposed to receive a copy, + // but this is not possible with MSL without some extra work. + // We will have to assume we're getting a reference in thread address space. + // If we happen to get a reference in constant address space, the caller must emit a copy and pass that. + // Thread const therefore becomes the only logical choice, since we cannot "create" a constant array from + // non-constant arrays, but we can create thread const from constant. + decl = string("thread const ") + decl; + decl += " (&"; + decl += to_expression(name_id); + decl += ")"; + decl += type_to_array_glsl(type); + } + else + { + decl += " "; + decl += to_expression(name_id); + } } else if (is_array(type) && !type_is_image) { @@ -4567,9 +4675,9 @@ string CompilerMSL::to_name(uint32_t id, bool allow_alias) const { if (current_function && (current_function->self == ir.default_entry_point)) { - string qual_name = ir.meta.at(id).decoration.qualified_alias; - if (!qual_name.empty()) - return qual_name; + auto *m = ir.find_meta(id); + if (m && !m->decoration.qualified_alias.empty()) + return m->decoration.qualified_alias; } return Compiler::to_name(id, allow_alias); } @@ -4602,49 +4710,273 @@ void CompilerMSL::replace_illegal_names() // FIXME: MSL and GLSL are doing two different things here. // Agree on convention and remove this override. static const unordered_set keywords = { - "kernel", "vertex", "fragment", "compute", "bias", + "kernel", + "vertex", + "fragment", + "compute", + "bias", + "assert", + "VARIABLE_TRACEPOINT", + "STATIC_DATA_TRACEPOINT", + "STATIC_DATA_TRACEPOINT_V", + "METAL_ALIGN", + "METAL_ASM", + "METAL_CONST", + "METAL_DEPRECATED", + "METAL_ENABLE_IF", + "METAL_FUNC", + "METAL_INTERNAL", + "METAL_NON_NULL_RETURN", + "METAL_NORETURN", + "METAL_NOTHROW", + "METAL_PURE", + "METAL_UNAVAILABLE", + "METAL_IMPLICIT", + "METAL_EXPLICIT", + "METAL_CONST_ARG", + "METAL_ARG_UNIFORM", + "METAL_ZERO_ARG", + "METAL_VALID_LOD_ARG", + "METAL_VALID_LEVEL_ARG", + "METAL_VALID_STORE_ORDER", + "METAL_VALID_LOAD_ORDER", + "METAL_VALID_COMPARE_EXCHANGE_FAILURE_ORDER", + "METAL_COMPATIBLE_COMPARE_EXCHANGE_ORDERS", + "METAL_VALID_RENDER_TARGET", + "is_function_constant_defined", + "CHAR_BIT", + "SCHAR_MAX", + "SCHAR_MIN", + "UCHAR_MAX", + "CHAR_MAX", + "CHAR_MIN", + "USHRT_MAX", + "SHRT_MAX", + "SHRT_MIN", + "UINT_MAX", + "INT_MAX", + "INT_MIN", + "FLT_DIG", + "FLT_MANT_DIG", + "FLT_MAX_10_EXP", + "FLT_MAX_EXP", + "FLT_MIN_10_EXP", + "FLT_MIN_EXP", + "FLT_RADIX", + "FLT_MAX", + "FLT_MIN", + "FLT_EPSILON", + "FP_ILOGB0", + "FP_ILOGBNAN", + "MAXFLOAT", + "HUGE_VALF", + "INFINITY", + "NAN", + "M_E_F", + "M_LOG2E_F", + "M_LOG10E_F", + "M_LN2_F", + "M_LN10_F", + "M_PI_F", + "M_PI_2_F", + "M_PI_4_F", + "M_1_PI_F", + "M_2_PI_F", + "M_2_SQRTPI_F", + "M_SQRT2_F", + "M_SQRT1_2_F", + "HALF_DIG", + "HALF_MANT_DIG", + "HALF_MAX_10_EXP", + "HALF_MAX_EXP", + "HALF_MIN_10_EXP", + "HALF_MIN_EXP", + "HALF_RADIX", + "HALF_MAX", + "HALF_MIN", + "HALF_EPSILON", + "MAXHALF", + "HUGE_VALH", + "M_E_H", + "M_LOG2E_H", + "M_LOG10E_H", + "M_LN2_H", + "M_LN10_H", + "M_PI_H", + "M_PI_2_H", + "M_PI_4_H", + "M_1_PI_H", + "M_2_PI_H", + "M_2_SQRTPI_H", + "M_SQRT2_H", + "M_SQRT1_2_H", + "DBL_DIG", + "DBL_MANT_DIG", + "DBL_MAX_10_EXP", + "DBL_MAX_EXP", + "DBL_MIN_10_EXP", + "DBL_MIN_EXP", + "DBL_RADIX", + "DBL_MAX", + "DBL_MIN", + "DBL_EPSILON", + "HUGE_VAL", + "M_E", + "M_LOG2E", + "M_LOG10E", + "M_LN2", + "M_LN10", + "M_PI", + "M_PI_2", + "M_PI_4", + "M_1_PI", + "M_2_PI", + "M_2_SQRTPI", + "M_SQRT2", + "M_SQRT1_2", }; static const unordered_set illegal_func_names = { "main", "saturate", + "assert", + "VARIABLE_TRACEPOINT", + "STATIC_DATA_TRACEPOINT", + "STATIC_DATA_TRACEPOINT_V", + "METAL_ALIGN", + "METAL_ASM", + "METAL_CONST", + "METAL_DEPRECATED", + "METAL_ENABLE_IF", + "METAL_FUNC", + "METAL_INTERNAL", + "METAL_NON_NULL_RETURN", + "METAL_NORETURN", + "METAL_NOTHROW", + "METAL_PURE", + "METAL_UNAVAILABLE", + "METAL_IMPLICIT", + "METAL_EXPLICIT", + "METAL_CONST_ARG", + "METAL_ARG_UNIFORM", + "METAL_ZERO_ARG", + "METAL_VALID_LOD_ARG", + "METAL_VALID_LEVEL_ARG", + "METAL_VALID_STORE_ORDER", + "METAL_VALID_LOAD_ORDER", + "METAL_VALID_COMPARE_EXCHANGE_FAILURE_ORDER", + "METAL_COMPATIBLE_COMPARE_EXCHANGE_ORDERS", + "METAL_VALID_RENDER_TARGET", + "is_function_constant_defined", + "CHAR_BIT", + "SCHAR_MAX", + "SCHAR_MIN", + "UCHAR_MAX", + "CHAR_MAX", + "CHAR_MIN", + "USHRT_MAX", + "SHRT_MAX", + "SHRT_MIN", + "UINT_MAX", + "INT_MAX", + "INT_MIN", + "FLT_DIG", + "FLT_MANT_DIG", + "FLT_MAX_10_EXP", + "FLT_MAX_EXP", + "FLT_MIN_10_EXP", + "FLT_MIN_EXP", + "FLT_RADIX", + "FLT_MAX", + "FLT_MIN", + "FLT_EPSILON", + "FP_ILOGB0", + "FP_ILOGBNAN", + "MAXFLOAT", + "HUGE_VALF", + "INFINITY", + "NAN", + "M_E_F", + "M_LOG2E_F", + "M_LOG10E_F", + "M_LN2_F", + "M_LN10_F", + "M_PI_F", + "M_PI_2_F", + "M_PI_4_F", + "M_1_PI_F", + "M_2_PI_F", + "M_2_SQRTPI_F", + "M_SQRT2_F", + "M_SQRT1_2_F", + "HALF_DIG", + "HALF_MANT_DIG", + "HALF_MAX_10_EXP", + "HALF_MAX_EXP", + "HALF_MIN_10_EXP", + "HALF_MIN_EXP", + "HALF_RADIX", + "HALF_MAX", + "HALF_MIN", + "HALF_EPSILON", + "MAXHALF", + "HUGE_VALH", + "M_E_H", + "M_LOG2E_H", + "M_LOG10E_H", + "M_LN2_H", + "M_LN10_H", + "M_PI_H", + "M_PI_2_H", + "M_PI_4_H", + "M_1_PI_H", + "M_2_PI_H", + "M_2_SQRTPI_H", + "M_SQRT2_H", + "M_SQRT1_2_H", + "DBL_DIG", + "DBL_MANT_DIG", + "DBL_MAX_10_EXP", + "DBL_MAX_EXP", + "DBL_MIN_10_EXP", + "DBL_MIN_EXP", + "DBL_RADIX", + "DBL_MAX", + "DBL_MIN", + "DBL_EPSILON", + "HUGE_VAL", + "M_E", + "M_LOG2E", + "M_LOG10E", + "M_LN2", + "M_LN10", + "M_PI", + "M_PI_2", + "M_PI_4", + "M_1_PI", + "M_2_PI", + "M_2_SQRTPI", + "M_SQRT2", + "M_SQRT1_2", }; - for (auto &id : ir.ids) - { - switch (id.get_type()) - { - case TypeVariable: - { - auto &dec = ir.meta[id.get_id()].decoration; - if (keywords.find(dec.alias) != end(keywords)) - dec.alias += "0"; + ir.for_each_typed_id([&](uint32_t self, SPIRVariable &) { + auto &dec = ir.meta[self].decoration; + if (keywords.find(dec.alias) != end(keywords)) + dec.alias += "0"; + }); - break; - } + ir.for_each_typed_id([&](uint32_t self, SPIRFunction &) { + auto &dec = ir.meta[self].decoration; + if (illegal_func_names.find(dec.alias) != end(illegal_func_names)) + dec.alias += "0"; + }); - case TypeFunction: - { - auto &dec = ir.meta[id.get_id()].decoration; - if (illegal_func_names.find(dec.alias) != end(illegal_func_names)) - dec.alias += "0"; - - break; - } - - case TypeType: - { - for (auto &mbr_dec : ir.meta[id.get_id()].members) - if (keywords.find(mbr_dec.alias) != end(keywords)) - mbr_dec.alias += "0"; - - break; - } - - default: - break; - } - } + ir.for_each_typed_id([&](uint32_t self, SPIRType &) { + for (auto &mbr_dec : ir.meta[self].members) + if (keywords.find(mbr_dec.alias) != end(keywords)) + mbr_dec.alias += "0"; + }); for (auto &entry : ir.entry_points) { diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index a0058e33e..f4520ddc0 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -168,6 +168,10 @@ public: bool disable_rasterization = false; bool swizzle_texture_samples = false; + // Fragment output in MSL must have at least as many components as the render pass. + // Add support to explicit pad out components. + bool pad_fragment_output_components = false; + bool is_ios() { return platform == iOS; @@ -312,6 +316,10 @@ public: // The remapped sampler must not be an array of samplers. void remap_constexpr_sampler(uint32_t id, const MSLConstexprSampler &sampler); + // If using CompilerMSL::Options::pad_fragment_output_components, override the number of components we expect + // to use for a particular location. The default is 4 if number of components is not overridden. + void set_fragment_output_components(uint32_t location, uint32_t components); + protected: void emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op); void emit_instruction(const Instruction &instr) override; @@ -380,7 +388,7 @@ protected: void emit_custom_functions(); void emit_resources(); - void emit_specialization_constants(); + void emit_specialization_constants_and_structs(); void emit_interface_block(uint32_t ib_var_id); bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs); void add_convert_row_major_matrix_function(uint32_t cols, uint32_t rows); @@ -390,6 +398,7 @@ protected: std::string to_qualified_member_name(const SPIRType &type, uint32_t index); std::string ensure_valid_name(std::string name, std::string pfx); std::string to_sampler_expression(uint32_t id); + std::string to_swizzle_expression(uint32_t id); std::string builtin_qualifier(spv::BuiltIn builtin); std::string builtin_type_decl(spv::BuiltIn builtin); std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma); @@ -427,6 +436,7 @@ protected: Options msl_options; std::set spv_function_implementations; std::unordered_map vtx_attrs_by_location; + std::unordered_map fragment_output_components; std::unordered_map struct_member_padding; std::set pragma_lines; std::set typedef_lines; @@ -444,11 +454,15 @@ protected: std::string stage_in_var_name = "in"; std::string stage_out_var_name = "out"; std::string sampler_name_suffix = "Smplr"; + std::string swizzle_name_suffix = "Swzl"; spv::Op previous_instruction_opcode = spv::OpNop; std::unordered_map constexpr_samplers; std::vector buffer_arrays; + uint32_t get_target_components_for_fragment_location(uint32_t location) const; + uint32_t build_extended_vector_type(uint32_t type_id, uint32_t components); + // OpcodeHandler that handles several MSL preprocessing operations. struct OpCodePreprocessor : OpcodeHandler { diff --git a/3rdparty/spirv-cross/spirv_parser.cpp b/3rdparty/spirv-cross/spirv_parser.cpp index 205305ddb..2f76144e8 100644 --- a/3rdparty/spirv-cross/spirv_parser.cpp +++ b/3rdparty/spirv-cross/spirv_parser.cpp @@ -1063,8 +1063,11 @@ bool Parser::types_are_logically_equivalent(const SPIRType &a, const SPIRType &b bool Parser::variable_storage_is_aliased(const SPIRVariable &v) const { auto &type = get(v.basetype); + + auto *type_meta = ir.find_meta(type.self); + bool ssbo = v.storage == StorageClassStorageBuffer || - ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); + (type_meta && type_meta->decoration.decoration_flags.get(DecorationBufferBlock)); bool image = type.basetype == SPIRType::Image; bool counter = type.basetype == SPIRType::AtomicCounter; diff --git a/3rdparty/spirv-cross/spirv_parser.hpp b/3rdparty/spirv-cross/spirv_parser.hpp index 81c54987b..cc153152b 100644 --- a/3rdparty/spirv-cross/spirv_parser.hpp +++ b/3rdparty/spirv-cross/spirv_parser.hpp @@ -47,7 +47,8 @@ private: template T &set(uint32_t id, P &&... args) { - auto &var = variant_set(ir.ids.at(id), std::forward

(args)...); + ir.add_typed_id(static_cast(T::type), id); + auto &var = variant_set(ir.ids[id], std::forward

(args)...); var.self = id; return var; } @@ -55,13 +56,13 @@ private: template T &get(uint32_t id) { - return variant_get(ir.ids.at(id)); + return variant_get(ir.ids[id]); } template T *maybe_get(uint32_t id) { - if (ir.ids.at(id).get_type() == T::type) + if (ir.ids[id].get_type() == static_cast(T::type)) return &get(id); else return nullptr; @@ -70,13 +71,13 @@ private: template const T &get(uint32_t id) const { - return variant_get(ir.ids.at(id)); + return variant_get(ir.ids[id]); } template const T *maybe_get(uint32_t id) const { - if (ir.ids.at(id).get_type() == T::type) + if (ir.ids[id].get_type() == T::type) return &get(id); else return nullptr; diff --git a/3rdparty/spirv-cross/spirv_reflect.cpp b/3rdparty/spirv-cross/spirv_reflect.cpp index 003073150..75f7a3083 100644 --- a/3rdparty/spirv-cross/spirv_reflect.cpp +++ b/3rdparty/spirv-cross/spirv_reflect.cpp @@ -264,18 +264,11 @@ string CompilerReflection::compile() void CompilerReflection::emit_types() { bool emitted_open_tag = false; - for (auto &id : ir.ids) - { - auto idType = id.get_type(); - if (idType == TypeType) - { - auto &type = id.get(); - if (type.basetype == SPIRType::Struct && !type.pointer && type.array.empty()) - { - emit_type(type, emitted_open_tag); - } - } - } + + ir.for_each_typed_id([&](uint32_t, SPIRType &type) { + if (type.basetype == SPIRType::Struct && !type.pointer && type.array.empty()) + emit_type(type, emitted_open_tag); + }); if (emitted_open_tag) { @@ -565,9 +558,16 @@ void CompilerReflection::emit_specialization_constants() string CompilerReflection::to_member_name(const SPIRType &type, uint32_t index) const { - auto &memb = ir.meta[type.self].members; - if (index < memb.size() && !memb[index].alias.empty()) - return memb[index].alias; + auto *type_meta = ir.find_meta(type.self); + + if (type_meta) + { + auto &memb = type_meta->members; + if (index < memb.size() && !memb[index].alias.empty()) + return memb[index].alias; + else + return join("_m", index); + } else return join("_m", index); } diff --git a/3rdparty/spirv-cross/test_shaders.py b/3rdparty/spirv-cross/test_shaders.py index 045c2551b..92fe5c4ae 100755 --- a/3rdparty/spirv-cross/test_shaders.py +++ b/3rdparty/spirv-cross/test_shaders.py @@ -129,7 +129,7 @@ def validate_shader_msl(shader, opt): raise except subprocess.CalledProcessError: print('Error compiling Metal shader: ' + msl_path) - sys.exit(1) + raise RuntimeError('Failed to compile Metal shader') def cross_compile_msl(shader, spirv, opt): spirv_path = create_temporary() @@ -152,6 +152,8 @@ def cross_compile_msl(shader, spirv, opt): msl_args.append('--msl-swizzle-texture-samples') if '.ios.' in shader: msl_args.append('--msl-ios') + if '.pad-fragment.' in shader: + msl_args.append('--msl-pad-fragment-output') subprocess.check_call(msl_args) @@ -201,12 +203,15 @@ def validate_shader_hlsl(shader, force_no_external_validation): subprocess.check_call(['fxc', '-nologo', shader_model_hlsl(shader), win_path]) except OSError as oe: if (oe.errno != errno.ENOENT): # Ignore not found errors + print('Failed to run FXC.') + ignore_fxc = True raise else: + print('Could not find FXC.') ignore_fxc = True except subprocess.CalledProcessError: print('Failed compiling HLSL shader:', shader, 'with FXC.') - sys.exit(1) + raise RuntimeError('Failed compiling HLSL shader') def shader_to_sm(shader): if '.sm60.' in shader: @@ -382,7 +387,8 @@ def regression_check_reflect(shader, json_file, update, keep, opt): # Otherwise, fail the test. Keep the shader file around so we can inspect. if not keep: remove_file(json_file) - sys.exit(1) + + raise RuntimeError('Does not match reference') else: remove_file(json_file) else: @@ -417,7 +423,7 @@ def regression_check(shader, glsl, update, keep, opt): # Otherwise, fail the test. Keep the shader file around so we can inspect. if not keep: remove_file(glsl) - sys.exit(1) + raise RuntimeError('Does not match reference') else: remove_file(glsl) else: @@ -533,14 +539,18 @@ def test_shader_reflect(stats, shader, update, keep, opt): remove_file(spirv) def test_shader_file(relpath, stats, shader_dir, update, keep, opt, force_no_external_validation, backend): - if backend == 'msl': - test_shader_msl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation) - elif backend == 'hlsl': - test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation) - elif backend == 'reflect': - test_shader_reflect(stats, (shader_dir, relpath), update, keep, opt) - else: - test_shader(stats, (shader_dir, relpath), update, keep, opt) + try: + if backend == 'msl': + test_shader_msl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation) + elif backend == 'hlsl': + test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation) + elif backend == 'reflect': + test_shader_reflect(stats, (shader_dir, relpath), update, keep, opt) + else: + test_shader(stats, (shader_dir, relpath), update, keep, opt) + return None + except Exception as e: + return e def test_shaders_helper(stats, backend, args): all_files = [] @@ -555,17 +565,27 @@ def test_shaders_helper(stats, backend, args): # at this point we need to switch to explicit arguments if args.parallel: pool = multiprocessing.Pool(multiprocessing.cpu_count()) - pool.map(partial(test_shader_file, - stats = stats, - shader_dir = args.folder, - update = args.update, - keep = args.keep, - opt = args.opt, - force_no_external_validation = args.force_no_external_validation, - backend = backend), all_files) + + results = [] + for f in all_files: + results.append(pool.apply_async(test_shader_file, + args = (f, stats, + args.folder, args.update, args.keep, args.opt, args.force_no_external_validation, + backend))) + + for res in results: + error = res.get() + if error is not None: + pool.close() + pool.join() + print('Error:', error) + sys.exit(1) else: for i in all_files: - test_shader_file(i, stats, args.folder, args.update, args.keep, args.opt, args.force_no_external_validation, backend) + e = test_shader_file(i, stats, args.folder, args.update, args.keep, args.opt, args.force_no_external_validation, backend) + if e is not None: + print('Error:', e) + sys.exit(1) def test_shaders(backend, args): if args.malisc: