DirectXShaderCompiler
DirectXShaderCompiler copied to clipboard
[SPIR-V] using vk::offset on struct causes invalid spir-v
Description
Putting a custom struct at a particular offset with vk::offset generates invalid spir-v while putting a builtin vector with the same size there works fine.
Steps to Reproduce
struct Ok
{
float2 a;
[[vk::offset(8)]] float2 b;
};
struct complex
{
float r;
float i;
};
struct Error
{
float2 a;
[[vk::offset(8)]] complex b;
};
Actual Behavior Produces invalid spir-v:
generated SPIR-V is invalid: Structure id 11 decorated as Block for variable in Uniform storage class must follow relaxed uniform buffer layout rules: member 1 at offset 8 is not aligned to 16 %Error = OpTypeStruct %v2float %complex
note: please file a bug report on https://github.com/Microsoft/DirectXShaderCompiler/issues with source code if possible
Environment dxcompiler.dll: 1.7 - 1.7.2308.7 (69e54e290); dxil.dll: 1.7(101.7.2308.12) Windows 10 version 22H2 build 19045.3803
I think the issue is that the custom struct with two floats is actually 16 bytes instead of the 8 bytes I expected it to be.
I cannot reproduce the problem (https://godbolt.org/z/G3YnYddza). Can you please provide a compiler explorer link that demonstrates the problem?
Yes, it needs a constant buffer instead of a structured buffer: https://godbolt.org/z/4PKheP3jG
@cassiebeckley Can you take a look at this?
I believe this is working as intended. cbuffers are lowered to Vulkan uniform buffers using vector-relaxed std140 layout, described in the Vulkan standard as extended alignment, which states that a structure type's alignment must be rounded up to a multiple of 16.
If you want to use C-like structure layout, you may use the flag -fvk-use-scalar-layout: https://godbolt.org/z/rWadrKfnd.
Any time the compiler produces SPIR-V that fails validation we consider it a bug. If the offsets are invalid for the resource type/layout rules then we should fail earlier in compilation with a more descriptive error message.
I still have the bug that the decoration doesn't have any effect when I then try to feed the struct to BDA pointer making templates