shader-slang / slang

Making it easier to work with shaders
MIT License
1.78k stars 159 forks source link

Flag to prevent cbuffer elements from being packed into a struct #3992

Closed pema99 closed 2 months ago

pema99 commented 2 months ago

If you compile a program using a cbuffer with the HLSL target:

cbuffer foo
{
    int bar;   
}

float computeMain()
{
    return bar;
}

You get output like this, with the cbuffer containing a struct variable.

struct SLANG_ParameterGroup_foo_0
{
    int bar_0;
};

cbuffer foo_0 : register(b0)
{
    SLANG_ParameterGroup_foo_0 foo_0;
}

[numthreads(1, 1, 1)]
float computeMain()
{
    return float(foo_0.bar_0);
}

This is undesirable in my use case. I'm making a tool for use with the Unity game engine, which in general doesn't support cbuffer's containing struct variables. I was planning to just work around this (I'm already doing some further analysis/cleanup of the output HLSL), but then I stumbled across this special case, which prevents this behavior https://github.com/shader-slang/slang/blob/8362c2d46e2da0c20fbd3daf511ccdf425f9a1f0/source/slang/slang-emit-hlsl.cpp#L224-L231 If one of the cbuffer members has a packoffset() modifier, you unpack the ParameterGroup struct. Since the logic to do this already exists in the compiler, I figured I'd ask whether this could be be put behind a flag, something like -hlsl-force-unpack-cbuffer-structs?

If you are willing to accept something like that, I could try making a PR to do it. If not, I'll find some workaround.

csyonghe commented 2 months ago

Yes, we welcome PRs like this if it unblocks you.