From 278a4c80edfeb90ba1ca50ce5f16c4ee39f27f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Fri, 4 Mar 2022 09:09:08 +0100 Subject: HLSL: Add support for gl_HelperInvocation --- spirv_hlsl.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 646fce33..ffbbfd97 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -728,6 +728,11 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() // Handled specially. break; + case BuiltInHelperInvocation: + if (hlsl_options.shader_model < 50 || (get_entry_point().model != ExecutionModelFragment && get_entry_point().model != ExecutionModelGLCompute)) + SPIRV_CROSS_THROW("Helper Invocation input is only supported in PS 5.0 or higher."); + break; + case BuiltInClipDistance: // HLSL is a bit weird here, use SV_ClipDistance0, SV_ClipDistance1 and so on with vectors. for (uint32_t clip = 0; clip < clip_distance_count; clip += 4) @@ -984,6 +989,8 @@ std::string CompilerHLSL::builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClas return "WaveGetLaneIndex()"; case BuiltInSubgroupSize: return "WaveGetLaneCount()"; + case BuiltInHelperInvocation: + return "IsHelperLane()"; default: return CompilerGLSL::builtin_to_glsl(builtin, storage); @@ -1103,6 +1110,11 @@ void CompilerHLSL::emit_builtin_variables() type = "uint4"; break; + case BuiltInHelperInvocation: + if (hlsl_options.shader_model < 50) + SPIRV_CROSS_THROW("Need SM 5.0 for Helper Invocation."); + break; + case BuiltInClipDistance: array_size = clip_distance_count; type = "float"; @@ -2521,6 +2533,7 @@ void CompilerHLSL::emit_hlsl_entry_point() case BuiltInPointCoord: case BuiltInSubgroupSize: case BuiltInSubgroupLocalInvocationId: + case BuiltInHelperInvocation: break; case BuiltInSubgroupEqMask: -- cgit v1.2.3 From 005c14ad6ab76ba1d770c9384a78b77e72382f06 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 4 Mar 2022 10:54:31 +0100 Subject: HLSL: Implement HelperInvocationEXT. It is volatile by nature and must not be forwarded. --- spirv_glsl.cpp | 2 ++ spirv_hlsl.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 4c465133..35e98912 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -12850,6 +12850,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) if (!options.vulkan_semantics) SPIRV_CROSS_THROW("GL_EXT_demote_to_helper_invocation is only supported in Vulkan GLSL."); require_extension_internal("GL_EXT_demote_to_helper_invocation"); + // Helper lane state with demote is volatile by nature. + // Do not forward this. emit_op(ops[0], ops[1], "helperInvocationEXT()", false); break; diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index ffbbfd97..52ccedf2 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -5603,7 +5603,12 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) } case OpIsHelperInvocationEXT: - SPIRV_CROSS_THROW("helperInvocationEXT() is not supported in HLSL."); + if (hlsl_options.shader_model < 50 || (get_entry_point().model != ExecutionModelFragment && get_entry_point().model != ExecutionModelGLCompute)) + SPIRV_CROSS_THROW("Helper Invocation input is only supported in PS 5.0 or higher."); + // Helper lane state with demote is volatile by nature. + // Do not forward this. + emit_op(ops[0], ops[1], "IsHelperLane()", false); + break; case OpBeginInvocationInterlockEXT: case OpEndInvocationInterlockEXT: -- cgit v1.2.3 From 5d9fc2d90361a37b4a3f2ad7962fbb9d02cd33fc Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 4 Mar 2022 10:58:40 +0100 Subject: HLSL: Add test for HelperInvocation. --- .../frag/helper-invocation.fxconly.nofxc.frag | 26 ++++++++++++++++++++++ .../frag/helper-invocation.fxconly.nofxc.frag | 11 +++++++++ 2 files changed, 37 insertions(+) create mode 100644 reference/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag create mode 100644 shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag diff --git a/reference/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag b/reference/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag new file mode 100644 index 00000000..ad61b21e --- /dev/null +++ b/reference/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag @@ -0,0 +1,26 @@ +static float FragColor; + +struct SPIRV_Cross_Input +{ +}; + +struct SPIRV_Cross_Output +{ + float FragColor : SV_Target0; +}; + +void frag_main() +{ + FragColor = float(IsHelperLane()); + discard; + bool _16 = IsHelperLane(); + FragColor = float(_16); +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor = FragColor; + return stage_output; +} diff --git a/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag b/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag new file mode 100644 index 00000000..6f70c772 --- /dev/null +++ b/shaders-hlsl-no-opt/frag/helper-invocation.fxconly.nofxc.frag @@ -0,0 +1,11 @@ +#version 450 +#extension GL_EXT_demote_to_helper_invocation : require + +layout(location = 0) out float FragColor; + +void main() +{ + FragColor = float(gl_HelperInvocation); + demote; + FragColor = float(helperInvocationEXT()); +} -- cgit v1.2.3 From 476b6541fab11d353d504ca0d51369f35a5f07b7 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 4 Mar 2022 11:05:21 +0100 Subject: Remove forwardable bit in SPIRVariable. Was never really used for anything. It's always true. --- spirv_common.hpp | 1 - spirv_glsl.cpp | 4 ++-- spirv_hlsl.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/spirv_common.hpp b/spirv_common.hpp index f568d7dc..4aaa7148 100644 --- a/spirv_common.hpp +++ b/spirv_common.hpp @@ -1072,7 +1072,6 @@ struct SPIRVariable : IVariant // Temporaries which can remain forwarded as long as this variable is not modified. SmallVector dependees; - bool forwardable = true; bool deferred_declaration = false; bool phi_variable = false; diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 35e98912..721741c3 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -9585,7 +9585,7 @@ bool CompilerGLSL::should_forward(uint32_t id) const // This is important because otherwise we'll get local sampler copies (highp sampler2D foo = bar) that are invalid in OpenGL GLSL auto *var = maybe_get(id); - if (var && var->forwardable) + if (var) return true; // For debugging emit temporary variables for all expressions @@ -12089,7 +12089,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) pure = false; } - if (var && var->forwardable) + if (var) { bool forward = forced_temporaries.find(id) == end(forced_temporaries); auto &e = emit_op(result_type, id, imgexpr, forward); diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 52ccedf2..253d6ad0 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -5359,7 +5359,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) image_format_to_components(get(var->basetype).image.format), imgexpr); } - if (var && var->forwardable) + if (var) { bool forward = forced_temporaries.find(id) == end(forced_temporaries); auto &e = emit_op(result_type, id, imgexpr, forward); -- cgit v1.2.3 From 93b0dc7718af42f822f034671637255a867008a0 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 4 Mar 2022 11:08:55 +0100 Subject: Consider Volatile in should_forward(). Never forward these variables. --- spirv_glsl.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 721741c3..52cef4ec 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -9586,7 +9586,10 @@ bool CompilerGLSL::should_forward(uint32_t id) const auto *var = maybe_get(id); if (var) - return true; + { + // Never forward volatile variables, e.g. SPIR-V 1.6 IsHelperInvocation. + return !has_decoration(id, DecorationVolatile); + } // For debugging emit temporary variables for all expressions if (options.force_temporary) @@ -9599,6 +9602,12 @@ bool CompilerGLSL::should_forward(uint32_t id) const if (expr && expr->expression_dependencies.size() >= max_expression_dependencies) return false; + if (expr && expr->loaded_from && has_decoration(expr->loaded_from, DecorationVolatile)) + { + // Never forward volatile variables. + return false; + } + // Immutable expression can always be forwarded. if (is_immutable(id)) return true; -- cgit v1.2.3 From 15d29f00e286e5e071547bb537707b16f68df1c4 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 4 Mar 2022 11:19:33 +0100 Subject: Add test for SPIR-V 1.6 Volatile HelperInvocation. --- ...tile-helper-invocation.fxconly.nofxc.spv16.frag | 29 ++++++++++++++++++++ .../volatile-helper-invocation.msl23.spv16.frag | 24 +++++++++++++++++ ...ile-helper-invocation.vk.nocompat.spv16.frag.vk | 16 +++++++++++ ...tile-helper-invocation.fxconly.nofxc.spv16.frag | 11 ++++++++ .../volatile-helper-invocation.msl23.spv16.frag | 11 ++++++++ ...latile-helper-invocation.vk.nocompat.spv16.frag | 11 ++++++++ test_shaders.py | 31 ++++++++++++++++++---- 7 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 reference/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag create mode 100644 reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag create mode 100644 reference/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag.vk create mode 100644 shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag create mode 100644 shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag create mode 100644 shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag diff --git a/reference/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag b/reference/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag new file mode 100644 index 00000000..1311c863 --- /dev/null +++ b/reference/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag @@ -0,0 +1,29 @@ +static float FragColor; + +struct SPIRV_Cross_Input +{ +}; + +struct SPIRV_Cross_Output +{ + float FragColor : SV_Target0; +}; + +void frag_main() +{ + bool _12 = IsHelperLane(); + float _15 = float(_12); + FragColor = _15; + discard; + bool _16 = IsHelperLane(); + float _17 = float(_16); + FragColor = _17; +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor = FragColor; + return stage_output; +} diff --git a/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag b/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag new file mode 100644 index 00000000..562cddaa --- /dev/null +++ b/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag @@ -0,0 +1,24 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float FragColor [[color(0)]]; +}; + +fragment main0_out main0() +{ + main0_out out = {}; + bool gl_HelperInvocation = simd_is_helper_thread(); + bool _12 = gl_HelperInvocation; + float _15 = float(_12); + out.FragColor = _15; + discard_fragment(); + bool _16 = gl_HelperInvocation; + float _17 = float(_16); + out.FragColor = _17; + return out; +} + diff --git a/reference/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag.vk b/reference/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag.vk new file mode 100644 index 00000000..73b0f9b0 --- /dev/null +++ b/reference/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag.vk @@ -0,0 +1,16 @@ +#version 450 +#extension GL_EXT_demote_to_helper_invocation : require + +layout(location = 0) out float FragColor; + +void main() +{ + bool _12 = gl_HelperInvocation; + float _15 = float(_12); + FragColor = _15; + demote; + bool _16 = gl_HelperInvocation; + float _17 = float(_16); + FragColor = _17; +} + diff --git a/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag b/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag new file mode 100644 index 00000000..9a8d9d20 --- /dev/null +++ b/shaders-hlsl-no-opt/frag/volatile-helper-invocation.fxconly.nofxc.spv16.frag @@ -0,0 +1,11 @@ +#version 450 +#extension GL_EXT_demote_to_helper_invocation : require + +layout(location = 0) out float FragColor; + +void main() +{ + FragColor = float(gl_HelperInvocation); + demote; + FragColor = float(gl_HelperInvocation); +} diff --git a/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag b/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag new file mode 100644 index 00000000..9a8d9d20 --- /dev/null +++ b/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag @@ -0,0 +1,11 @@ +#version 450 +#extension GL_EXT_demote_to_helper_invocation : require + +layout(location = 0) out float FragColor; + +void main() +{ + FragColor = float(gl_HelperInvocation); + demote; + FragColor = float(gl_HelperInvocation); +} diff --git a/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag b/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag new file mode 100644 index 00000000..9a8d9d20 --- /dev/null +++ b/shaders-no-opt/vulkan/frag/volatile-helper-invocation.vk.nocompat.spv16.frag @@ -0,0 +1,11 @@ +#version 450 +#extension GL_EXT_demote_to_helper_invocation : require + +layout(location = 0) out float FragColor; + +void main() +{ + FragColor = float(gl_HelperInvocation); + demote; + FragColor = float(gl_HelperInvocation); +} diff --git a/test_shaders.py b/test_shaders.py index 49038939..2726ae75 100755 --- a/test_shaders.py +++ b/test_shaders.py @@ -192,8 +192,18 @@ def cross_compile_msl(shader, spirv, opt, iterations, paths): spirv_path = create_temporary() msl_path = create_temporary(os.path.basename(shader)) + spirv_16 = '.spv16.' in shader spirv_14 = '.spv14.' in shader - spirv_env = 'vulkan1.1spv1.4' if spirv_14 else 'vulkan1.1' + + if spirv_16: + spirv_env = 'spv1.6' + glslang_env = 'spirv1.6' + elif spirv_14: + spirv_env = 'vulkan1.1spv1.4' + glslang_env = 'spirv1.4' + else: + spirv_env = 'vulkan1.1' + glslang_env = 'vulkan1.1' spirv_cmd = [paths.spirv_as, '--target-env', spirv_env, '-o', spirv_path, shader] if '.preserve.' in shader: @@ -202,7 +212,6 @@ def cross_compile_msl(shader, spirv, opt, iterations, paths): if spirv: subprocess.check_call(spirv_cmd) else: - glslang_env = 'spirv1.4' if spirv_14 else 'vulkan1.1' subprocess.check_call([paths.glslang, '--amb' ,'--target-env', glslang_env, '-V', '-o', spirv_path, shader]) if opt and (not shader_is_invalid_spirv(shader)): @@ -442,8 +451,19 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation, iterati spirv_path = create_temporary() hlsl_path = create_temporary(os.path.basename(shader)) + spirv_16 = '.spv16.' in shader spirv_14 = '.spv14.' in shader - spirv_env = 'vulkan1.1spv1.4' if spirv_14 else 'vulkan1.1' + + if spirv_16: + spirv_env = 'spv1.6' + glslang_env = 'spirv1.6' + elif spirv_14: + spirv_env = 'vulkan1.1spv1.4' + glslang_env = 'spirv1.4' + else: + spirv_env = 'vulkan1.1' + glslang_env = 'vulkan1.1' + spirv_cmd = [paths.spirv_as, '--target-env', spirv_env, '-o', spirv_path, shader] if '.preserve.' in shader: spirv_cmd.append('--preserve-numeric-ids') @@ -451,7 +471,6 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation, iterati if spirv: subprocess.check_call(spirv_cmd) else: - glslang_env = 'spirv1.4' if spirv_14 else 'vulkan1.1' subprocess.check_call([paths.glslang, '--amb', '--target-env', glslang_env, '-V', '-o', spirv_path, shader]) if opt and (not shader_is_invalid_spirv(hlsl_path)): @@ -526,10 +545,13 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl spirv_14 = '.spv14.' in shader if spirv_16: spirv_env = 'spv1.6' + glslang_env = 'spirv1.6' elif spirv_14: spirv_env = 'vulkan1.1spv1.4' + glslang_env = 'spirv1.4' else: spirv_env = 'vulkan1.1' + glslang_env = 'vulkan1.1' if vulkan or spirv: vulkan_glsl_path = create_temporary('vk' + os.path.basename(shader)) @@ -541,7 +563,6 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl if spirv: subprocess.check_call(spirv_cmd) else: - glslang_env = 'spirv1.4' if spirv_14 else 'vulkan1.1' subprocess.check_call([paths.glslang, '--amb', '--target-env', glslang_env, '-V', '-o', spirv_path, shader]) if opt and (not invalid_spirv): -- cgit v1.2.3 From b192b8887a5f0d53c8ebd66407346c52f82f075b Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 4 Mar 2022 11:46:35 +0100 Subject: MSL: Consider that gl_IsHelperInvocation can be Volatile. Just emit simd_is_helper_thread() directly. --- .../shaders-msl/frag/helper-invocation.msl21.frag | 3 +-- .../volatile-helper-invocation.msl23.spv16.frag | 5 ++--- .../shaders-msl/frag/helper-invocation.msl21.frag | 7 +++--- spirv_msl.cpp | 26 +++++++++++++--------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/reference/opt/shaders-msl/frag/helper-invocation.msl21.frag b/reference/opt/shaders-msl/frag/helper-invocation.msl21.frag index a833fa08..9d876df1 100644 --- a/reference/opt/shaders-msl/frag/helper-invocation.msl21.frag +++ b/reference/opt/shaders-msl/frag/helper-invocation.msl21.frag @@ -16,9 +16,8 @@ struct main0_in fragment main0_out main0(main0_in in [[stage_in]], texture2d uSampler [[texture(0)]], sampler uSamplerSmplr [[sampler(0)]]) { main0_out out = {}; - bool gl_HelperInvocation = simd_is_helper_thread(); float4 _52; - if (!gl_HelperInvocation) + if (!simd_is_helper_thread()) { _52 = uSampler.sample(uSamplerSmplr, in.vUV, level(0.0)); } diff --git a/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag b/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag index 562cddaa..eef92efe 100644 --- a/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag +++ b/reference/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag @@ -11,12 +11,11 @@ struct main0_out fragment main0_out main0() { main0_out out = {}; - bool gl_HelperInvocation = simd_is_helper_thread(); - bool _12 = gl_HelperInvocation; + bool _12 = simd_is_helper_thread(); float _15 = float(_12); out.FragColor = _15; discard_fragment(); - bool _16 = gl_HelperInvocation; + bool _16 = simd_is_helper_thread(); float _17 = float(_16); out.FragColor = _17; return out; diff --git a/reference/shaders-msl/frag/helper-invocation.msl21.frag b/reference/shaders-msl/frag/helper-invocation.msl21.frag index 7cf97a25..36d14239 100644 --- a/reference/shaders-msl/frag/helper-invocation.msl21.frag +++ b/reference/shaders-msl/frag/helper-invocation.msl21.frag @@ -16,10 +16,10 @@ struct main0_in }; static inline __attribute__((always_inline)) -float4 foo(thread bool& gl_HelperInvocation, texture2d uSampler, sampler uSamplerSmplr, thread float2& vUV) +float4 foo(texture2d uSampler, sampler uSamplerSmplr, thread float2& vUV) { float4 color; - if (!gl_HelperInvocation) + if (!simd_is_helper_thread()) { color = uSampler.sample(uSamplerSmplr, vUV, level(0.0)); } @@ -33,8 +33,7 @@ float4 foo(thread bool& gl_HelperInvocation, texture2d uSampler, sampler fragment main0_out main0(main0_in in [[stage_in]], texture2d uSampler [[texture(0)]], sampler uSamplerSmplr [[sampler(0)]]) { main0_out out = {}; - bool gl_HelperInvocation = simd_is_helper_thread(); - out.FragColor = foo(gl_HelperInvocation, uSampler, uSamplerSmplr, in.vUV); + out.FragColor = foo(uSampler, uSamplerSmplr, in.vUV); return out; } diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 4eeb3b7f..8ea27d5f 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -1548,6 +1548,14 @@ void CompilerMSL::extract_global_variables_from_functions() // Uniforms unordered_set global_var_ids; ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + // Some builtins resolve directly to a function call which does not need any declared variables. + // Skip these. + if (var.storage == StorageClassInput && has_decoration(var.self, DecorationBuiltIn) && + BuiltIn(get_decoration(var.self, DecorationBuiltIn)) == BuiltInHelperInvocation) + { + return; + } + if (var.storage == StorageClassInput || var.storage == StorageClassOutput || var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) @@ -12163,16 +12171,6 @@ void CompilerMSL::fix_up_shader_inputs_outputs() }); } break; - case BuiltInHelperInvocation: - if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) - SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.3 on iOS."); - 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."); - - entry_func.fixup_hooks_in.push_back([=]() { - statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = simd_is_helper_thread();"); - }); - break; case BuiltInInvocationId: // This is direct-mapped without multi-patch workgroups. if (get_execution_model() != ExecutionModelTessellationControl || !msl_options.multi_patch_workgroup) @@ -14467,6 +14465,14 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) } break; + case BuiltInHelperInvocation: + if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) + SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.3 on iOS."); + 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."); + // In SPIR-V 1.6 with Volatile HelperInvocation, we cannot emit a fixup early. + return "simd_is_helper_thread()"; + default: break; } -- cgit v1.2.3