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 f42aeb876..29ff2dd7c 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 @@ -1,3 +1,5 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + #include #include @@ -8,18 +10,24 @@ struct main0_out float FragColor [[color(0)]]; }; +static inline __attribute__((always_inline)) +void func(thread float& FragColor, thread bool& gl_HelperInvocation) +{ + bool _14 = gl_HelperInvocation; + float _17 = float(_14); + FragColor = _17; + gl_HelperInvocation = true, discard_fragment(); + bool _18 = gl_HelperInvocation; + float _19 = float(_18); + FragColor = _19; +} + fragment main0_out main0() { main0_out out = {}; bool gl_HelperInvocation = {}; gl_HelperInvocation = simd_is_helper_thread(); - bool _12 = gl_HelperInvocation; - float _15 = float(_12); - out.FragColor = _15; - gl_HelperInvocation = true, discard_fragment(); - bool _16 = gl_HelperInvocation; - float _17 = float(_16); - out.FragColor = _17; + func(out.FragColor, gl_HelperInvocation); return out; } 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 index 9a8d9d20b..44cd4f117 100644 --- a/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag +++ b/shaders-msl-no-opt/frag/volatile-helper-invocation.msl23.spv16.frag @@ -3,9 +3,14 @@ layout(location = 0) out float FragColor; -void main() +void func() { FragColor = float(gl_HelperInvocation); demote; FragColor = float(gl_HelperInvocation); } + +void main() +{ + func(); +} diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 383ce688e..38cfedb75 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -1576,8 +1576,7 @@ string CompilerMSL::compile() preprocess_op_codes(); build_implicit_builtins(); - if (needs_manual_helper_invocation_updates() && - (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) + if (needs_manual_helper_invocation_updates() && needs_helper_invocation) { string builtin_helper_invocation = builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput); string discard_expr = join(builtin_helper_invocation, " = true, discard_fragment()"); @@ -1721,7 +1720,7 @@ void CompilerMSL::preprocess_op_codes() (is_sample_rate() && (active_input_builtins.get(BuiltInFragCoord) || (need_subpass_input_ms && !msl_options.use_framebuffer_fetch_subpasses)))) needs_sample_id = true; - if (preproc.needs_helper_invocation) + if (preproc.needs_helper_invocation || active_input_builtins.get(BuiltInHelperInvocation)) needs_helper_invocation = true; // OpKill is removed by the parser, so we need to identify those by inspecting @@ -2058,8 +2057,7 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: } case OpDemoteToHelperInvocation: - if (needs_manual_helper_invocation_updates() && - (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) + if (needs_manual_helper_invocation_updates() && needs_helper_invocation) added_arg_ids.insert(builtin_helper_invocation_id); break; @@ -2112,7 +2110,7 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: } if (needs_manual_helper_invocation_updates() && b.terminator == SPIRBlock::Kill && - (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) + needs_helper_invocation) added_arg_ids.insert(builtin_helper_invocation_id); // TODO: Add all other operations which can affect memory. @@ -13215,7 +13213,10 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bo addr_space = type.pointer || (argument && type.basetype == SPIRType::ControlPointArray) ? "thread" : ""; } - return join(decoration_flags_signal_volatile(flags) ? "volatile " : "", addr_space); + if (decoration_flags_signal_volatile(flags) && 0 != strcmp(addr_space, "thread")) + return join("volatile ", addr_space); + else + return addr_space; } const char *CompilerMSL::to_restrict(uint32_t id, bool space)