mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-15 00:11:06 +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_int16_type = "short";
|
||||||
backend.basic_uint16_type = "ushort";
|
backend.basic_uint16_type = "ushort";
|
||||||
backend.discard_literal = "discard_fragment()";
|
backend.discard_literal = "discard_fragment()";
|
||||||
backend.demote_literal = "unsupported-demote";
|
backend.demote_literal = "discard_fragment()";
|
||||||
backend.boolean_mix_function = "select";
|
backend.boolean_mix_function = "select";
|
||||||
backend.swizzle_is_function = false;
|
backend.swizzle_is_function = false;
|
||||||
backend.shared_is_implied = false;
|
backend.shared_is_implied = false;
|
||||||
@ -7117,11 +7117,18 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|||||||
break;
|
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:
|
case OpIsHelperInvocationEXT:
|
||||||
if (msl_options.is_ios())
|
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
|
||||||
SPIRV_CROSS_THROW("simd_is_helper_thread() is only supported on macOS.");
|
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))
|
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);
|
emit_op(ops[0], ops[1], "simd_is_helper_thread()", false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -107,17 +107,17 @@ def print_msl_compiler_version():
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def msl_compiler_supports_22():
|
def msl_compiler_supports_version(version):
|
||||||
try:
|
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)
|
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
|
return True
|
||||||
except OSError as e:
|
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
|
return False
|
||||||
except subprocess.CalledProcessError:
|
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
|
return False
|
||||||
|
|
||||||
def path_to_msl_standard(shader):
|
def path_to_msl_standard(shader):
|
||||||
@ -128,6 +128,8 @@ def path_to_msl_standard(shader):
|
|||||||
return '-std=ios-metal2.1'
|
return '-std=ios-metal2.1'
|
||||||
elif '.msl22.' in shader:
|
elif '.msl22.' in shader:
|
||||||
return '-std=ios-metal2.2'
|
return '-std=ios-metal2.2'
|
||||||
|
elif '.msl23.' in shader:
|
||||||
|
return '-std=ios-metal2.3'
|
||||||
elif '.msl11.' in shader:
|
elif '.msl11.' in shader:
|
||||||
return '-std=ios-metal1.1'
|
return '-std=ios-metal1.1'
|
||||||
elif '.msl10.' in shader:
|
elif '.msl10.' in shader:
|
||||||
@ -141,6 +143,8 @@ def path_to_msl_standard(shader):
|
|||||||
return '-std=macos-metal2.1'
|
return '-std=macos-metal2.1'
|
||||||
elif '.msl22.' in shader:
|
elif '.msl22.' in shader:
|
||||||
return '-std=macos-metal2.2'
|
return '-std=macos-metal2.2'
|
||||||
|
elif '.msl23.' in shader:
|
||||||
|
return '-std=macos-metal2.3'
|
||||||
elif '.msl11.' in shader:
|
elif '.msl11.' in shader:
|
||||||
return '-std=macos-metal1.1'
|
return '-std=macos-metal1.1'
|
||||||
else:
|
else:
|
||||||
@ -153,6 +157,8 @@ def path_to_msl_standard_cli(shader):
|
|||||||
return '20100'
|
return '20100'
|
||||||
elif '.msl22.' in shader:
|
elif '.msl22.' in shader:
|
||||||
return '20200'
|
return '20200'
|
||||||
|
elif '.msl23.' in shader:
|
||||||
|
return '20300'
|
||||||
elif '.msl11.' in shader:
|
elif '.msl11.' in shader:
|
||||||
return '10100'
|
return '10100'
|
||||||
else:
|
else:
|
||||||
@ -712,7 +718,8 @@ def test_shader_msl(stats, shader, args, paths):
|
|||||||
# print('SPRIV shader: ' + spirv)
|
# print('SPRIV shader: ' + spirv)
|
||||||
|
|
||||||
shader_is_msl22 = 'msl22' in joined_path
|
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:
|
if '.invalid.' in joined_path:
|
||||||
skip_validation = True
|
skip_validation = True
|
||||||
|
|
||||||
@ -860,9 +867,11 @@ def main():
|
|||||||
args.parallel = False
|
args.parallel = False
|
||||||
|
|
||||||
args.msl22 = False
|
args.msl22 = False
|
||||||
|
args.msl23 = False
|
||||||
if args.msl:
|
if args.msl:
|
||||||
print_msl_compiler_version()
|
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'
|
backend = 'glsl'
|
||||||
if (args.msl or args.metal):
|
if (args.msl or args.metal):
|
||||||
|
Loading…
Reference in New Issue
Block a user