MSL: Use correct alignment rule for whole structs.

Structs are aligned as you would expect in MSL (maximum member
alignment), and it is not minimum 16 bytes like in std140.

Also rename the dummy "pad" members to a reserved naming scheme.
This commit is contained in:
Hans-Kristian Arntzen 2019-01-28 11:02:28 +01:00
parent 1f124d0a81
commit 8c632da461
10 changed files with 35 additions and 19 deletions

View File

@ -73,7 +73,7 @@ struct _18
float2 _m24; float2 _m24;
float2 _m25; float2 _m25;
float2 _m26; float2 _m26;
char pad27[8]; char _m27_pad[8];
packed_float3 _m27; packed_float3 _m27;
float _m28; float _m28;
float _m29; float _m29;

View File

@ -40,10 +40,12 @@ struct Content
S1 m1s[1]; S1 m1s[1];
S2 m2s[1]; S2 m2s[1];
S0 m0; S0 m0;
char _m4_pad[4];
S1 m1; S1 m1;
S2 m2; S2 m2;
char _m6_pad[8];
S3 m3; S3 m3;
char pad7[4]; char _m7_pad[4];
float m4; float m4;
S4 m3s[8]; S4 m3s[8];
}; };
@ -53,7 +55,7 @@ struct SSBO1
Content content; Content content;
Content content1[2]; Content content1[2];
Content content2; Content content2;
char pad3[8]; char _m3_pad[8];
float2x2 m0; float2x2 m0;
float2x2 m1; float2x2 m1;
float2x3 m2[4]; float2x3 m2[4];
@ -61,9 +63,9 @@ struct SSBO1
float2x2 m4; float2x2 m4;
float2x2 m5[9]; float2x2 m5[9];
packed_float2x3 m6[4][2]; packed_float2x3 m6[4][2];
char pad10[8]; char _m10_pad[8];
float3x2 m7; float3x2 m7;
char pad11[8]; char _m11_pad[8];
float array[1]; float array[1];
}; };
@ -102,11 +104,14 @@ struct Content_1
S1_1 m1s[1]; S1_1 m1s[1];
S2_1 m2s[1]; S2_1 m2s[1];
S0_1 m0; S0_1 m0;
char _m4_pad[12];
S1_1 m1; S1_1 m1;
S2_1 m2; S2_1 m2;
char _m6_pad[8];
S3_1 m3; S3_1 m3;
char pad7[4]; char _m7_pad[4];
float m4; float m4;
char _m8_pad[8];
S4_1 m3s[8]; S4_1 m3s[8];
}; };

View File

@ -16,7 +16,7 @@ struct _42
float4x4 _m0; float4x4 _m0;
float4x4 _m1; float4x4 _m1;
float _m2; float _m2;
char pad3[12]; char _m3_pad[12];
packed_float3 _m3; packed_float3 _m3;
float _m4; float _m4;
packed_float3 _m5; packed_float3 _m5;

View File

@ -7,7 +7,7 @@ struct UBO
{ {
float4x4 mvp; float4x4 mvp;
float2 targSize; float2 targSize;
char pad2[8]; char _m2_pad[8];
packed_float3 color; packed_float3 color;
float opacity; float opacity;
}; };

View File

@ -73,7 +73,7 @@ struct _18
float2 _m24; float2 _m24;
float2 _m25; float2 _m25;
float2 _m26; float2 _m26;
char pad27[8]; char _m27_pad[8];
packed_float3 _m27; packed_float3 _m27;
float _m28; float _m28;
float _m29; float _m29;

View File

@ -40,10 +40,12 @@ struct Content
S1 m1s[1]; S1 m1s[1];
S2 m2s[1]; S2 m2s[1];
S0 m0; S0 m0;
char _m4_pad[4];
S1 m1; S1 m1;
S2 m2; S2 m2;
char _m6_pad[8];
S3 m3; S3 m3;
char pad7[4]; char _m7_pad[4];
float m4; float m4;
S4 m3s[8]; S4 m3s[8];
}; };
@ -53,7 +55,7 @@ struct SSBO1
Content content; Content content;
Content content1[2]; Content content1[2];
Content content2; Content content2;
char pad3[8]; char _m3_pad[8];
float2x2 m0; float2x2 m0;
float2x2 m1; float2x2 m1;
float2x3 m2[4]; float2x3 m2[4];
@ -61,9 +63,9 @@ struct SSBO1
float2x2 m4; float2x2 m4;
float2x2 m5[9]; float2x2 m5[9];
packed_float2x3 m6[4][2]; packed_float2x3 m6[4][2];
char pad10[8]; char _m10_pad[8];
float3x2 m7; float3x2 m7;
char pad11[8]; char _m11_pad[8];
float array[1]; float array[1];
}; };
@ -102,11 +104,14 @@ struct Content_1
S1_1 m1s[1]; S1_1 m1s[1];
S2_1 m2s[1]; S2_1 m2s[1];
S0_1 m0; S0_1 m0;
char _m4_pad[12];
S1_1 m1; S1_1 m1;
S2_1 m2; S2_1 m2;
char _m6_pad[8];
S3_1 m3; S3_1 m3;
char pad7[4]; char _m7_pad[4];
float m4; float m4;
char _m8_pad[8];
S4_1 m3s[8]; S4_1 m3s[8];
}; };

View File

@ -16,7 +16,7 @@ struct _42
float4x4 _m0; float4x4 _m0;
float4x4 _m1; float4x4 _m1;
float _m2; float _m2;
char pad3[12]; char _m3_pad[12];
packed_float3 _m3; packed_float3 _m3;
float _m4; float _m4;
packed_float3 _m5; packed_float3 _m5;

View File

@ -7,7 +7,7 @@ struct UBO
{ {
float4x4 mvp; float4x4 mvp;
float2 targSize; float2 targSize;
char pad2[8]; char _m2_pad[8];
packed_float3 color; packed_float3 color;
float opacity; float opacity;
}; };

View File

@ -960,7 +960,7 @@ uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bits
if (type.basetype == SPIRType::Struct) if (type.basetype == SPIRType::Struct)
{ {
// Rule 9. Structs alignments are maximum alignment of its members. // Rule 9. Structs alignments are maximum alignment of its members.
uint32_t alignment = 0; uint32_t alignment = 1;
for (uint32_t i = 0; i < type.member_types.size(); i++) for (uint32_t i = 0; i < type.member_types.size(); i++)
{ {
auto member_flags = ir.meta[type.self].members[i].decoration_flags; auto member_flags = ir.meta[type.self].members[i].decoration_flags;

View File

@ -4030,7 +4030,7 @@ void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_
MSLStructMemberKey key = get_struct_member_key(type.self, index); MSLStructMemberKey key = get_struct_member_key(type.self, index);
uint32_t pad_len = struct_member_padding[key]; uint32_t pad_len = struct_member_padding[key];
if (pad_len > 0) if (pad_len > 0)
statement("char pad", to_string(index), "[", to_string(pad_len), "];"); statement("char _m", index, "_pad", "[", to_string(pad_len), "];");
// If this member is packed, mark it as so. // If this member is packed, mark it as so.
string pack_pfx = ""; string pack_pfx = "";
@ -5712,7 +5712,13 @@ size_t CompilerMSL::get_declared_struct_member_alignment(const SPIRType &struct_
SPIRV_CROSS_THROW("Querying alignment of opaque object."); SPIRV_CROSS_THROW("Querying alignment of opaque object.");
case SPIRType::Struct: case SPIRType::Struct:
return 16; // Per Vulkan spec section 14.5.4 {
// In MSL, a struct's alignment is equal to the maximum alignment of any of its members.
uint32_t alignment = 1;
for (uint32_t i = 0; i < type.member_types.size(); i++)
alignment = max(alignment, uint32_t(get_declared_struct_member_alignment(type, i)));
return alignment;
}
default: default:
{ {