microsoft / microsoft/DirectXShaderCompiler
[SPIR-V] Bitfields can cause wrong struct member access
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.7k
- Forks
- 900
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 44
Description
Description
Accessing data in a constant buffer via a local struct variable can cause wrong elements to be accessed if bitfield members precede them. In the example below, watch how the %uint_1 offset in the last OpAccessChain changes to %uint_0 if the second approach is used.
I noticed this while using my workaround for #8373, meaning I cannot always use a variable of ConstantBuffer<...> type directly, which would avoid this issue...
Steps to Reproduce
https://godbolt.org/z/ohd9eafGP
// -E main -T ps_6_7 -spirv -fspv-target-env=vulkan1.3 -HV 2021
struct MyData {
uint a : 16;
uint b : 16;
uint c;
};
uint main() : SV_Target {
ConstantBuffer<MyData> md = ResourceDescriptorHeap[123]; // Works
//MyData md = (ConstantBuffer<MyData>)ResourceDescriptorHeap[123]; // Word 0 instead of 1 is accessed!
return md.c;
}
Actual Behavior
Word 0 instead of 1 of the struct is accessed, if the second approach is used.
Environment
- DXC trunk
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Godbolt reproduction and compare the generated SPIR-V for the direct ConstantBuffer access and the cast-to-struct approach. Trace the differing OpAccessChain offsets in DXC trunk; done means the cast approach accesses word 1 for md.c, matching the direct approach.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100