mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-10 06:00:07 +00:00
Handle padding for struct members in buffers.
Fixes earlier issues with struct-packing test.
This commit is contained in:
parent
2d38c6e192
commit
44ef367141
@ -32,12 +32,16 @@ struct Content
|
||||
S2 m2s[1];
|
||||
S0 m0;
|
||||
S1 m1;
|
||||
float m4;
|
||||
S2 m2;
|
||||
S3 m3;
|
||||
float m4;
|
||||
};
|
||||
|
||||
layout(binding = 1, std430) buffer SSBO1
|
||||
{
|
||||
Content content;
|
||||
Content content1[2];
|
||||
Content content2;
|
||||
mat2 m0;
|
||||
mat2 m1;
|
||||
mat2x3 m2[4];
|
||||
@ -46,10 +50,7 @@ layout(binding = 1, std430) buffer SSBO1
|
||||
layout(row_major) mat2 m5[9];
|
||||
layout(row_major) mat2x3 m6[2][4];
|
||||
layout(row_major) mat3x2 m7;
|
||||
float array[1024];
|
||||
Content content;
|
||||
Content content1[2];
|
||||
Content content2;
|
||||
float array[];
|
||||
} ssbo_430;
|
||||
|
||||
layout(binding = 0, std140) buffer SSBO0
|
||||
|
@ -32,12 +32,17 @@ struct Content
|
||||
S2 m2s[1];
|
||||
S0 m0;
|
||||
S1 m1;
|
||||
float m4;
|
||||
S2 m2;
|
||||
S3 m3;
|
||||
float m4;
|
||||
};
|
||||
|
||||
layout(binding = 1, std430) buffer SSBO1
|
||||
{
|
||||
Content content;
|
||||
Content content1[2];
|
||||
Content content2;
|
||||
|
||||
layout(column_major) mat2 m0;
|
||||
layout(column_major) mat2 m1;
|
||||
layout(column_major) mat2x3 m2[4];
|
||||
@ -46,11 +51,7 @@ layout(binding = 1, std430) buffer SSBO1
|
||||
layout(row_major) mat2 m5[9];
|
||||
layout(row_major) mat2x3 m6[4][2];
|
||||
layout(row_major) mat3x2 m7;
|
||||
float array[1024];
|
||||
|
||||
Content content;
|
||||
Content content1[2];
|
||||
Content content2;
|
||||
float array[];
|
||||
} ssbo_430;
|
||||
|
||||
layout(binding = 0, std140) buffer SSBO0
|
||||
|
@ -584,11 +584,23 @@ uint32_t CompilerGLSL::type_to_std430_size(const SPIRType &type, uint64_t flags)
|
||||
|
||||
if (type.basetype == SPIRType::Struct)
|
||||
{
|
||||
uint32_t pad_alignment = 1;
|
||||
|
||||
for (uint32_t i = 0; i < type.member_types.size(); i++)
|
||||
{
|
||||
auto member_flags = meta[type.self].members.at(i).decoration_flags;
|
||||
auto &member_type = get<SPIRType>(type.member_types[i]);
|
||||
uint32_t alignment = type_to_std430_alignment(member_type, member_flags);
|
||||
|
||||
uint32_t std430_alignment = type_to_std430_alignment(member_type, member_flags);
|
||||
uint32_t alignment = max(std430_alignment, pad_alignment);
|
||||
|
||||
// The next member following a struct member is aligned to the base alignment of the struct that came before.
|
||||
// GL 4.5 spec, 7.6.2.2.
|
||||
if (member_type.basetype == SPIRType::Struct)
|
||||
pad_alignment = std430_alignment;
|
||||
else
|
||||
pad_alignment = 1;
|
||||
|
||||
size = (size + alignment - 1) & ~(alignment - 1);
|
||||
size += type_to_std430_size(member_type, member_flags);
|
||||
}
|
||||
@ -634,6 +646,7 @@ bool CompilerGLSL::ssbo_is_std430_packing(const SPIRType &type)
|
||||
// std430 only removes the vec4 requirement.
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t pad_alignment = 1;
|
||||
|
||||
for (uint32_t i = 0; i < type.member_types.size(); i++)
|
||||
{
|
||||
@ -642,7 +655,15 @@ bool CompilerGLSL::ssbo_is_std430_packing(const SPIRType &type)
|
||||
|
||||
// Verify alignment rules.
|
||||
uint32_t std430_alignment = type_to_std430_alignment(memb_type, member_flags);
|
||||
offset = (offset + std430_alignment - 1) & ~(std430_alignment - 1);
|
||||
uint32_t alignment = max(std430_alignment, pad_alignment);
|
||||
offset = (offset + alignment - 1) & ~(alignment - 1);
|
||||
|
||||
// The next member following a struct member is aligned to the base alignment of the struct that came before.
|
||||
// GL 4.5 spec, 7.6.2.2.
|
||||
if (memb_type.basetype == SPIRType::Struct)
|
||||
pad_alignment = std430_alignment;
|
||||
else
|
||||
pad_alignment = 1;
|
||||
|
||||
uint32_t actual_offset = type_struct_member_offset(type, i);
|
||||
if (actual_offset != offset) // This cannot be std430.
|
||||
|
Loading…
Reference in New Issue
Block a user