Skip to content

Advanced Vulkan Compute scalar layout issues #494

Description

@juliusikkala

The scalar layouts section makes multiple untrue claims that will mislead readers and lead to difficult-to-debug data corruption.

In Vulkan 1.4, this functionality is now a core requirement. By using the `scalar` layout, you can ensure that your data structures on the GPU match your C{pp} structures perfectly, byte-for-byte.

Scalar layout (as it is implemented in GLSL and Slang) in fact does not match C++ structure layout exactly, there is a notable corner case with nested structs:

struct Inner
{
    uint a;
    uint16_t b;
};

struct Outer
{
    Inner ab;
    uint16_t c;
};

With scalar layout (in Slang and GLSL), sizeof(Outer) == 8, as Outer::c gets packed into the trailing padding of Outer::ab. In C++, sizeof(Outer) == 12. Slang does have -fvk-use-c-layout (slangc) / OptionKind::ForceCLayout (API) / CDataLayout (in-language) that does actually match the C++ layout (with the only known caveat being empty structs, which are 0 bytes in Slang and 1 in C/C++). As for HLSL/DXC, they have changed their scalar layout to match C/C++ somewhat recently: microsoft/DirectXShaderCompiler#7996.

If you are using Slang, you don't even need to worry about manual layout qualifiers for most cases. Slang's layout engine handles the `scalar` rules for you when targeting Vulkan 1.4:

This is just untrue. StructuredBuffer<T> in Slang does not default to scalar layout. You also don't target Vulkan versions with Slang, you target SPIR-V versions instead, but none of those change the default layout to be scalar layout. You have to either specify it globally with -fvk-use-scalar-layout (slangc), OptionKind::GLSLForceScalarLayout (Slang API) or specify it per-buffer with RWStructuredBuffer<T, ScalarDataLayout> buf;.

Not really a factual error, but swapping std430 -> scalar is not exactly what I would call a "manual struggle". It is just as manual as it is in Slang.

If you are using modern languages like Slang, this becomes even easier. Slang defaults to a more natural, C{pp}-like layout, and its Vulkan backend handles the scalar layout details for you automatically when targeting Vulkan 1.4.

Again, Slang does not default to a "C++-like" layout. It doesn't even default to scalar layout. And I don't know why this would be in plural, "modern languages". None of the big three shading languages default to scalar layout.

By understanding these low-level architectural details, you've moved beyond "writing shaders" and started "programming the hardware."

This is a completely meaningless, tautological statement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions