Skip to content

Commit 6f5c250

Browse files
authored
Small improvements around atomics (shader-slang#1333)
* Use the original value in the test. Run test on VK. * Added RWBuffer and Buffer types to C++ prelude. * Add vk to atomics.slang tests * Update target-compatibility around atomics. When tests disabled in atomics-buffer.slang explained why. * tabs -> spaces. * Small docs improvement.
1 parent 806ab08 commit 6f5c250

6 files changed

+57
-10
lines changed

docs/target-compatibility.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ Items with ^ means there is some discussion about support later in the document
3737
| Full bool | Yes | Yes | Yes | No | Yes ^
3838
| Mesh Shader | No | No + | No + | No | No
3939
| `[unroll]` | Yes | Yes | Yes ^ | Yes | Limited +
40-
40+
| Atomics | Yes | Yes | Yes | Yes | No +
41+
| Atomics on RWBuffer | Yes | Yes | Yes | No | No +
4142

4243
## Half Type
4344

@@ -161,3 +162,10 @@ On GLSL and VK targets loop unrolling uses the [GL_EXT_control_flow_attributes](
161162

162163
Slang does have a cross target mechanism to [unroll loops](language-reference/06-statements.md), in the section `Compile-Time For Statement`.
163164

165+
## Atomics on RWBuffer
166+
167+
For VK the GLSL output from Slang seems plausible, but VK binding fails in tests harness.
168+
169+
On CUDA RWBuffer becomes CUsurfObject, which is a 'texture' type and does not support atomics.
170+
171+
On the CPU atomics are not supported, but will be in the future.

prelude/slang-cpp-types.h

+23
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,29 @@ struct StructuredBuffer
116116
size_t count;
117117
};
118118

119+
120+
template <typename T>
121+
struct RWBuffer
122+
{
123+
SLANG_FORCE_INLINE T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; }
124+
const T& Load(size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; }
125+
void GetDimensions(uint32_t& outCount) { outCount = uint32_t(count); }
126+
127+
T* data;
128+
size_t count;
129+
};
130+
131+
template <typename T>
132+
struct Buffer
133+
{
134+
SLANG_FORCE_INLINE const T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; }
135+
const T& Load(size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; }
136+
void GetDimensions(uint32_t& outCount) { outCount = uint32_t(count); }
137+
138+
T* data;
139+
size_t count;
140+
};
141+
119142
// Missing Load(_In_ int Location, _Out_ uint Status);
120143
struct ByteAddressBuffer
121144
{

tests/compute/atomics-buffer.slang

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
44
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12
5+
// Doesn't work on VK - GLSL output doesn't replace InterlockedAdd.
6+
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -vk
7+
// Cannot work on CUDA, as outputBuffer becomes a CUsurfObject - which do not appear to have atomics available.
8+
// If the buffer was a StructuredBuffer this would work on CUDA.
9+
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cuda
10+
// Atomics not available on CPU currently
11+
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cpu
512

613
//TEST_INPUT:ubuffer(format=R_UInt32, data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]):out,name outputBuffer
714

tests/compute/atomics-groupshared.slang

+13-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
44
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12
5+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -vk
56
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cuda
67

78
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
@@ -18,13 +19,20 @@ uint test(uint val)
1819

1920
GroupMemoryBarrierWithGroupSync();
2021

21-
InterlockedAdd(shared[val], val, originalValue);
22-
InterlockedAdd(shared[val ^ 1], val*16, originalValue);
23-
InterlockedAdd(shared[val ^ 2], val*16*16, originalValue);
24-
22+
uint originalSum = 0;
23+
24+
InterlockedAdd(shared[val], val, originalValue);
25+
originalSum += originalValue;
26+
27+
InterlockedAdd(shared[val ^ 1], val*16, originalValue);
28+
originalSum += originalValue;
29+
30+
InterlockedAdd(shared[val ^ 2], val*16*16, originalValue);
31+
originalSum += originalValue;
32+
2533
GroupMemoryBarrierWithGroupSync();
2634

27-
return shared[val];
35+
return shared[val] ^ originalSum;
2836
}
2937

3038
[numthreads(4, 1, 1)]
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
210
2-
301
3-
32
4-
123
1+
223
2+
322
3+
21
4+
120

tests/compute/atomics.slang

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
44
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12
5+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -vk
56
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cuda
67

78
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name outputBuffer

0 commit comments

Comments
 (0)