microsoft / microsoft/DirectXShaderCompiler
Initializing a const-qualified var of type 'struct/array of (struct/array of) more than one type' with initializer 'init' will ignore any dynamic writes made to 'init' beforehand
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.7k
- Forks
- 900
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 44
Description
See the following HLSL compute shader:
01: struct S {
02: float2x3 m;
03: };
04:
05: RWByteAddressBuffer buffer : register(u0);
06:
07: [numthreads(1, 1, 1)]
08: void main() {
09: float2x3 m = float2x3(42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f);
10: m[0] = float3(1, 2, 3);
11: m[1] = float3(4, 5, 6);
12:
13: S a = {m}; // valid, S contains values written to m after init
14: // const S a = {m}; // invalid, S contains init m values
15:
16: buffer.Store3(0u, int3(a.m[0]));
17: buffer.Store3(16u, int3(a.m[1]));
18: }
When line 13 is uncommented, that is, we create a non-const instance of S, the compiled DXIL shows that it correctly initializes the buffer with the values that were written to the matrix on lines 10 and 11:
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %1, i32 0, i32 undef, i32 1, i32 2, i32 3, i32 undef, i8 7, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %1, i32 16, i32 undef, i32 4, i32 5, i32 6, i32 undef, i8 7, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
However, if we comment out line 13 and uncomment line 14 so that we create a const instance of S instead, now the compiled DXIL shows that the buffer is initialized with the initial values that were in the matrix from line 9:
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %1, i32 0, i32 undef, i32 42, i32 43, i32 44, i32 undef, i8 7, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %1, i32 16, i32 undef, i32 45, i32 46, i32 47, i32 undef, i8 7, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
This seems to only happen with matrices inside a struct. So to summarize: it looks like initializing a const-qualified var of type 'struct of matrix' with m ignores dynamic writes made to m before said initialization.
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 by compiling the HLSL compute shader shown in the issue, comparing the generated DXIL for non-const and const S a = {m} initialization. Trace the compiler entry points handling aggregate initialization and matrix values. Done means the const-qualified case preserves the dynamic writes from lines 10 and 11 rather than the initial values from line 9.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100