HLSL: Fix issue with vec4 straddle rules in substructs.

This commit is contained in:
Hans-Kristian Arntzen 2024-01-05 14:05:04 +01:00
parent eabcc5e5b2
commit bedc49b859
5 changed files with 80 additions and 2 deletions

View File

@ -0,0 +1,16 @@
cbuffer UboData : register(b0)
{
float3 _12_data0 : packoffset(c0);
int2 _12_data1 : packoffset(c1);
};
void comp_main()
{
}
[numthreads(1, 1, 1)]
void main()
{
comp_main();
}

View File

@ -0,0 +1,21 @@
struct Data
{
float3 data0;
int2 data1;
};
cbuffer UboData : register(b0)
{
Data _13_scene : packoffset(c0);
};
void comp_main()
{
}
[numthreads(1, 1, 1)]
void main()
{
comp_main();
}

View File

@ -0,0 +1,12 @@
#version 450
layout(set = 0, binding = 0, std140) uniform UboData
{
vec3 data0;
// uint padding0; // 4 bytes of padding here
ivec2 data1;
};
void main()
{
}

View File

@ -0,0 +1,17 @@
#version 450
struct Data
{
vec3 data0;
// uint padding0; // 4 bytes of padding here
ivec2 data1;
};
layout(set = 0, binding = 0, std140) uniform UboData
{
Data scene;
};
void main()
{
}

View File

@ -1797,8 +1797,20 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
if (packing_is_hlsl(packing))
{
// If a member straddles across a vec4 boundary, alignment is actually vec4.
uint32_t begin_word = actual_offset / 16;
uint32_t end_word = (actual_offset + packed_size - 1) / 16;
uint32_t target_offset;
// If we intend to use explicit packing, we must check for improper straddle with that offset.
// In implicit packing, we must check with implicit offset, since the explicit offset
// might have already accounted for the straddle, and we'd miss the alignment promotion to vec4.
// This is important when packing sub-structs that don't support packoffset().
if (packing_has_flexible_offset(packing))
target_offset = actual_offset;
else
target_offset = offset;
uint32_t begin_word = target_offset / 16;
uint32_t end_word = (target_offset + packed_size - 1) / 16;
if (begin_word != end_word)
packed_alignment = max<uint32_t>(packed_alignment, 16u);
}