MSL: Support input/output blocks containing nested struct arrays
Fixes numerous CTS tests of types dEQP-VK.pipeline.interface_matching.vector_length.member_of_*, passing complex nested structs between stages as stage I/O. - Make add_composite_member_variable_to_interface_block() recursive to allow struct members to contain nested structs, building up member names and access chains recursively, and only add the resulting flattened leaf members to the synthetic input and output interface blocks. - Recursively generate individual location numbers for the flattened members of the input/output block. - Replace to_qualified_member_name() with append_member_name(). - Update add_variable_to_interface_block() to support arrays as struct members, adding a member to input and output interface blocks for each element of the array. - Pass name qualifiers to add_plain_member_variable_to_interface_block() to allow struct members to be arrays of structs, building up member names and access chains, and adding multiple distinct flattened leaf members to the synthetic input and output interface blocks. - Generate individual location numbers for the individual array members of the input/output block. - SPIRVCrossDecorationInterfaceMemberIndex references the index of a member of a variable that is a struct type. The value is relative to the variable, and for structs nested within that top-level struct, the index value needs to take into consideration the members within those nested structs. - Pass var_mbr_idx to add_plain_member_variable_to_interface_block() and add_composite_member_variable_to_interface_block(), start at zero for each variable, and increment for each member or nested member within that variable. - Add unit test shaders-msl/vert/out-block-with-nested-struct-array.vert - Add unit test shaders-msl/vert/out-block-with-struct-array.vert - Add unit test shaders-msl/tese/in-block-with-nested-struct.tese
This commit is contained in:
parent
d16183d1d2
commit
3d4daab29d
@ -0,0 +1,43 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
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<main0_in> 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;
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
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;
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
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;
|
||||
}
|
||||
|
44
reference/shaders-msl/tese/in-block-with-nested-struct.tese
Normal file
44
reference/shaders-msl/tese/in-block-with-nested-struct.tese
Normal file
@ -0,0 +1,44 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
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<main0_in> 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;
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
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;
|
||||
}
|
||||
|
83
reference/shaders-msl/vert/out-block-with-struct-array.vert
Normal file
83
reference/shaders-msl/vert/out-block-with-struct-array.vert
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
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;
|
||||
}
|
||||
|
31
shaders-msl/tese/in-block-with-nested-struct.tese
Normal file
31
shaders-msl/tese/in-block-with-nested-struct.tese
Normal file
@ -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;
|
||||
}
|
28
shaders-msl/vert/out-block-with-nested-struct-array.vert
Normal file
28
shaders-msl/vert/out-block-with-nested-struct-array.vert
Normal file
@ -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);
|
||||
}
|
24
shaders-msl/vert/out-block-with-struct-array.vert
Normal file
24
shaders-msl/vert/out-block-with-struct-array.vert
Normal file
@ -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);
|
||||
}
|
300
spirv_msl.cpp
300
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<SPIRFunction>(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<SPIRType>(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<SPIRFunction>(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<SPIRType>(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<SPIRType>(mbr_type_id), storage);
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location);
|
||||
mark_location_as_used_by_shader(location, get<SPIRType>(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<SPIRType>(mbr_type_id), storage);
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location);
|
||||
mark_location_as_used_by_shader(location, get<SPIRType>(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<SPIRType>(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<SPIRType>(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<SPIRType>(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<SPIRType>(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<SPIRConstant>(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<SPIRType>(ptr_type_id, ptr_type);
|
||||
set<SPIRVariable>(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<SPIRConstant>(var.initializer))
|
||||
initializer = c->subconstants[mbr_idx];
|
||||
|
||||
set<SPIRType>(ptr_type_id, ptr_type);
|
||||
set<SPIRVariable>(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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user