Don't forward uses of an OpIsHelperInvocationEXT op.

If this is computed *before* a `demote`, but used *after*, forwarding it
will produce the wrong value. This does make for uglier shaders, but
it's necessary right now to ensure correctness.

I needed to use an assembly shader to produce the test for this.
`spirv-opt` is not smart enough (or too smart?) to eliminate the
variable that would be used in GLSL to express this.
This commit is contained in:
Chip Davis 2019-07-18 17:32:35 -05:00
parent 50dce10c5d
commit 12a8654784
9 changed files with 80 additions and 5 deletions

View File

@ -5,5 +5,6 @@ using namespace metal;
fragment void main0()
{
bool _9 = simd_is_helper_thread();
}

View File

@ -0,0 +1,15 @@
#version 450
#extension GL_EXT_demote_to_helper_invocation : require
layout(location = 0) out vec4 FragColor;
void main()
{
bool _15 = helperInvocationEXT();
demote;
if (!_15)
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
}

View File

@ -4,6 +4,7 @@
void main()
{
demote;
bool helper = helperInvocationEXT();
bool _9 = helperInvocationEXT();
bool helper = _9;
}

View File

@ -5,6 +5,7 @@ using namespace metal;
fragment void main0()
{
bool helper = simd_is_helper_thread();
bool _9 = simd_is_helper_thread();
bool helper = _9;
}

View File

@ -0,0 +1,15 @@
#version 450
#extension GL_EXT_demote_to_helper_invocation : require
layout(location = 0) out vec4 FragColor;
void main()
{
bool _15 = helperInvocationEXT();
demote;
if (!_15)
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
}

View File

@ -4,6 +4,7 @@
void main()
{
demote;
bool helper = helperInvocationEXT();
bool _9 = helperInvocationEXT();
bool helper = _9;
}

View File

@ -0,0 +1,41 @@
; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 19
; Schema: 0
OpCapability Shader
OpCapability DemoteToHelperInvocationEXT
OpExtension "SPV_EXT_demote_to_helper_invocation"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %FragColor
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_demote_to_helper_invocation"
OpName %main "main"
OpName %FragColor "FragColor"
OpDecorate %FragColor Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%bool = OpTypeBool
%_ptr_Function_bool = OpTypePointer Function %bool
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%FragColor = OpVariable %_ptr_Output_v4float Output
%float_1 = OpConstant %float 1
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
%main = OpFunction %void None %3
%5 = OpLabel
%9 = OpIsHelperInvocationEXT %bool
OpDemoteToHelperInvocationEXT
%10 = OpLogicalNot %bool %9
OpSelectionMerge %12 None
OpBranchConditional %10 %11 %12
%11 = OpLabel
OpStore %FragColor %19
OpBranch %12
%12 = OpLabel
OpReturn
OpFunctionEnd

View File

@ -9789,7 +9789,7 @@ 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");
emit_op(ops[0], ops[1], "helperInvocationEXT()", true);
emit_op(ops[0], ops[1], "helperInvocationEXT()", false);
break;
default:

View File

@ -4473,7 +4473,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
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.");
emit_op(ops[0], ops[1], "simd_is_helper_thread()", true);
emit_op(ops[0], ops[1], "simd_is_helper_thread()", false);
break;
default: