diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag new file mode 100644 index 000000000..697389fa8 --- /dev/null +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag @@ -0,0 +1,48 @@ +#include +#include + +using namespace metal; + +struct _4 +{ + float4 _m0; +}; + +struct _6 +{ + int _m0; +}; + +struct _7 +{ + float4 _m0; +}; + +struct main0_out +{ + float4 m_3 [[color(0)]]; +}; + +fragment main0_out main0(constant _6& _20 [[buffer(0)]], constant _7* _8_0 [[buffer(1)]], constant _7* _8_1 [[buffer(2)]], constant _7* _8_2 [[buffer(3)]], constant _7* _8_3 [[buffer(4)]], const device _4* _5_0 [[buffer(5)]], const device _4* _5_1 [[buffer(6)]], const device _4* _5_2 [[buffer(7)]], const device _4* _5_3 [[buffer(8)]]) +{ + constant _7* _8[] = + { + _8_0, + _8_1, + _8_2, + _8_3, + }; + + const device _4* _5[] = + { + _5_0, + _5_1, + _5_2, + _5_3, + }; + + main0_out out = {}; + out.m_3 = _5[_20._m0]->_m0 + (_8[_20._m0]->_m0 * float4(0.20000000298023223876953125)); + return out; +} + diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc index e256409da..0a2bb6bfd 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc @@ -52,6 +52,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 3) + return; VertexOutput _223[3] = { VertexOutput{ gl_in[0].gl_Position, gl_in[0].VertexOutput_uv }, VertexOutput{ gl_in[1].gl_Position, gl_in[1].VertexOutput_uv }, VertexOutput{ gl_in[2].gl_Position, gl_in[2].VertexOutput_uv } }; VertexOutput param[3]; spvArrayCopyFromStack1(param, _223); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese index 3d4c27866..83ef72932 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese @@ -10,26 +10,14 @@ struct main0_out struct main0_patchIn { - float gl_TessLevelInner_0 [[attribute(0)]]; - float gl_TessLevelInner_1 [[attribute(1)]]; - float gl_TessLevelOuter_0 [[attribute(2)]]; - float gl_TessLevelOuter_1 [[attribute(3)]]; - float gl_TessLevelOuter_2 [[attribute(4)]]; - float gl_TessLevelOuter_3 [[attribute(5)]]; + float2 gl_TessLevelInner [[attribute(0)]]; + float4 gl_TessLevelOuter [[attribute(1)]]; }; [[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]]) { main0_out out = {}; - float gl_TessLevelInner[2] = {}; - float gl_TessLevelOuter[4] = {}; - gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0; - gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1; - gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0; - gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1; - gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2; - gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3; - out.gl_Position = float4(((gl_TessCoord.x * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[3])), 0.0, 1.0); + out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w), 0.0, 1.0); return out; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc b/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc index b9949290e..699493613 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc @@ -25,6 +25,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 4) + return; gl_out[gl_InvocationID].vVertex = gl_in[gl_InvocationID].vInput + gl_in[gl_InvocationID ^ 1].vInput; threadgroup_barrier(mem_flags::mem_device); if (gl_InvocationID == 0) diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc b/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc index 4d932d589..530938484 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc @@ -25,6 +25,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 1) + return; spvTessLevel[gl_PrimitiveID].insideTessellationFactor[0] = half(8.8999996185302734375); spvTessLevel[gl_PrimitiveID].insideTessellationFactor[1] = half(6.900000095367431640625); spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(8.8999996185302734375); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc b/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc index 3496d04c3..2e63aee1e 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc @@ -26,6 +26,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 4) + return; Boo vInput_24; vInput_24.a = gl_in[gl_InvocationID].Boo_a; vInput_24.b = gl_in[gl_InvocationID].Boo_b; diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/tesc/water_tess.tesc b/3rdparty/spirv-cross/reference/opt/shaders-msl/tesc/water_tess.tesc index e89e6570e..b67ae2766 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/tesc/water_tess.tesc +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/tesc/water_tess.tesc @@ -30,6 +30,8 @@ kernel void main0(main0_in in [[stage_in]], constant UBO& _41 [[buffer(0)]], uin if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 1) + return; float2 _430 = (gl_in[0].vPatchPosBase - float2(10.0)) * _41.uScale.xy; float2 _440 = ((gl_in[0].vPatchPosBase + _41.uPatchSize) + float2(10.0)) * _41.uScale.xy; float3 _445 = float3(_430.x, -10.0, _430.y); diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.domain.tese b/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.domain.tese index 1a2f7980d..78b58ab99 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.domain.tese +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.domain.tese @@ -10,27 +10,15 @@ struct main0_out struct main0_patchIn { - float gl_TessLevelInner_0 [[attribute(0)]]; - float gl_TessLevelInner_1 [[attribute(1)]]; - float gl_TessLevelOuter_0 [[attribute(2)]]; - float gl_TessLevelOuter_1 [[attribute(3)]]; - float gl_TessLevelOuter_2 [[attribute(4)]]; - float gl_TessLevelOuter_3 [[attribute(5)]]; + float2 gl_TessLevelInner [[attribute(0)]]; + float4 gl_TessLevelOuter [[attribute(1)]]; }; [[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]]) { main0_out out = {}; - float gl_TessLevelInner[2] = {}; - float gl_TessLevelOuter[4] = {}; - gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0; - gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1; - gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0; - gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1; - gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2; - gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3; gl_TessCoord.y = 1.0 - gl_TessCoord.y; - out.gl_Position = float4(((gl_TessCoord.x * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[3])) + (((1.0 - gl_TessCoord.y) * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[1])), 0.0, 1.0); + out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y), 0.0, 1.0); return out; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.tese b/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.tese index 3d4c27866..83ef72932 100644 --- a/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.tese +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/quad.tese @@ -10,26 +10,14 @@ struct main0_out struct main0_patchIn { - float gl_TessLevelInner_0 [[attribute(0)]]; - float gl_TessLevelInner_1 [[attribute(1)]]; - float gl_TessLevelOuter_0 [[attribute(2)]]; - float gl_TessLevelOuter_1 [[attribute(3)]]; - float gl_TessLevelOuter_2 [[attribute(4)]]; - float gl_TessLevelOuter_3 [[attribute(5)]]; + float2 gl_TessLevelInner [[attribute(0)]]; + float4 gl_TessLevelOuter [[attribute(1)]]; }; [[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]]) { main0_out out = {}; - float gl_TessLevelInner[2] = {}; - float gl_TessLevelOuter[4] = {}; - gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0; - gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1; - gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0; - gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1; - gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2; - gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3; - out.gl_Position = float4(((gl_TessCoord.x * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[3])), 0.0, 1.0); + out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w), 0.0, 1.0); return out; } diff --git a/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/triangle-tess-level.tese b/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/triangle-tess-level.tese new file mode 100644 index 000000000..975e62985 --- /dev/null +++ b/3rdparty/spirv-cross/reference/opt/shaders-msl/tese/triangle-tess-level.tese @@ -0,0 +1,28 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 gl_Position [[position]]; +}; + +struct main0_patchIn +{ + float4 gl_TessLevel [[attribute(0)]]; +}; + +[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]]) +{ + main0_out out = {}; + float gl_TessLevelInner[2] = {}; + float gl_TessLevelOuter[4] = {}; + gl_TessLevelInner[0] = patchIn.gl_TessLevel.w; + gl_TessLevelOuter[0] = patchIn.gl_TessLevel.x; + gl_TessLevelOuter[1] = patchIn.gl_TessLevel.y; + gl_TessLevelOuter[2] = patchIn.gl_TessLevel.z; + out.gl_Position = float4((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0], (gl_TessCoord.y * gl_TessLevelInner[0]) * gl_TessLevelOuter[1], (gl_TessCoord.z * gl_TessLevelInner[0]) * gl_TessLevelOuter[2], 1.0); + return out; +} + diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag b/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag new file mode 100644 index 000000000..697389fa8 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag @@ -0,0 +1,48 @@ +#include +#include + +using namespace metal; + +struct _4 +{ + float4 _m0; +}; + +struct _6 +{ + int _m0; +}; + +struct _7 +{ + float4 _m0; +}; + +struct main0_out +{ + float4 m_3 [[color(0)]]; +}; + +fragment main0_out main0(constant _6& _20 [[buffer(0)]], constant _7* _8_0 [[buffer(1)]], constant _7* _8_1 [[buffer(2)]], constant _7* _8_2 [[buffer(3)]], constant _7* _8_3 [[buffer(4)]], const device _4* _5_0 [[buffer(5)]], const device _4* _5_1 [[buffer(6)]], const device _4* _5_2 [[buffer(7)]], const device _4* _5_3 [[buffer(8)]]) +{ + constant _7* _8[] = + { + _8_0, + _8_1, + _8_2, + _8_3, + }; + + const device _4* _5[] = + { + _5_0, + _5_1, + _5_2, + _5_3, + }; + + main0_out out = {}; + out.m_3 = _5[_20._m0]->_m0 + (_8[_20._m0]->_m0 * float4(0.20000000298023223876953125)); + return out; +} + diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc b/3rdparty/spirv-cross/reference/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc index ef9ef7ccc..a8e3af263 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/tesc/tess-fixed-input-array-builtin-array.invalid.asm.tesc @@ -82,6 +82,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 3) + return; VertexOutput p[3]; p[0].pos = gl_in[0].gl_Position; p[0].uv = gl_in[0].VertexOutput_uv; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese b/3rdparty/spirv-cross/reference/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese index 3d4c27866..83ef72932 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese +++ b/3rdparty/spirv-cross/reference/shaders-msl/asm/tese/unnamed-builtin-array.asm.tese @@ -10,26 +10,14 @@ struct main0_out struct main0_patchIn { - float gl_TessLevelInner_0 [[attribute(0)]]; - float gl_TessLevelInner_1 [[attribute(1)]]; - float gl_TessLevelOuter_0 [[attribute(2)]]; - float gl_TessLevelOuter_1 [[attribute(3)]]; - float gl_TessLevelOuter_2 [[attribute(4)]]; - float gl_TessLevelOuter_3 [[attribute(5)]]; + float2 gl_TessLevelInner [[attribute(0)]]; + float4 gl_TessLevelOuter [[attribute(1)]]; }; [[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]]) { main0_out out = {}; - float gl_TessLevelInner[2] = {}; - float gl_TessLevelOuter[4] = {}; - gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0; - gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1; - gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0; - gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1; - gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2; - gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3; - out.gl_Position = float4(((gl_TessCoord.x * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[3])), 0.0, 1.0); + out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w), 0.0, 1.0); return out; } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc b/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc index b9949290e..699493613 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc +++ b/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/arrayed-output.desktop.sso.tesc @@ -25,6 +25,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 4) + return; gl_out[gl_InvocationID].vVertex = gl_in[gl_InvocationID].vInput + gl_in[gl_InvocationID ^ 1].vInput; threadgroup_barrier(mem_flags::mem_device); if (gl_InvocationID == 0) diff --git a/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc b/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc index 9c4e3b3ae..eacb34285 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc +++ b/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/basic.desktop.sso.tesc @@ -32,6 +32,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 1) + return; spvTessLevel[gl_PrimitiveID].insideTessellationFactor[0] = half(8.8999996185302734375); spvTessLevel[gl_PrimitiveID].insideTessellationFactor[1] = half(6.900000095367431640625); spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(8.8999996185302734375); diff --git a/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc b/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc index 3496d04c3..2e63aee1e 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc +++ b/3rdparty/spirv-cross/reference/shaders-msl/desktop-only/tesc/struct-copy.desktop.sso.tesc @@ -26,6 +26,8 @@ kernel void main0(main0_in in [[stage_in]], uint gl_InvocationID [[thread_index_ if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 4) + return; Boo vInput_24; vInput_24.a = gl_in[gl_InvocationID].Boo_a; vInput_24.b = gl_in[gl_InvocationID].Boo_b; diff --git a/3rdparty/spirv-cross/reference/shaders-msl/tesc/water_tess.tesc b/3rdparty/spirv-cross/reference/shaders-msl/tesc/water_tess.tesc index 48b3566f5..53eab0a11 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/tesc/water_tess.tesc +++ b/3rdparty/spirv-cross/reference/shaders-msl/tesc/water_tess.tesc @@ -112,6 +112,8 @@ kernel void main0(main0_in in [[stage_in]], constant UBO& v_41 [[buffer(0)]], ui if (gl_InvocationID < spvIndirectParams[0]) gl_in[gl_InvocationID] = in; threadgroup_barrier(mem_flags::mem_threadgroup); + if (gl_InvocationID >= 1) + return; float2 p0 = gl_in[0].vPatchPosBase; float2 param = p0; if (!frustum_cull(param, v_41)) diff --git a/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.domain.tese b/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.domain.tese index 1a2f7980d..78b58ab99 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.domain.tese +++ b/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.domain.tese @@ -10,27 +10,15 @@ struct main0_out struct main0_patchIn { - float gl_TessLevelInner_0 [[attribute(0)]]; - float gl_TessLevelInner_1 [[attribute(1)]]; - float gl_TessLevelOuter_0 [[attribute(2)]]; - float gl_TessLevelOuter_1 [[attribute(3)]]; - float gl_TessLevelOuter_2 [[attribute(4)]]; - float gl_TessLevelOuter_3 [[attribute(5)]]; + float2 gl_TessLevelInner [[attribute(0)]]; + float4 gl_TessLevelOuter [[attribute(1)]]; }; [[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]]) { main0_out out = {}; - float gl_TessLevelInner[2] = {}; - float gl_TessLevelOuter[4] = {}; - gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0; - gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1; - gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0; - gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1; - gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2; - gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3; gl_TessCoord.y = 1.0 - gl_TessCoord.y; - out.gl_Position = float4(((gl_TessCoord.x * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[3])) + (((1.0 - gl_TessCoord.y) * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[1])), 0.0, 1.0); + out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y), 0.0, 1.0); return out; } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.tese b/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.tese index 3d4c27866..df3d260fa 100644 --- a/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.tese +++ b/3rdparty/spirv-cross/reference/shaders-msl/tese/quad.tese @@ -1,3 +1,5 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + #include #include @@ -10,26 +12,19 @@ struct main0_out struct main0_patchIn { - float gl_TessLevelInner_0 [[attribute(0)]]; - float gl_TessLevelInner_1 [[attribute(1)]]; - float gl_TessLevelOuter_0 [[attribute(2)]]; - float gl_TessLevelOuter_1 [[attribute(3)]]; - float gl_TessLevelOuter_2 [[attribute(4)]]; - float gl_TessLevelOuter_3 [[attribute(5)]]; + float2 gl_TessLevelInner [[attribute(0)]]; + float4 gl_TessLevelOuter [[attribute(1)]]; }; +void set_position(thread float4& gl_Position, thread float2& gl_TessCoord, thread float2& gl_TessLevelInner, thread float4& gl_TessLevelOuter) +{ + gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner.x) * gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner.x) * gl_TessLevelOuter.z), ((gl_TessCoord.y * gl_TessLevelInner.y) * gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner.y) * gl_TessLevelOuter.w), 0.0, 1.0); +} + [[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]]) { main0_out out = {}; - float gl_TessLevelInner[2] = {}; - float gl_TessLevelOuter[4] = {}; - gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0; - gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1; - gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0; - gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1; - gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2; - gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3; - out.gl_Position = float4(((gl_TessCoord.x * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type(gl_TessLevelInner[0])) * as_type(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type(gl_TessLevelInner[1])) * as_type(gl_TessLevelOuter[3])), 0.0, 1.0); + set_position(out.gl_Position, gl_TessCoord, patchIn.gl_TessLevelInner, patchIn.gl_TessLevelOuter); return out; } diff --git a/3rdparty/spirv-cross/reference/shaders-msl/tese/triangle-tess-level.tese b/3rdparty/spirv-cross/reference/shaders-msl/tese/triangle-tess-level.tese new file mode 100644 index 000000000..975e62985 --- /dev/null +++ b/3rdparty/spirv-cross/reference/shaders-msl/tese/triangle-tess-level.tese @@ -0,0 +1,28 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 gl_Position [[position]]; +}; + +struct main0_patchIn +{ + float4 gl_TessLevel [[attribute(0)]]; +}; + +[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]]) +{ + main0_out out = {}; + float gl_TessLevelInner[2] = {}; + float gl_TessLevelOuter[4] = {}; + gl_TessLevelInner[0] = patchIn.gl_TessLevel.w; + gl_TessLevelOuter[0] = patchIn.gl_TessLevel.x; + gl_TessLevelOuter[1] = patchIn.gl_TessLevel.y; + gl_TessLevelOuter[2] = patchIn.gl_TessLevel.z; + out.gl_Position = float4((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0], (gl_TessCoord.y * gl_TessLevelInner[0]) * gl_TessLevelOuter[1], (gl_TessCoord.z * gl_TessLevelInner[0]) * gl_TessLevelOuter[2], 1.0); + return out; +} + diff --git a/3rdparty/spirv-cross/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag b/3rdparty/spirv-cross/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag new file mode 100644 index 000000000..7af7605d8 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-msl/asm/frag/descriptor-array-unnamed.asm.frag @@ -0,0 +1,63 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 39 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %FragColor + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpDecorate %FragColor Location 0 + OpMemberDecorate %SSBO 0 NonWritable + OpMemberDecorate %SSBO 0 Offset 0 + OpDecorate %SSBO BufferBlock + OpDecorate %ssbos DescriptorSet 0 + OpDecorate %ssbos Binding 5 + OpMemberDecorate %Registers 0 Offset 0 + OpDecorate %Registers Block + OpMemberDecorate %UBO 0 Offset 0 + OpDecorate %UBO Block + OpDecorate %ubos DescriptorSet 0 + OpDecorate %ubos Binding 1 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %FragColor = OpVariable %_ptr_Output_v4float Output + %SSBO = OpTypeStruct %v4float + %uint = OpTypeInt 32 0 + %uint_4 = OpConstant %uint 4 +%_arr_SSBO_uint_4 = OpTypeArray %SSBO %uint_4 +%_ptr_Uniform__arr_SSBO_uint_4 = OpTypePointer Uniform %_arr_SSBO_uint_4 + %ssbos = OpVariable %_ptr_Uniform__arr_SSBO_uint_4 Uniform + %int = OpTypeInt 32 1 + %Registers = OpTypeStruct %int +%_ptr_PushConstant_Registers = OpTypePointer PushConstant %Registers + %registers = OpVariable %_ptr_PushConstant_Registers PushConstant + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_int = OpTypePointer PushConstant %int +%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float + %UBO = OpTypeStruct %v4float +%_arr_UBO_uint_4 = OpTypeArray %UBO %uint_4 +%_ptr_Uniform__arr_UBO_uint_4 = OpTypePointer Uniform %_arr_UBO_uint_4 + %ubos = OpVariable %_ptr_Uniform__arr_UBO_uint_4 Uniform +%float_0_200000003 = OpConstant %float 0.200000003 + %36 = OpConstantComposite %v4float %float_0_200000003 %float_0_200000003 %float_0_200000003 %float_0_200000003 + %main = OpFunction %void None %3 + %5 = OpLabel + %22 = OpAccessChain %_ptr_PushConstant_int %registers %int_0 + %23 = OpLoad %int %22 + %25 = OpAccessChain %_ptr_Uniform_v4float %ssbos %23 %int_0 + %26 = OpLoad %v4float %25 + %31 = OpAccessChain %_ptr_PushConstant_int %registers %int_0 + %32 = OpLoad %int %31 + %33 = OpAccessChain %_ptr_Uniform_v4float %ubos %32 %int_0 + %34 = OpLoad %v4float %33 + %37 = OpFMul %v4float %34 %36 + %38 = OpFAdd %v4float %26 %37 + OpStore %FragColor %38 + OpReturn + OpFunctionEnd diff --git a/3rdparty/spirv-cross/shaders-msl/tese/quad.tese b/3rdparty/spirv-cross/shaders-msl/tese/quad.tese index 0c0f45006..4fdb9960b 100644 --- a/3rdparty/spirv-cross/shaders-msl/tese/quad.tese +++ b/3rdparty/spirv-cross/shaders-msl/tese/quad.tese @@ -3,10 +3,15 @@ layout(cw, quads, fractional_even_spacing) in; -void main() +void set_position() { gl_Position = vec4(gl_TessCoord.x * gl_TessLevelInner[0] * gl_TessLevelOuter[0] + (1.0 - gl_TessCoord.x) * gl_TessLevelInner[0] * gl_TessLevelOuter[2], gl_TessCoord.y * gl_TessLevelInner[1] * gl_TessLevelOuter[1] + (1.0 - gl_TessCoord.y) * gl_TessLevelInner[1] * gl_TessLevelOuter[3], 0, 1); } +void main() +{ + set_position(); +} + diff --git a/3rdparty/spirv-cross/shaders-msl/tese/triangle-tess-level.tese b/3rdparty/spirv-cross/shaders-msl/tese/triangle-tess-level.tese new file mode 100644 index 000000000..5ea55af15 --- /dev/null +++ b/3rdparty/spirv-cross/shaders-msl/tese/triangle-tess-level.tese @@ -0,0 +1,13 @@ +#version 310 es +#extension GL_EXT_tessellation_shader : require + +layout(cw, triangles, fractional_even_spacing) in; + +void main() +{ + gl_Position = vec4(gl_TessCoord.x * gl_TessLevelInner[0] * gl_TessLevelOuter[0], + gl_TessCoord.y * gl_TessLevelInner[0] * gl_TessLevelOuter[1], + gl_TessCoord.z * gl_TessLevelInner[0] * gl_TessLevelOuter[2], + 1); +} + diff --git a/3rdparty/spirv-cross/spirv_common.hpp b/3rdparty/spirv-cross/spirv_common.hpp index b5a93c7f5..7be404613 100644 --- a/3rdparty/spirv-cross/spirv_common.hpp +++ b/3rdparty/spirv-cross/spirv_common.hpp @@ -23,13 +23,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -245,10 +245,12 @@ inline std::string merge(const std::vector &list) return s; } -template -inline std::string convert_to_string(T &&t) +// Make sure we don't accidentally call this with float or doubles with SFINAE. +// Have to use the radix-aware overload. +template ::value, int>::type = 0> +inline std::string convert_to_string(const T &t) { - return std::to_string(std::forward(t)); + return std::to_string(t); } // Allow implementations to set a convenient standard precision @@ -263,24 +265,43 @@ inline std::string convert_to_string(T &&t) #pragma warning(disable : 4996) #endif -inline std::string convert_to_string(float t) +static inline void fixup_radix_point(char *str, char radix_point) +{ + // Setting locales is a very risky business in multi-threaded program, + // so just fixup locales instead. We only need to care about the radix point. + if (radix_point != '.') + { + while (*str != '\0') + { + if (*str == radix_point) + *str = '.'; + str++; + } + } +} + +inline std::string convert_to_string(float t, char locale_radix_point) { // std::to_string for floating point values is broken. // Fallback to something more sane. char buf[64]; sprintf(buf, SPIRV_CROSS_FLT_FMT, t); + fixup_radix_point(buf, locale_radix_point); + // Ensure that the literal is float. if (!strchr(buf, '.') && !strchr(buf, 'e')) strcat(buf, ".0"); return buf; } -inline std::string convert_to_string(double t) +inline std::string convert_to_string(double t, char locale_radix_point) { // std::to_string for floating point values is broken. // Fallback to something more sane. char buf[64]; sprintf(buf, SPIRV_CROSS_FLT_FMT, t); + fixup_radix_point(buf, locale_radix_point); + // Ensure that the literal is float. if (!strchr(buf, '.') && !strchr(buf, 'e')) strcat(buf, ".0"); @@ -1404,22 +1425,6 @@ struct Meta using VariableTypeRemapCallback = std::function; -class ClassicLocale -{ -public: - ClassicLocale() - { - old = std::locale::global(std::locale::classic()); - } - ~ClassicLocale() - { - std::locale::global(old); - } - -private: - std::locale old; -}; - class Hasher { public: diff --git a/3rdparty/spirv-cross/spirv_cpp.cpp b/3rdparty/spirv-cross/spirv_cpp.cpp index 094275fa8..1b791ee53 100644 --- a/3rdparty/spirv-cross/spirv_cpp.cpp +++ b/3rdparty/spirv-cross/spirv_cpp.cpp @@ -306,9 +306,6 @@ void CompilerCPP::emit_resources() string CompilerCPP::compile() { - // Force a classic "C" locale, reverts when function returns - ClassicLocale classic_locale; - // Do not deal with ES-isms like precision, older extensions and such. options.es = false; options.version = 450; diff --git a/3rdparty/spirv-cross/spirv_cross.cpp b/3rdparty/spirv-cross/spirv_cross.cpp index 611dc9255..3faf511f0 100644 --- a/3rdparty/spirv-cross/spirv_cross.cpp +++ b/3rdparty/spirv-cross/spirv_cross.cpp @@ -64,8 +64,6 @@ void Compiler::set_ir(const ParsedIR &ir_) string Compiler::compile() { - // Force a classic "C" locale, reverts when function returns - ClassicLocale classic_locale; return ""; } diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index f1b4e750e..887685b7c 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -21,8 +21,14 @@ #include #include #include +#include #include +#ifndef _WIN32 +#include +#endif +#include + using namespace spv; using namespace spirv_cross; using namespace std; @@ -149,6 +155,31 @@ string CompilerGLSL::sanitize_underscores(const string &str) return res; } +void CompilerGLSL::init() +{ + if (ir.source.known) + { + options.es = ir.source.es; + options.version = ir.source.version; + } + + // Query the locale to see what the decimal point is. + // We'll rely on fixing it up ourselves in the rare case we have a comma-as-decimal locale + // rather than setting locales ourselves. Settings locales in a safe and isolated way is rather + // tricky. +#ifdef _WIN32 + // On Windows, localeconv uses thread-local storage, so it should be fine. + const struct lconv *conv = localeconv(); + if (conv && conv->decimal_point) + current_locale_radix_character = *conv->decimal_point; +#else + // localeconv, the portable function is not MT safe ... + const char *decimal_point = nl_langinfo(RADIXCHAR); + if (decimal_point && *decimal_point != '\0') + current_locale_radix_character = *decimal_point; +#endif +} + static const char *to_pls_layout(PlsFormat format) { switch (format) @@ -387,9 +418,6 @@ void CompilerGLSL::find_static_extensions() string CompilerGLSL::compile() { - // Force a classic "C" locale, reverts when function returns - ClassicLocale classic_locale; - if (options.vulkan_semantics) backend.allow_precision_qualifiers = true; backend.force_gl_in_out_block = true; @@ -2985,7 +3013,7 @@ string CompilerGLSL::convert_half_to_string(const SPIRConstant &c, uint32_t col, type.basetype = SPIRType::Half; type.vecsize = 1; type.columns = 1; - res = join(type_to_glsl(type), "(", convert_to_string(float_value), ")"); + res = join(type_to_glsl(type), "(", convert_to_string(float_value, current_locale_radix_character), ")"); } return res; @@ -3043,7 +3071,7 @@ string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col } else { - res = convert_to_string(float_value); + res = convert_to_string(float_value, current_locale_radix_character); if (backend.float_literal_suffix) res += "f"; } @@ -3115,7 +3143,7 @@ std::string CompilerGLSL::convert_double_to_string(const SPIRConstant &c, uint32 } else { - res = convert_to_string(double_value); + res = convert_to_string(double_value, current_locale_radix_character); if (backend.double_literal_suffix) res += "lf"; } diff --git a/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/spirv-cross/spirv_glsl.hpp index c0d9207c0..97593d9a6 100644 --- a/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/3rdparty/spirv-cross/spirv_glsl.hpp @@ -643,15 +643,10 @@ protected: bool variable_is_lut(const SPIRVariable &var) const; + char current_locale_radix_character = '.'; + private: - void init() - { - if (ir.source.known) - { - options.es = ir.source.es; - options.version = ir.source.version; - } - } + void init(); }; } // namespace spirv_cross diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 5489f7d36..555d6e140 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -546,8 +546,8 @@ void CompilerMSL::emit_entry_point_declarations() args.push_back(join("max_anisotropy(", s.max_anisotropy, ")")); if (s.lod_clamp_enable) { - args.push_back( - join("lod_clamp(", convert_to_string(s.lod_clamp_min), ", ", convert_to_string(s.lod_clamp_max), ")")); + args.push_back(join("lod_clamp(", convert_to_string(s.lod_clamp_min, current_locale_radix_character), ", ", + convert_to_string(s.lod_clamp_max, current_locale_radix_character), ")")); } statement("constexpr sampler ", @@ -560,7 +560,7 @@ void CompilerMSL::emit_entry_point_declarations() { const auto &var = get(array_id); const auto &type = get_variable_data_type(var); - string name = get_name(array_id); + string name = to_name(array_id); statement(get_argument_address_space(var) + " " + type_to_glsl(type) + "* " + name + "[] ="); begin_scope(); for (uint32_t i = 0; i < type.array[0]; ++i) @@ -574,9 +574,6 @@ void CompilerMSL::emit_entry_point_declarations() string CompilerMSL::compile() { - // Force a classic "C" locale, reverts when function returns - ClassicLocale classic_locale; - // Do not deal with GLES-isms like precision, older extensions and such. options.vulkan_semantics = true; options.es = false; @@ -1054,7 +1051,7 @@ uint32_t CompilerMSL::build_extended_vector_type(uint32_t type_id, uint32_t comp auto &type = set(new_type_id, get(type_id)); type.vecsize = components; type.self = new_type_id; - type.parent_type = 0; + type.parent_type = type_id; type.pointer = false; return new_type_id; @@ -1165,7 +1162,7 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co if (is_builtin) { set_member_decoration(ib_type.self, ib_mbr_idx, DecorationBuiltIn, builtin); - if (builtin == BuiltInPosition) + if (builtin == BuiltInPosition && storage == StorageClassOutput) qual_pos_var_name = qual_var_name; } @@ -1572,7 +1569,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor if (is_builtin) { set_member_decoration(ib_type.self, ib_mbr_idx, DecorationBuiltIn, builtin); - if (builtin == BuiltInPosition) + if (builtin == BuiltInPosition && storage == StorageClassOutput) qual_pos_var_name = qual_var_name; } @@ -1590,6 +1587,122 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, mbr_idx); } +// In Metal, the tessellation levels are stored as tightly packed half-precision floating point values. +// But, stage-in attribute offsets and strides must be multiples of four, so we can't pass the levels +// individually. Therefore, we must pass them as vectors. Triangles get a single float4, with the outer +// levels in 'xyz' and the inner level in 'w'. Quads get a float4 containing the outer levels and a +// float2 containing the inner levels. +void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var) +{ + auto &entry_func = get(ir.default_entry_point); + auto &var_type = get_variable_element_type(var); + + BuiltIn builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); + + // Force the variable to have the proper name. + set_name(var.self, builtin_to_glsl(builtin, StorageClassFunction)); + + if (get_entry_point().flags.get(ExecutionModeTriangles)) + { + // Triangles are tricky, because we want only one member in the struct. + + // We need to declare the variable early and at entry-point scope. + entry_func.add_local_variable(var.self); + vars_needing_early_declaration.push_back(var.self); + + string mbr_name = "gl_TessLevel"; + + // If we already added the other one, we can skip this step. + if (!added_builtin_tess_level) + { + // Add a reference to the variable type to the interface struct. + uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size()); + + uint32_t type_id = build_extended_vector_type(var_type.self, 4); + + ib_type.member_types.push_back(type_id); + + // Give the member a name + set_member_name(ib_type.self, ib_mbr_idx, mbr_name); + + // There is no qualified alias since we need to flatten the internal array on return. + if (get_decoration_bitset(var.self).get(DecorationLocation)) + { + uint32_t locn = get_decoration(var.self, DecorationLocation); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); + mark_location_as_used_by_shader(locn, StorageClassInput); + } + else if (vtx_attrs_by_builtin.count(builtin)) + { + uint32_t locn = vtx_attrs_by_builtin[builtin]->location; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); + mark_location_as_used_by_shader(locn, StorageClassInput); + } + + added_builtin_tess_level = true; + } + + switch (builtin) + { + case BuiltInTessLevelOuter: + entry_func.fixup_hooks_in.push_back([=, &var]() { + statement(to_name(var.self), "[0] = ", ib_var_ref, ".", mbr_name, ".x;"); + statement(to_name(var.self), "[1] = ", ib_var_ref, ".", mbr_name, ".y;"); + statement(to_name(var.self), "[2] = ", ib_var_ref, ".", mbr_name, ".z;"); + }); + break; + + case BuiltInTessLevelInner: + entry_func.fixup_hooks_in.push_back( + [=, &var]() { statement(to_name(var.self), "[0] = ", ib_var_ref, ".", mbr_name, ".w;"); }); + break; + + default: + assert(false); + break; + } + } + else + { + // Add a reference to the variable type to the interface struct. + uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size()); + + uint32_t type_id = build_extended_vector_type(var_type.self, builtin == BuiltInTessLevelOuter ? 4 : 2); + // Change the type of the variable, too. + uint32_t ptr_type_id = ir.increase_bound_by(1); + auto &new_var_type = set(ptr_type_id, get(type_id)); + new_var_type.pointer = true; + new_var_type.storage = StorageClassInput; + new_var_type.parent_type = type_id; + var.basetype = ptr_type_id; + + ib_type.member_types.push_back(type_id); + + // Give the member a name + string mbr_name = to_expression(var.self); + set_member_name(ib_type.self, ib_mbr_idx, mbr_name); + + // Since vectors can be indexed like arrays, there is no need to unpack this. We can + // just refer to the vector directly. So give it a qualified alias. + string qual_var_name = ib_var_ref + "." + mbr_name; + ir.meta[var.self].decoration.qualified_alias = qual_var_name; + + if (get_decoration_bitset(var.self).get(DecorationLocation)) + { + uint32_t locn = get_decoration(var.self, DecorationLocation); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); + mark_location_as_used_by_shader(locn, StorageClassInput); + } + else if (vtx_attrs_by_builtin.count(builtin)) + { + uint32_t locn = vtx_attrs_by_builtin[builtin]->location; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); + mark_location_as_used_by_shader(locn, StorageClassInput); + } + } +} + void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var, bool strip_array) { @@ -1598,6 +1711,8 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st // usually declared as arrays. In these cases, we want to add the element type to the // interface block, since in Metal it's the interface block itself which is arrayed. auto &var_type = strip_array ? get_variable_element_type(var) : get_variable_data_type(var); + bool is_builtin = is_builtin_variable(var); + auto builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); if (var_type.basetype == SPIRType::Struct) { @@ -1627,8 +1742,8 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st // Flatten the struct members into the interface struct for (uint32_t mbr_idx = 0; mbr_idx < uint32_t(var_type.member_types.size()); mbr_idx++) { - BuiltIn builtin = BuiltInMax; - bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); + builtin = BuiltInMax; + is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); auto &mbr_type = get(var_type.member_types[mbr_idx]); if (!is_builtin || has_active_builtin(builtin, storage)) @@ -1650,12 +1765,14 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st } } } + else if (get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput && + !strip_array && is_builtin && (builtin == BuiltInTessLevelOuter || builtin == BuiltInTessLevelInner)) + { + add_tess_level_input_to_interface_block(ib_var_ref, ib_type, var); + } else if (var_type.basetype == SPIRType::Boolean || var_type.basetype == SPIRType::Char || type_is_integral(var_type) || type_is_floating_point(var_type) || var_type.basetype == SPIRType::Boolean) { - bool is_builtin = is_builtin_variable(var); - BuiltIn builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); - if (!is_builtin || has_active_builtin(builtin, storage)) { // MSL does not allow matrices or arrays in input or output variables, so need to handle it specially. @@ -1796,6 +1913,9 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) statement(" ", input_wg_var_name, "[", to_expression(builtin_invocation_id_id), "] = ", ib_var_ref, ";"); statement("threadgroup_barrier(mem_flags::mem_threadgroup);"); + statement("if (", to_expression(builtin_invocation_id_id), " >= ", get_entry_point().output_vertices, + ")"); + statement(" return;"); }); } break; @@ -6526,7 +6646,13 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInTessLevelOuter: if (get_execution_model() == ExecutionModelTessellationEvaluation) - break; + { + if (storage != StorageClassOutput && !get_entry_point().flags.get(ExecutionModeTriangles) && + current_function && (current_function->self == ir.default_entry_point)) + return join(patch_stage_in_var_name, ".", CompilerGLSL::builtin_to_glsl(builtin, storage)); + else + break; + } if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point)) return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id), "].edgeTessellationFactor"); @@ -6534,7 +6660,13 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInTessLevelInner: if (get_execution_model() == ExecutionModelTessellationEvaluation) - break; + { + if (storage != StorageClassOutput && !get_entry_point().flags.get(ExecutionModeTriangles) && + current_function && (current_function->self == ir.default_entry_point)) + return join(patch_stage_in_var_name, ".", CompilerGLSL::builtin_to_glsl(builtin, storage)); + else + break; + } if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point)) return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id), "].insideTessellationFactor"); @@ -6659,6 +6791,7 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) // Returns an MSL string type declaration for a SPIR-V builtin string CompilerMSL::builtin_type_decl(BuiltIn builtin) { + const SPIREntryPoint &execution = get_entry_point(); switch (builtin) { // Vertex function in @@ -6701,13 +6834,17 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin) // Tess. control function out case BuiltInTessLevelInner: + if (execution.model == ExecutionModelTessellationEvaluation) + return !execution.flags.get(ExecutionModeTriangles) ? "float2" : "float"; return "half"; case BuiltInTessLevelOuter: + if (execution.model == ExecutionModelTessellationEvaluation) + return !execution.flags.get(ExecutionModeTriangles) ? "float4" : "float"; return "half"; // Tess. evaluation function in case BuiltInTessCoord: - return get_entry_point().flags.get(ExecutionModeTriangles) ? "float3" : "float2"; + return execution.flags.get(ExecutionModeTriangles) ? "float3" : "float2"; // Fragment function in case BuiltInFrontFacing: @@ -7226,7 +7363,8 @@ void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &exp case BuiltInTessLevelInner: case BuiltInTessLevelOuter: - expected_type = SPIRType::Half; + if (get_execution_model() == ExecutionModelTessellationControl) + expected_type = SPIRType::Half; break; default: diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index c462a62b8..c0e5ecf29 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -422,6 +422,7 @@ protected: SPIRType &ib_type, SPIRVariable &var, uint32_t index, bool strip_array); uint32_t get_accumulated_member_location(const SPIRVariable &var, uint32_t mbr_idx, bool strip_array); + void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var); void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id); @@ -516,6 +517,7 @@ protected: bool capture_output_to_buffer = false; bool needs_aux_buffer_def = false; bool used_aux_buffer = false; + bool added_builtin_tess_level = false; std::string qual_pos_var_name; std::string stage_in_var_name = "in"; std::string stage_out_var_name = "out"; diff --git a/3rdparty/spirv-cross/spirv_reflect.cpp b/3rdparty/spirv-cross/spirv_reflect.cpp index 43c416caf..1e042a9a3 100644 --- a/3rdparty/spirv-cross/spirv_reflect.cpp +++ b/3rdparty/spirv-cross/spirv_reflect.cpp @@ -247,9 +247,6 @@ void CompilerReflection::set_format(const std::string &format) string CompilerReflection::compile() { - // Force a classic "C" locale, reverts when function returns - ClassicLocale classic_locale; - // Move constructor for this type is broken on GCC 4.9 ... json_stream = std::make_shared(); json_stream->begin_json_object();