Fix volatile helper invocation in non-main functions

This commit is contained in:
Evan Tang 2024-07-02 10:59:43 -05:00
parent 66363ac7e8
commit 670cc7fb1d
3 changed files with 25 additions and 14 deletions

View File

@ -1,3 +1,5 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
@ -8,18 +10,24 @@ struct main0_out
float FragColor [[color(0)]];
};
static inline __attribute__((always_inline))
void func(thread float& FragColor, volatile 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;
}

View File

@ -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();
}

View File

@ -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.