mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-14 16:01:07 +00:00
MSL: Support SPV_EXT_demote_to_helper_invocation for MSL 2.3.
MSL 2.3 has everything needed to support this extension on all platforms. The existing `discard_fragment()` function was given demote semantics, similar to Direct3D, and the `simd_is_helper_thread()` function was finally added to iOS. I've left the old test alone. Should I remove it in favor of these?
This commit is contained in:
parent
401af49326
commit
2219c4a392
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
bool _15 = simd_is_helper_thread();
|
||||
discard_fragment();
|
||||
if (!_15)
|
||||
{
|
||||
out.FragColor = float4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
fragment void main0()
|
||||
{
|
||||
discard_fragment();
|
||||
bool _9 = simd_is_helper_thread();
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
fragment void main0()
|
||||
{
|
||||
discard_fragment();
|
||||
bool _9 = simd_is_helper_thread();
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
bool _15 = simd_is_helper_thread();
|
||||
discard_fragment();
|
||||
if (!_15)
|
||||
{
|
||||
out.FragColor = float4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
fragment void main0()
|
||||
{
|
||||
discard_fragment();
|
||||
bool _9 = simd_is_helper_thread();
|
||||
bool helper = _9;
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
fragment void main0()
|
||||
{
|
||||
discard_fragment();
|
||||
bool _9 = simd_is_helper_thread();
|
||||
bool helper = _9;
|
||||
}
|
||||
|
@ -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
|
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
#extension GL_EXT_demote_to_helper_invocation : require
|
||||
|
||||
void main()
|
||||
{
|
||||
demote;
|
||||
bool helper = helperInvocationEXT();
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
#extension GL_EXT_demote_to_helper_invocation : require
|
||||
|
||||
void main()
|
||||
{
|
||||
demote;
|
||||
bool helper = helperInvocationEXT();
|
||||
}
|
@ -1120,7 +1120,7 @@ string CompilerMSL::compile()
|
||||
backend.basic_int16_type = "short";
|
||||
backend.basic_uint16_type = "ushort";
|
||||
backend.discard_literal = "discard_fragment()";
|
||||
backend.demote_literal = "unsupported-demote";
|
||||
backend.demote_literal = "discard_fragment()";
|
||||
backend.boolean_mix_function = "select";
|
||||
backend.swizzle_is_function = false;
|
||||
backend.shared_is_implied = false;
|
||||
@ -7117,11 +7117,18 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
// SPV_EXT_demote_to_helper_invocation
|
||||
case OpDemoteToHelperInvocationEXT:
|
||||
if (!msl_options.supports_msl_version(2, 3))
|
||||
SPIRV_CROSS_THROW("discard_fragment() does not formally have demote semantics until MSL 2.3.");
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
break;
|
||||
|
||||
case OpIsHelperInvocationEXT:
|
||||
if (msl_options.is_ios())
|
||||
SPIRV_CROSS_THROW("simd_is_helper_thread() is only supported on macOS.");
|
||||
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
|
||||
SPIRV_CROSS_THROW("simd_is_helper_thread() requires MSL 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.");
|
||||
SPIRV_CROSS_THROW("simd_is_helper_thread() requires MSL 2.1 on macOS.");
|
||||
emit_op(ops[0], ops[1], "simd_is_helper_thread()", false);
|
||||
break;
|
||||
|
||||
|
@ -107,17 +107,17 @@ def print_msl_compiler_version():
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
def msl_compiler_supports_22():
|
||||
def msl_compiler_supports_version(version):
|
||||
try:
|
||||
subprocess.check_call(['xcrun', '--sdk', 'macosx', 'metal', '-x', 'metal', '-std=macos-metal2.2', '-'],
|
||||
subprocess.check_call(['xcrun', '--sdk', 'macosx', 'metal', '-x', 'metal', '-std=macos-metal' + version, '-'],
|
||||
stdin = subprocess.DEVNULL, stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL)
|
||||
print('Current SDK supports MSL 2.2. Enabling validation for MSL 2.2 shaders.')
|
||||
print('Current SDK supports MSL {0}. Enabling validation for MSL {0} shaders.'.format(version))
|
||||
return True
|
||||
except OSError as e:
|
||||
print('Failed to check if MSL 2.2 is not supported. It probably is not.')
|
||||
print('Failed to check if MSL {} is not supported. It probably is not.'.format(version))
|
||||
return False
|
||||
except subprocess.CalledProcessError:
|
||||
print('Current SDK does NOT support MSL 2.2. Disabling validation for MSL 2.2 shaders.')
|
||||
print('Current SDK does NOT support MSL {0}. Disabling validation for MSL {0} shaders.'.format(version))
|
||||
return False
|
||||
|
||||
def path_to_msl_standard(shader):
|
||||
@ -128,6 +128,8 @@ def path_to_msl_standard(shader):
|
||||
return '-std=ios-metal2.1'
|
||||
elif '.msl22.' in shader:
|
||||
return '-std=ios-metal2.2'
|
||||
elif '.msl23.' in shader:
|
||||
return '-std=ios-metal2.3'
|
||||
elif '.msl11.' in shader:
|
||||
return '-std=ios-metal1.1'
|
||||
elif '.msl10.' in shader:
|
||||
@ -141,6 +143,8 @@ def path_to_msl_standard(shader):
|
||||
return '-std=macos-metal2.1'
|
||||
elif '.msl22.' in shader:
|
||||
return '-std=macos-metal2.2'
|
||||
elif '.msl23.' in shader:
|
||||
return '-std=macos-metal2.3'
|
||||
elif '.msl11.' in shader:
|
||||
return '-std=macos-metal1.1'
|
||||
else:
|
||||
@ -153,6 +157,8 @@ def path_to_msl_standard_cli(shader):
|
||||
return '20100'
|
||||
elif '.msl22.' in shader:
|
||||
return '20200'
|
||||
elif '.msl23.' in shader:
|
||||
return '20300'
|
||||
elif '.msl11.' in shader:
|
||||
return '10100'
|
||||
else:
|
||||
@ -712,7 +718,8 @@ def test_shader_msl(stats, shader, args, paths):
|
||||
# print('SPRIV shader: ' + spirv)
|
||||
|
||||
shader_is_msl22 = 'msl22' in joined_path
|
||||
skip_validation = shader_is_msl22 and (not args.msl22)
|
||||
shader_is_msl23 = 'msl23' in joined_path
|
||||
skip_validation = (shader_is_msl22 and (not args.msl22)) or (shader_is_msl23 and (not args.msl23))
|
||||
if '.invalid.' in joined_path:
|
||||
skip_validation = True
|
||||
|
||||
@ -860,9 +867,11 @@ def main():
|
||||
args.parallel = False
|
||||
|
||||
args.msl22 = False
|
||||
args.msl23 = False
|
||||
if args.msl:
|
||||
print_msl_compiler_version()
|
||||
args.msl22 = msl_compiler_supports_22()
|
||||
args.msl22 = msl_compiler_supports_version('2.2')
|
||||
args.msl23 = msl_compiler_supports_version('2.3')
|
||||
|
||||
backend = 'glsl'
|
||||
if (args.msl or args.metal):
|
||||
|
Loading…
Reference in New Issue
Block a user