Bitfield initialization unclear
Description It is unclear to me how to initialize a bitfield to all 0 in HLSL. It appears a simple syntax works in some cases, but not others.
Steps to Reproduce
test.hlsl file contains:
RWStructuredBuffer<uint> g_Buffer : register(u1);
enum SomeEnum
{
SomeEnum_val0,
SomeEnum_val1,
SomeEnum_val2,
SomeEnum_val3
};
struct SomeBitfield
{
SomeEnum field1 : 2;
uint32_t rest : 30;
};
[RootSignature("UAV(u1)")]
[numthreads(1, 1, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
SomeBitfield val = (SomeBitfield)0;
g_Buffer[0] = (uint)val;
}
Compile with:
dxc -T cs_6_6 -HV 2021 -E main test.hlsl
Actual Behavior You get this output:
test.hlsl:21:24: error: cannot convert from 'literal int' to 'SomeBitfield'
SomeBitfield val = (SomeBitfield)0;
However, if I switch the order of the field1 and rest members in SomeBitfield, it seemingly works and the generated code looks correct. Is the SomeBitfield val = (SomeBitfield)0 syntax meant to be valid? If yes, it doesn't seem to work reliably. If no, how to I easily (and most efficiently) initialize all members of a bitfield to 0?
Environment
- DXC version:
dxcompiler_xs.dll!DxcCreateInstance: 1.7 - 2310.2307.12501.10025 - Host Operating System: Windows 11 Version 22H2 (OS Build 22621.2134)
Adding a few bits of context. This is not a valid initializer in C++: https://godbolt.org/z/6T38Pv6Ka
This would be valid with C/C++ initialization rules: https://godbolt.org/z/a4E5TbrWb
In HLSL the struct gets treated as a vector initializer, which is… extremely odd.
The current workaround for HLSL would be to initialize each member: https://godbolt.org/z/7oMejaTzz
I suspect the bug here is in how HLSL flattened initializers work. We may be able to implement a hacky fix that resolves this issue but the correct long-term solution would be to adopt C/C++ initialization rules, which we have a rough feature proposal for.
It would be great if it was possible to do zero-initialization like C++:
SomeBitfield val = {};
But not sure if that messes with other vector intialization rules.
That would be supported if we adopted C++ initialization rules, which is my hope for the future.
Related: https://github.com/microsoft/hlsl-specs/issues/310