KhronosGroup / KhronosGroup/glslang
Cannot call InterlockedAdd() method on a RWByteAddressBuffer in HLSL
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.6k
- Forks
- 990
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 31
Description
Here's my repro case:
```hlsl
RWByteAddressBuffer MyBuffer;
[numthreads(1, 1, 1)]
void main()
{
uint previous_value;
MyBuffer.InterlockedAdd(0, 1, previous_value);
}
```
This shader compiles to SPIR-V with the following command:
```sh
$ glslangValidator --target-env spirv1.3 -g -e main -V -D test_interlocked.comp.hlsl -o test_interlocked.comp.spv.unoptimized
$ spirv-opt test_interlocked.comp.spv.unoptimized --legalize-hlsl -Os -o test_interlocked.comp.spv
```
```sh
$ glslangValidator --version
Glslang Version: 8.13.3559
ESSL Version: OpenGL ES GLSL 3.20 glslang Khronos. 13.3559
GLSL Version: 4.60 glslang Khronos. 13.3559
SPIR-V Version 0x00010400, Revision 1
GLSL.std.450 Version 100, Revision 1
Khronos Tool ID 8
SPIR-V Generator Version 8
GL_KHR_vulkan_glsl version 100
ARB_GL_gl_spirv version 100
```
The compilation fails when `spirv-opt` is invoked with the following message:
```
error: line 51: AtomicIAdd: expected Value to be of type Result Type
%25 = OpAtomicIAdd %uint %21 %uint_1 %uint_0 %int_1
```
I'm not sure if this problem comes from `glslang` or `spirv-opt`, maybe you guys have more info on this.
As a reference, here is what `dxc` outputs at the atomic instruction for my example:
```spirv
%14 = OpAtomicIAdd %uint %13 %uint_1 %uint_0 %uint_1
```
EDIT: So I slept on it and tried to force constants to the `uint` type. Here's the changed part:
```hlsl
MyBuffer.InterlockedAdd(0, uint(1), previous_value);
```
This successfully compiles with `glslang`. I still think there's a bug here though.
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
Reproduce the issue with test_interlocked.comp.hlsl using the shown glslangValidator and spirv-opt commands, starting at the HLSL InterlockedAdd handling and generated OpAtomicIAdd. Compare the output with the dxc reference and the uint(1) workaround; done means the uncast literal produces valid SPIR-V without the spirv-opt type error.
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
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100