diff --git a/reference/opt/shaders-msl/tese/in-block-with-nested-struct.tese b/reference/opt/shaders-msl/tese/in-block-with-nested-struct.tese new file mode 100644 index 00000000..f177debf --- /dev/null +++ b/reference/opt/shaders-msl/tese/in-block-with-nested-struct.tese @@ -0,0 +1,43 @@ +#include +#include + +using namespace metal; + +struct _RESERVED_IDENTIFIER_FIXUP_35 +{ + float2 _RESERVED_IDENTIFIER_FIXUP_m0; + float4 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct _RESERVED_IDENTIFIER_FIXUP_36 +{ + float2 _RESERVED_IDENTIFIER_FIXUP_m0; + _RESERVED_IDENTIFIER_FIXUP_35 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct main0_out +{ + float _RESERVED_IDENTIFIER_FIXUP_80 [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float2 _RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m0 [[attribute(0)]]; + float2 _RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m0 [[attribute(1)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1 [[attribute(2)]]; +}; + +struct main0_patchIn +{ + patch_control_point gl_in; +}; + +[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]]) +{ + main0_out out = {}; + out.gl_Position = float4((gl_TessCoord.xy * 2.0) - float2(1.0), 0.0, 1.0); + out._RESERVED_IDENTIFIER_FIXUP_80 = ((float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.x - (-4.0)) < 0.001000000047497451305389404296875) * float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.y - (-9.0)) < 0.001000000047497451305389404296875)) * float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.z - 3.0) < 0.001000000047497451305389404296875)) * float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.w - 7.0) < 0.001000000047497451305389404296875); + return out; +} + diff --git a/reference/opt/shaders-msl/vert/out-block-with-nested-struct-array.vert b/reference/opt/shaders-msl/vert/out-block-with-nested-struct-array.vert new file mode 100644 index 00000000..5a42d8d8 --- /dev/null +++ b/reference/opt/shaders-msl/vert/out-block-with-nested-struct-array.vert @@ -0,0 +1,88 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wmissing-braces" + +#include +#include + +using namespace metal; + +template +struct spvUnsafeArray +{ + T elements[Num ? Num : 1]; + + thread T& operator [] (size_t pos) thread + { + return elements[pos]; + } + constexpr const thread T& operator [] (size_t pos) const thread + { + return elements[pos]; + } + + device T& operator [] (size_t pos) device + { + return elements[pos]; + } + constexpr const device T& operator [] (size_t pos) const device + { + return elements[pos]; + } + + constexpr const constant T& operator [] (size_t pos) const constant + { + return elements[pos]; + } + + threadgroup T& operator [] (size_t pos) threadgroup + { + return elements[pos]; + } + constexpr const threadgroup T& operator [] (size_t pos) const threadgroup + { + return elements[pos]; + } +}; + +struct _RESERVED_IDENTIFIER_FIXUP_21 +{ + float4 _RESERVED_IDENTIFIER_FIXUP_m0; + float4 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct _RESERVED_IDENTIFIER_FIXUP_24 +{ + spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_21, 3> _RESERVED_IDENTIFIER_FIXUP_m0; +}; + +struct main0_out +{ + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn0)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn1)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn2)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn3)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn4)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn5)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float4 _RESERVED_IDENTIFIER_FIXUP_17 [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + _RESERVED_IDENTIFIER_FIXUP_24 _RESERVED_IDENTIFIER_FIXUP_26 = {}; + out.gl_Position = in._RESERVED_IDENTIFIER_FIXUP_17; + _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[1]._RESERVED_IDENTIFIER_FIXUP_m1 = float4(-4.0, -9.0, 3.0, 7.0); + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[0]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[0]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[1]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[1]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[2]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[2]._RESERVED_IDENTIFIER_FIXUP_m1; + return out; +} + diff --git a/reference/opt/shaders-msl/vert/out-block-with-struct-array.vert b/reference/opt/shaders-msl/vert/out-block-with-struct-array.vert new file mode 100644 index 00000000..d9a35c4f --- /dev/null +++ b/reference/opt/shaders-msl/vert/out-block-with-struct-array.vert @@ -0,0 +1,83 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wmissing-braces" + +#include +#include + +using namespace metal; + +template +struct spvUnsafeArray +{ + T elements[Num ? Num : 1]; + + thread T& operator [] (size_t pos) thread + { + return elements[pos]; + } + constexpr const thread T& operator [] (size_t pos) const thread + { + return elements[pos]; + } + + device T& operator [] (size_t pos) device + { + return elements[pos]; + } + constexpr const device T& operator [] (size_t pos) const device + { + return elements[pos]; + } + + constexpr const constant T& operator [] (size_t pos) const constant + { + return elements[pos]; + } + + threadgroup T& operator [] (size_t pos) threadgroup + { + return elements[pos]; + } + constexpr const threadgroup T& operator [] (size_t pos) const threadgroup + { + return elements[pos]; + } +}; + +struct _RESERVED_IDENTIFIER_FIXUP_21 +{ + float _RESERVED_IDENTIFIER_FIXUP_m0; + float4 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct main0_out +{ + float _RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn0)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn1)]]; + float _RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn2)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn3)]]; + float _RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn4)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn5)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float4 _RESERVED_IDENTIFIER_FIXUP_17 [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_21, 3> _RESERVED_IDENTIFIER_FIXUP_25 = {}; + out.gl_Position = in._RESERVED_IDENTIFIER_FIXUP_17; + _RESERVED_IDENTIFIER_FIXUP_25[2]._RESERVED_IDENTIFIER_FIXUP_m1 = float4(-4.0, -9.0, 3.0, 7.0); + out._RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_25[0]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_25[0]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_25[1]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_25[1]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_25[2]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_25[2]._RESERVED_IDENTIFIER_FIXUP_m1; + return out; +} + diff --git a/reference/shaders-msl/tese/in-block-with-nested-struct.tese b/reference/shaders-msl/tese/in-block-with-nested-struct.tese new file mode 100644 index 00000000..097df3bd --- /dev/null +++ b/reference/shaders-msl/tese/in-block-with-nested-struct.tese @@ -0,0 +1,44 @@ +#include +#include + +using namespace metal; + +struct _RESERVED_IDENTIFIER_FIXUP_35 +{ + float2 _RESERVED_IDENTIFIER_FIXUP_m0; + float4 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct _RESERVED_IDENTIFIER_FIXUP_36 +{ + float2 _RESERVED_IDENTIFIER_FIXUP_m0; + _RESERVED_IDENTIFIER_FIXUP_35 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct main0_out +{ + float _RESERVED_IDENTIFIER_FIXUP_80 [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float2 _RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m0 [[attribute(0)]]; + float2 _RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m0 [[attribute(1)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1 [[attribute(2)]]; +}; + +struct main0_patchIn +{ + patch_control_point gl_in; +}; + +[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]]) +{ + main0_out out = {}; + out.gl_Position = float4((gl_TessCoord.xy * 2.0) - float2(1.0), 0.0, 1.0); + float _RESERVED_IDENTIFIER_FIXUP_34 = ((float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.x - (-4.0)) < 0.001000000047497451305389404296875) * float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.y - (-9.0)) < 0.001000000047497451305389404296875)) * float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.z - 3.0) < 0.001000000047497451305389404296875)) * float(abs(patchIn.gl_in[0]._RESERVED_IDENTIFIER_FIXUP_36_RESERVED_IDENTIFIER_FIXUP_m1_RESERVED_IDENTIFIER_FIXUP_m1.w - 7.0) < 0.001000000047497451305389404296875); + out._RESERVED_IDENTIFIER_FIXUP_80 = _RESERVED_IDENTIFIER_FIXUP_34; + return out; +} + diff --git a/reference/shaders-msl/vert/out-block-with-nested-struct-array.vert b/reference/shaders-msl/vert/out-block-with-nested-struct-array.vert new file mode 100644 index 00000000..5a42d8d8 --- /dev/null +++ b/reference/shaders-msl/vert/out-block-with-nested-struct-array.vert @@ -0,0 +1,88 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wmissing-braces" + +#include +#include + +using namespace metal; + +template +struct spvUnsafeArray +{ + T elements[Num ? Num : 1]; + + thread T& operator [] (size_t pos) thread + { + return elements[pos]; + } + constexpr const thread T& operator [] (size_t pos) const thread + { + return elements[pos]; + } + + device T& operator [] (size_t pos) device + { + return elements[pos]; + } + constexpr const device T& operator [] (size_t pos) const device + { + return elements[pos]; + } + + constexpr const constant T& operator [] (size_t pos) const constant + { + return elements[pos]; + } + + threadgroup T& operator [] (size_t pos) threadgroup + { + return elements[pos]; + } + constexpr const threadgroup T& operator [] (size_t pos) const threadgroup + { + return elements[pos]; + } +}; + +struct _RESERVED_IDENTIFIER_FIXUP_21 +{ + float4 _RESERVED_IDENTIFIER_FIXUP_m0; + float4 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct _RESERVED_IDENTIFIER_FIXUP_24 +{ + spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_21, 3> _RESERVED_IDENTIFIER_FIXUP_m0; +}; + +struct main0_out +{ + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn0)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn1)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn2)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn3)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn4)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn5)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float4 _RESERVED_IDENTIFIER_FIXUP_17 [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + _RESERVED_IDENTIFIER_FIXUP_24 _RESERVED_IDENTIFIER_FIXUP_26 = {}; + out.gl_Position = in._RESERVED_IDENTIFIER_FIXUP_17; + _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[1]._RESERVED_IDENTIFIER_FIXUP_m1 = float4(-4.0, -9.0, 3.0, 7.0); + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[0]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_0_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[0]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[1]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_1_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[1]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[2]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_24_RESERVED_IDENTIFIER_FIXUP_m0_2_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_26._RESERVED_IDENTIFIER_FIXUP_m0[2]._RESERVED_IDENTIFIER_FIXUP_m1; + return out; +} + diff --git a/reference/shaders-msl/vert/out-block-with-struct-array.vert b/reference/shaders-msl/vert/out-block-with-struct-array.vert new file mode 100644 index 00000000..d9a35c4f --- /dev/null +++ b/reference/shaders-msl/vert/out-block-with-struct-array.vert @@ -0,0 +1,83 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wmissing-braces" + +#include +#include + +using namespace metal; + +template +struct spvUnsafeArray +{ + T elements[Num ? Num : 1]; + + thread T& operator [] (size_t pos) thread + { + return elements[pos]; + } + constexpr const thread T& operator [] (size_t pos) const thread + { + return elements[pos]; + } + + device T& operator [] (size_t pos) device + { + return elements[pos]; + } + constexpr const device T& operator [] (size_t pos) const device + { + return elements[pos]; + } + + constexpr const constant T& operator [] (size_t pos) const constant + { + return elements[pos]; + } + + threadgroup T& operator [] (size_t pos) threadgroup + { + return elements[pos]; + } + constexpr const threadgroup T& operator [] (size_t pos) const threadgroup + { + return elements[pos]; + } +}; + +struct _RESERVED_IDENTIFIER_FIXUP_21 +{ + float _RESERVED_IDENTIFIER_FIXUP_m0; + float4 _RESERVED_IDENTIFIER_FIXUP_m1; +}; + +struct main0_out +{ + float _RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn0)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn1)]]; + float _RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn2)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn3)]]; + float _RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m0 [[user(locn4)]]; + float4 _RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m1 [[user(locn5)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float4 _RESERVED_IDENTIFIER_FIXUP_17 [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_21, 3> _RESERVED_IDENTIFIER_FIXUP_25 = {}; + out.gl_Position = in._RESERVED_IDENTIFIER_FIXUP_17; + _RESERVED_IDENTIFIER_FIXUP_25[2]._RESERVED_IDENTIFIER_FIXUP_m1 = float4(-4.0, -9.0, 3.0, 7.0); + out._RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_25[0]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_21_0_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_25[0]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_25[1]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_21_1_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_25[1]._RESERVED_IDENTIFIER_FIXUP_m1; + out._RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m0 = _RESERVED_IDENTIFIER_FIXUP_25[2]._RESERVED_IDENTIFIER_FIXUP_m0; + out._RESERVED_IDENTIFIER_FIXUP_21_2_RESERVED_IDENTIFIER_FIXUP_m1 = _RESERVED_IDENTIFIER_FIXUP_25[2]._RESERVED_IDENTIFIER_FIXUP_m1; + return out; +} + diff --git a/shaders-msl/tese/in-block-with-nested-struct.tese b/shaders-msl/tese/in-block-with-nested-struct.tese new file mode 100644 index 00000000..6a41d274 --- /dev/null +++ b/shaders-msl/tese/in-block-with-nested-struct.tese @@ -0,0 +1,31 @@ +#version 450 +layout(triangles, ccw, equal_spacing) in; + +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[1]; + float gl_CullDistance[1]; +}; + +struct _35 +{ + vec2 _m0; + vec4 _m1; +}; + +layout(location = 0) in _36 +{ + vec2 _m0; + _35 _m1; +} _40[32]; + +layout(location = 0) out float _80; + +void main() +{ + gl_Position = vec4((gl_TessCoord.xy * 2.0) - vec2(1.0), 0.0, 1.0); + float _34 = ((float(abs(_40[0]._m1._m1.x - (-4.0)) < 0.001000000047497451305389404296875) * float(abs(_40[0]._m1._m1.y - (-9.0)) < 0.001000000047497451305389404296875)) * float(abs(_40[0]._m1._m1.z - 3.0) < 0.001000000047497451305389404296875)) * float(abs(_40[0]._m1._m1.w - 7.0) < 0.001000000047497451305389404296875); + _80 = _34; +} diff --git a/shaders-msl/vert/out-block-with-nested-struct-array.vert b/shaders-msl/vert/out-block-with-nested-struct-array.vert new file mode 100644 index 00000000..592a5271 --- /dev/null +++ b/shaders-msl/vert/out-block-with-nested-struct-array.vert @@ -0,0 +1,28 @@ +#version 450 + +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[1]; + float gl_CullDistance[1]; +}; + +struct _21 +{ + vec4 _m0; + vec4 _m1; +}; + +layout(location = 0) in vec4 _17; +layout(location = 0) out _24 +{ + _21 _m0[3]; +} _26; + + +void main() +{ + gl_Position = _17; + _26._m0[1]._m1 = vec4(-4.0, -9.0, 3.0, 7.0); +} diff --git a/shaders-msl/vert/out-block-with-struct-array.vert b/shaders-msl/vert/out-block-with-struct-array.vert new file mode 100644 index 00000000..8b8029f7 --- /dev/null +++ b/shaders-msl/vert/out-block-with-struct-array.vert @@ -0,0 +1,24 @@ +#version 450 + +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[1]; + float gl_CullDistance[1]; +}; + +struct _21 +{ + float _m0; + vec4 _m1; +}; + +layout(location = 0) in vec4 _17; +layout(location = 0) out _21 _25[3]; + +void main() +{ + gl_Position = _17; + _25[2]._m1 = vec4(-4.0, -9.0, 3.0, 7.0); +} diff --git a/spirv_msl.cpp b/spirv_msl.cpp index d125aeaf..e68deffa 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -2508,12 +2508,15 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage } } -void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass storage, const string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, - uint32_t mbr_idx, InterfaceBlockMeta &meta) +void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass storage, + const string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const string &mbr_name_qual, + const string &var_chain_qual, + uint32_t& location, uint32_t& var_mbr_idx) { auto &entry_func = get(ir.default_entry_point); - auto &var_type = meta.strip_array ? get_variable_element_type(var) : get_variable_data_type(var); BuiltIn builtin = BuiltInMax; bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); @@ -2528,8 +2531,8 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass uint32_t mbr_type_id = var_type.member_types[mbr_idx]; auto &mbr_type = get(mbr_type_id); - uint32_t elem_cnt = 0; + uint32_t elem_cnt = 1; if (is_matrix(mbr_type)) { if (is_array(mbr_type)) @@ -2572,6 +2575,26 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass return; } + // Recursively handle nested structures. + if (mbr_type.basetype == SPIRType::Struct) + { + for (uint32_t i = 0; i < elem_cnt; i++) + { + string mbr_name = append_member_name(mbr_name_qual, var_type, mbr_idx) + (elem_cnt == 1 ? "" : join("_", i)); + string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (elem_cnt == 1 ? "" : join("[", i, "]"))); + uint32_t sub_mbr_cnt = uint32_t(mbr_type.member_types.size()); + for (uint32_t sub_mbr_idx = 0; sub_mbr_idx < sub_mbr_cnt; sub_mbr_idx++) + { + add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, + var, mbr_type, sub_mbr_idx, + meta, mbr_name, var_chain, + location, var_mbr_idx); + var_mbr_idx++; + } + } + return; + } + for (uint32_t i = 0; i < elem_cnt; i++) { // Add a reference to the variable type to the interface struct. @@ -2582,26 +2605,38 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass ib_type.member_types.push_back(usable_type->self); // Give the member a name - string mbr_name = ensure_valid_name(join(to_qualified_member_name(var_type, mbr_idx), "_", i), "m"); + string mbr_name = ensure_valid_name(append_member_name(mbr_name_qual, var_type, mbr_idx) + (elem_cnt == 1 ? "" : join("_", i)), "m"); set_member_name(ib_type.self, ib_mbr_idx, mbr_name); - if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + // Once we determine the location of the first member within nested structures, + // from a var of the topmost structure, the remaining flattened members of the + // nested structures will have consecutive location values. + if (!is_builtin && location) { - uint32_t locn = get_member_decoration(var_type.self, mbr_idx, DecorationLocation) + i; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, *usable_type, storage); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; + } + else if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + { + location = get_member_decoration(var_type.self, mbr_idx, DecorationLocation) + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; } else if (has_decoration(var.self, DecorationLocation)) { - uint32_t locn = get_accumulated_member_location(var, mbr_idx, meta.strip_array) + i; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, *usable_type, storage); + location = get_accumulated_member_location(var, mbr_idx, meta.strip_array) + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; } else if (is_builtin && is_tessellation_shader() && storage == StorageClassInput && inputs_by_builtin.count(builtin)) { - uint32_t locn = inputs_by_builtin[builtin].location + i; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, *usable_type, storage); + location = inputs_by_builtin[builtin].location + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; } else if (is_builtin && (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance)) { @@ -2611,7 +2646,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass } if (has_member_decoration(var_type.self, mbr_idx, DecorationComponent)) - SPIRV_CROSS_THROW("DecorationComponent on matrices and arrays make little sense."); + SPIRV_CROSS_THROW("DecorationComponent on matrices and arrays is not supported."); if (storage != StorageClassInput || !pull_model_inputs.count(var.self)) { @@ -2627,47 +2662,36 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass } set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceOrigID, var.self); - set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, mbr_idx); + set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, var_mbr_idx); // Unflatten or flatten from [[stage_in]] or [[stage_out]] as appropriate. if (!meta.strip_array && meta.allow_local_declaration) { + string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (elem_cnt == 1 ? "" : join("[", i, "]"))); switch (storage) { case StorageClassInput: - entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() { + entry_func.fixup_hooks_in.push_back([=, &var]() { + string lerp_call; if (pull_model_inputs.count(var.self)) { - string lerp_call; if (is_centroid) lerp_call = ".interpolate_at_centroid()"; else if (is_sample) lerp_call = join(".interpolate_at_sample(", to_expression(builtin_sample_id_id), ")"); else lerp_call = ".interpolate_at_center()"; - statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref, - ".", mbr_name, lerp_call, ";"); - } - else - { - statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref, - ".", mbr_name, ";"); } + statement(var_chain, " = ", ib_var_ref, ".", mbr_name, lerp_call, ";"); }); break; case StorageClassOutput: - entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() { + entry_func.fixup_hooks_out.push_back([=]() { if (flatten_from_ib_var) - { - statement(ib_var_ref, ".", mbr_name, " = ", ib_var_ref, ".", flatten_from_ib_mbr_name, "[", i, - "];"); - } + statement(ib_var_ref, ".", mbr_name, " = ", ib_var_ref, ".", flatten_from_ib_mbr_name, "[", i, "];"); else - { - statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), ".", - to_member_name(var_type, mbr_idx), "[", i, "];"); - } + statement(ib_var_ref, ".", mbr_name, " = ", var_chain, ";"); }); break; @@ -2678,11 +2702,14 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass } } -void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass storage, const string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, uint32_t mbr_idx, - InterfaceBlockMeta &meta) +void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass storage, + const string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const string &mbr_name_qual, + const string &var_chain_qual, + uint32_t& location, uint32_t& var_mbr_idx) { - auto &var_type = meta.strip_array ? get_variable_element_type(var) : get_variable_data_type(var); auto &entry_func = get(ir.default_entry_point); BuiltIn builtin = BuiltInMax; @@ -2707,7 +2734,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor ib_type.member_types.push_back(mbr_type_id); // Give the member a name - string mbr_name = ensure_valid_name(to_qualified_member_name(var_type, mbr_idx), "m"); + string mbr_name = ensure_valid_name(append_member_name(mbr_name_qual, var_type, mbr_idx), "m"); set_member_name(ib_type.self, ib_mbr_idx, mbr_name); // Update the original variable reference to include the structure reference @@ -2724,7 +2751,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor } bool flatten_stage_out = false; - + string var_chain = var_chain_qual + "." + to_member_name(var_type, mbr_idx); if (is_builtin && !meta.strip_array) { // For the builtin gl_PerVertex, we cannot treat it as a block anyways, @@ -2737,15 +2764,15 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor switch (storage) { case StorageClassInput: - entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() { - statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), " = ", qual_var_name, ";"); + entry_func.fixup_hooks_in.push_back([=]() { + statement(var_chain, " = ", qual_var_name, ";"); }); break; case StorageClassOutput: flatten_stage_out = true; - entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() { - statement(qual_var_name, " = ", to_name(var.self), ".", to_member_name(var_type, mbr_idx), ";"); + entry_func.fixup_hooks_out.push_back([=]() { + statement(qual_var_name, " = ", var_chain, ";"); }); break; @@ -2754,48 +2781,54 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor } } - // Copy the variable location from the original variable to the member - if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + // Once we determine the location of the first member within nested structures, + // from a var of the topmost structure, the remaining flattened members of the + // nested structures will have consecutive location values. + if (!is_builtin && location) { - uint32_t locn = get_member_decoration(var_type.self, mbr_idx, DecorationLocation); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location++; + } + else if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + { + location = get_member_decoration(var_type.self, mbr_idx, DecorationLocation); uint32_t comp = get_member_decoration(var_type.self, mbr_idx, DecorationComponent); if (storage == StorageClassInput) { - mbr_type_id = ensure_correct_input_type(mbr_type_id, locn, comp, 0, meta.strip_array); + mbr_type_id = ensure_correct_input_type(mbr_type_id, location, comp, 0, meta.strip_array); var_type.member_types[mbr_idx] = mbr_type_id; if (storage == StorageClassInput && pull_model_inputs.count(var.self)) ib_type.member_types[ib_mbr_idx] = build_msl_interpolant_type(mbr_type_id, is_noperspective); else ib_type.member_types[ib_mbr_idx] = mbr_type_id; } - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, get(mbr_type_id), storage); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location++; } else if (has_decoration(var.self, DecorationLocation)) { - // The block itself might have a location and in this case, all members of the block - // receive incrementing locations. - uint32_t locn = get_accumulated_member_location(var, mbr_idx, meta.strip_array); + location = get_accumulated_member_location(var, mbr_idx, meta.strip_array); if (storage == StorageClassInput) { - mbr_type_id = ensure_correct_input_type(mbr_type_id, locn, 0, 0, meta.strip_array); + mbr_type_id = ensure_correct_input_type(mbr_type_id, location, 0, 0, meta.strip_array); var_type.member_types[mbr_idx] = mbr_type_id; if (storage == StorageClassInput && pull_model_inputs.count(var.self)) ib_type.member_types[ib_mbr_idx] = build_msl_interpolant_type(mbr_type_id, is_noperspective); else ib_type.member_types[ib_mbr_idx] = mbr_type_id; } - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, get(mbr_type_id), storage); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location++; } else if (is_builtin && is_tessellation_shader() && storage == StorageClassInput && inputs_by_builtin.count(builtin)) { - uint32_t locn = 0; - auto builtin_itr = inputs_by_builtin.find(builtin); - if (builtin_itr != end(inputs_by_builtin)) - locn = builtin_itr->second.location; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, get(mbr_type_id), storage); + location = inputs_by_builtin[builtin].location; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location++; } // Copy the component location, if present. @@ -2854,7 +2887,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor } set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceOrigID, var.self); - set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, mbr_idx); + set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, var_mbr_idx); } // In Metal, the tessellation levels are stored as tightly packed half-precision floating point values. @@ -3114,67 +3147,98 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st else { bool masked_block = false; - - // 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++) + uint32_t location = 0; + uint32_t var_mbr_idx = 0; + uint32_t elem_cnt = 1; + if (is_matrix(var_type)) { - builtin = BuiltInMax; - is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); - auto &mbr_type = get(var_type.member_types[mbr_idx]); + if (is_array(var_type)) + SPIRV_CROSS_THROW("MSL cannot emit arrays-of-matrices in input and output variables."); - if (storage == StorageClassOutput && is_stage_output_block_member_masked(var, mbr_idx, meta.strip_array)) + elem_cnt = var_type.columns; + } + else if (is_array(var_type)) + { + if (var_type.array.size() != 1) + SPIRV_CROSS_THROW("MSL cannot emit arrays-of-arrays in input and output variables."); + + elem_cnt = to_array_size_literal(var_type); + } + + for (uint32_t elem_idx = 0; elem_idx < elem_cnt; elem_idx++) + { + // 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++) { - if (is_block) - masked_block = true; + builtin = BuiltInMax; + is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); + auto &mbr_type = get(var_type.member_types[mbr_idx]); - // Non-builtin block output variables are just ignored, since they will still access - // the block variable as-is. They're just not flattened. - if (is_builtin && !meta.strip_array) + if (storage == StorageClassOutput && is_stage_output_block_member_masked(var, mbr_idx, meta.strip_array)) { - // Emit a fake variable instead. - uint32_t ids = ir.increase_bound_by(2); - uint32_t ptr_type_id = ids + 0; - uint32_t var_id = ids + 1; + location++; // Skip this location - auto ptr_type = mbr_type; - ptr_type.pointer = true; - ptr_type.pointer_depth++; - ptr_type.parent_type = var_type.member_types[mbr_idx]; - ptr_type.storage = StorageClassOutput; + if (is_block) + masked_block = true; - uint32_t initializer = 0; - if (var.initializer) - if (auto *c = maybe_get(var.initializer)) - initializer = c->subconstants[mbr_idx]; + // Non-builtin block output variables are just ignored, since they will still access + // the block variable as-is. They're just not flattened. + if (is_builtin && !meta.strip_array) + { + // Emit a fake variable instead. + uint32_t ids = ir.increase_bound_by(2); + uint32_t ptr_type_id = ids + 0; + uint32_t var_id = ids + 1; - set(ptr_type_id, ptr_type); - set(var_id, ptr_type_id, StorageClassOutput, initializer); - entry_func.add_local_variable(var_id); - vars_needing_early_declaration.push_back(var_id); - set_name(var_id, builtin_to_glsl(builtin, StorageClassOutput)); - set_decoration(var_id, DecorationBuiltIn, builtin); + auto ptr_type = mbr_type; + ptr_type.pointer = true; + ptr_type.pointer_depth++; + ptr_type.parent_type = var_type.member_types[mbr_idx]; + ptr_type.storage = StorageClassOutput; + + uint32_t initializer = 0; + if (var.initializer) + if (auto *c = maybe_get(var.initializer)) + initializer = c->subconstants[mbr_idx]; + + set(ptr_type_id, ptr_type); + set(var_id, ptr_type_id, StorageClassOutput, initializer); + entry_func.add_local_variable(var_id); + vars_needing_early_declaration.push_back(var_id); + set_name(var_id, builtin_to_glsl(builtin, StorageClassOutput)); + set_decoration(var_id, DecorationBuiltIn, builtin); + } } - } - else if (!is_builtin || has_active_builtin(builtin, storage)) - { - bool is_composite_type = is_matrix(mbr_type) || is_array(mbr_type); - bool attribute_load_store = - storage == StorageClassInput && get_execution_model() != ExecutionModelFragment; - bool storage_is_stage_io = variable_storage_requires_stage_io(storage); - - // Clip/CullDistance always need to be declared as user attributes. - if (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance) - is_builtin = false; - - if ((!is_builtin || attribute_load_store) && storage_is_stage_io && is_composite_type) + else if (!is_builtin || has_active_builtin(builtin, storage)) { - add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_idx, - meta); - } - else - { - add_plain_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_idx, meta); + bool is_composite_type = is_matrix(mbr_type) || is_array(mbr_type) || mbr_type.basetype == SPIRType::Struct; + bool attribute_load_store = + storage == StorageClassInput && get_execution_model() != ExecutionModelFragment; + bool storage_is_stage_io = variable_storage_requires_stage_io(storage); + + // Clip/CullDistance always need to be declared as user attributes. + if (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance) + is_builtin = false; + + string mbr_name_qual = to_name(var_type.self) + (elem_cnt == 1 ? "" : join("_", elem_idx)); + string var_chain_qual = to_name(var.self) + (elem_cnt == 1 ? "" : join("[", elem_idx, "]")); + + if ((!is_builtin || attribute_load_store) && storage_is_stage_io && is_composite_type) + { + add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, + var, var_type, mbr_idx, meta, + mbr_name_qual, var_chain_qual, + location, var_mbr_idx); + } + else + { + add_plain_member_variable_to_interface_block(storage, ib_var_ref, ib_type, + var, var_type, mbr_idx, meta, + mbr_name_qual, var_chain_qual, + location, var_mbr_idx); + } } + var_mbr_idx++; } } @@ -12982,8 +13046,8 @@ string CompilerMSL::to_name(uint32_t id, bool allow_alias) const return Compiler::to_name(id, allow_alias); } -// Returns a name that combines the name of the struct with the name of the member, except for Builtins -string CompilerMSL::to_qualified_member_name(const SPIRType &type, uint32_t index) +// Appends the name of the member to the variable qualifier string, except for Builtins. +string CompilerMSL::append_member_name(const string qualifier, const SPIRType &type, uint32_t index) { // Don't qualify Builtin names because they are unique and are treated as such when building expressions BuiltIn builtin = BuiltInMax; @@ -12994,7 +13058,7 @@ string CompilerMSL::to_qualified_member_name(const SPIRType &type, uint32_t inde string mbr_name = to_member_name(type, index); size_t startPos = mbr_name.find_first_not_of("_"); mbr_name = (startPos != string::npos) ? mbr_name.substr(startPos) : ""; - return join(to_name(type.self), "_", mbr_name); + return join(qualifier, "_", mbr_name); } // Ensures that the specified name is permanently usable by prepending a prefix diff --git a/spirv_msl.hpp b/spirv_msl.hpp index 641f49e9..174e8230 100644 --- a/spirv_msl.hpp +++ b/spirv_msl.hpp @@ -831,12 +831,20 @@ protected: bool add_component_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, SPIRVariable &var, const SPIRType &type, InterfaceBlockMeta &meta); - void add_plain_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, uint32_t index, - InterfaceBlockMeta &meta); - void add_composite_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, uint32_t index, - InterfaceBlockMeta &meta); + void add_plain_member_variable_to_interface_block(spv::StorageClass storage, + const std::string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const std::string &mbr_name_qual, + const std::string &var_chain_qual, + uint32_t& location, uint32_t& var_mbr_idx); + void add_composite_member_variable_to_interface_block(spv::StorageClass storage, + const std::string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const std::string &mbr_name_qual, + const std::string &var_chain_qual, + uint32_t& location, uint32_t& var_mbr_idx); 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); @@ -863,7 +871,7 @@ protected: std::string entry_point_arg_stage_in(); void entry_point_args_builtin(std::string &args); void entry_point_args_discrete_descriptors(std::string &args); - std::string to_qualified_member_name(const SPIRType &type, uint32_t index); + std::string append_member_name(const std::string qualifier, const SPIRType &type, uint32_t index); std::string ensure_valid_name(std::string name, std::string pfx); std::string to_sampler_expression(uint32_t id); std::string to_swizzle_expression(uint32_t id);