Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitfield initialization unclear #5587

Open
mstrgram opened this issue Aug 23, 2023 · 4 comments
Open

Bitfield initialization unclear #5587

mstrgram opened this issue Aug 23, 2023 · 4 comments
Labels
bug Bug, regression, crash hlsl2021 Pertaining to HLSL2021 features
Milestone

Comments

@mstrgram
Copy link

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)
@mstrgram mstrgram added bug Bug, regression, crash needs-triage Awaiting triage labels Aug 23, 2023
@llvm-beanz llvm-beanz moved this to Done in HLSL Triage Aug 23, 2023
@llvm-beanz llvm-beanz added hlsl2021 Pertaining to HLSL2021 features and removed needs-triage Awaiting triage labels Aug 23, 2023
@llvm-beanz
Copy link
Collaborator

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.

@mstrgram
Copy link
Author

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.

@llvm-beanz
Copy link
Collaborator

That would be supported if we adopted C++ initialization rules, which is my hope for the future.

@damyanp
Copy link
Member

damyanp commented Oct 10, 2024

Related: microsoft/hlsl-specs#310

@damyanp damyanp added this to the Dormant milestone Oct 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug, regression, crash hlsl2021 Pertaining to HLSL2021 features
Projects
Status: Triaged
Development

No branches or pull requests

3 participants