shader-slang/slang

Push constants laid out as std140 instead of std430 and I don't know how to override/fix that.

Closed this issue · 0 comments

Apologies up front if this is a case of "user didn't read the docs hard enough".

I'm in the process of migrating from VK-GLSL to Slang and I was surprised to see that push constants are laid out std140 instead of std430. That's not what I expected (or what anyone would ever want, I think), and short of making my types ugly by writing everything out manually as float4s I can't figure out how to fix this. I don't see an attribute I can throw on the struct or on the variable to force it to the std430 rules, but I also don't want to globally force all uniforms over to std430.

The shader code is really simple:

struct Transform
{
    float4 Tint;
    float2x2 ScaleRot; // << why u no std430???
    float2 Translation;
};

[[vk::binding(0, 0)]]
Sampler2DArray Tex0;

struct InVert_1uv
{
    int2 Position;
    float4 Color;
    uint3 TcAndArrayIndex;
};

struct OutVert_1uv
{
    float4 Position : SV_Position;
    float4 Color;
    float3 TexCoord;
};

[shader("vertex")]
OutVert_1uv vs_1uv(
    [[vk::push_constant]] uniform Transform transform,
    in InVert_1uv in)
{
    OutVert_1uv out;

    out.Position.xy = mul(in.Position, transform.ScaleRot + transform.Translation;
    out.Position.zw = float2(0, 1);

    out.Color = in.Color * transform.Tint;

    float3 texSize;
    Tex0.GetDimensions(texSize.x, texSize.y, texSize.z);
    out.TexCoord.xy = in.TcAndArrayIndex.xy / texSize.xy;
    out.TexCoord.z = in.TcAndArrayIndex.z;

    return out;
}

That was surprising coming from GLSL where the following declaration Just Works:

layout(push_constant) uniform Transform
{
	vec4 uColor;
	mat2 uSR;
	vec2 uT;
};

I tried declaring transform at file scope and got the same result. I've even tried breaking it up into individual fields (either as parameters or at file scope), but then I lost control of what order they were packing in (and the matrix still packed std140). Right now I'm working around it by just declaring ScaleRot a float4 and casting to float2x2 in the shader, which works, but it'd be nice if I didn't have to trip over this with every shader going forward.

Using the Slang version bundled into the current Vulkan SDK (1.3.296.0; slang::IGlobalSession::getBuildTagString says 2024.13, if that's the right thing to check).

Thank you.