MSL: Remove over-zealous check for struct packing compatibility.

Previous test for SPIRVCrossDecorationPhysicalTypePacked on parent struct
when unpacking member struct was too restrictive, and not needed as long
as padding compensates.
This commit is contained in:
Bill Hollings 2021-10-28 19:36:32 -04:00
parent 66adba17a8
commit be812c45e5
4 changed files with 161 additions and 10 deletions

View File

@ -0,0 +1,52 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef packed_float4 packed_rm_float4x4[4];
struct s0
{
float3x4 m0;
packed_int4 m1;
packed_rm_float4x4 m2;
packed_uint2 m3;
};
struct s1
{
float4x4 m0;
int m1;
char _m2_pad[12];
packed_uint3 m2;
s0 m3;
};
struct data_u_t
{
float4 m1[5];
float2x4 m3;
int4 m4;
s1 m2;
float3x4 m0;
};
struct main0_out
{
float foo [[user(locn0)]];
float4 gl_Position [[position]];
};
struct main0_in
{
float4 vtx_posn [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant data_u_t& data_u [[buffer(0)]])
{
main0_out out = {};
out.gl_Position = in.vtx_posn;
out.foo = (((data_u.m1[3].y + float(data_u.m4.z)) * data_u.m0[2][1]) * data_u.m2.m0[3][2]) * data_u.m2.m3.m2[3][3];
return out;
}

View File

@ -0,0 +1,57 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef packed_float4 packed_rm_float4x4[4];
struct s0
{
float3x4 m0;
packed_int4 m1;
packed_rm_float4x4 m2;
packed_uint2 m3;
};
struct s1
{
float4x4 m0;
int m1;
char _m2_pad[12];
packed_uint3 m2;
s0 m3;
};
struct data_u_t
{
float4 m1[5];
float2x4 m3;
int4 m4;
s1 m2;
float3x4 m0;
};
struct main0_out
{
float foo [[user(locn0)]];
float4 gl_Position [[position]];
};
struct main0_in
{
float4 vtx_posn [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant data_u_t& data_u [[buffer(0)]])
{
main0_out out = {};
out.gl_Position = in.vtx_posn;
float2 a = data_u.m1[3].xy;
int4 b = data_u.m4;
float2x3 c = transpose(float3x2(data_u.m0[0].xy, data_u.m0[1].xy, data_u.m0[2].xy));
float3x4 d = transpose(float4x3(data_u.m2.m0[0].xyz, data_u.m2.m0[1].xyz, data_u.m2.m0[2].xyz, data_u.m2.m0[3].xyz));
float4x4 e = transpose(float4x4(float4(data_u.m2.m3.m2[0]), float4(data_u.m2.m3.m2[1]), float4(data_u.m2.m3.m2[2]), float4(data_u.m2.m3.m2[3])));
out.foo = (((a.y + float(b.z)) * c[1].z) * d[2].w) * e[3].w;
return out;
}

View File

@ -0,0 +1,50 @@
#version 450
out gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[1];
float gl_CullDistance[1];
};
struct s0
{
mediump mat2x3 m0;
ivec4 m1;
mat4 m2;
uvec2 m3;
};
struct s1
{
mediump mat3x4 m0;
mediump int m1;
uvec3 m2;
s0 m3;
};
layout(set = 0, binding = 0, std140) uniform data_u_t
{
layout(row_major, offset = 368) mediump mat2x3 m0;
layout(offset = 0) vec2 m1[5];
layout(row_major, offset = 128) s1 m2;
layout(row_major, offset = 80) mediump mat4x2 m3;
layout(offset = 112) ivec4 m4;
} data_u;
layout(location = 0) in vec4 vtx_posn;
layout(location = 0) out mediump float foo;
void main()
{
gl_Position = vtx_posn;
vec2 a = data_u.m1[3];
ivec4 b = data_u.m4;
mat2x3 c = data_u.m0;
mat3x4 d = data_u.m2.m0;
mat4 e = data_u.m2.m3.m2;
foo = (a.y + b.z) * c[1][2] * d[2][3] * e[3][3];
}

View File

@ -4171,11 +4171,7 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in
set_decoration(type_id, DecorationArrayStride, array_stride);
// Remove packed_ for vectors of size 1, 2 and 4.
if (has_extended_decoration(ib_type.self, SPIRVCrossDecorationPhysicalTypePacked))
SPIRV_CROSS_THROW("Unable to remove packed decoration as entire struct must be fully packed. Do not mix "
"scalar and std140 layout rules.");
else
unset_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypePacked);
unset_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypePacked);
}
else if (is_matrix(mbr_type))
{
@ -4202,11 +4198,7 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in
set_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypeID, type_id);
// Remove packed_ for vectors of size 1, 2 and 4.
if (has_extended_decoration(ib_type.self, SPIRVCrossDecorationPhysicalTypePacked))
SPIRV_CROSS_THROW("Unable to remove packed decoration as entire struct must be fully packed. Do not mix "
"scalar and std140 layout rules.");
else
unset_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypePacked);
unset_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypePacked);
}
else
SPIRV_CROSS_THROW("Found a buffer packing case which we cannot represent in MSL.");