Skip to content

Commit 2420f47

Browse files
authored
CPU unsized array documentation and another example (shader-slang#1080)
* WIP: Unsized arrays on CPU. * unbounded-array-of-array working on CPU. * Test that has an unbounded array of array directly (ie without wrapping with ParameterBlock). Test works on CPU. * Remove some left over comments. * Added documention on unsized array usage on CPU targets.
1 parent 9c17d0b commit 2420f47

3 files changed

+68
-2
lines changed

docs/cpu-target.md

+28-2
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,35 @@ Notice that of the entry point parameters `dispatchThreadID` is not part of Unif
182182
size_t sizeInBytes;
183183
```
184184

185-
Resource types become pointers to interfaces that implement their features. For example `Texture2D` become a pointer to a `ITexture2D` interface that has to be implemented in client side code. Similarly SamplerState and SamplerComparisonState become `ISamplerState` and `ISamplerComparisonState`.
186185

186+
Resource types become pointers to interfaces that implement their features. For example `Texture2D` become a pointer to a `ITexture2D` interface that has to be implemented in client side code. Similarly SamplerState and SamplerComparisonState become `ISamplerState` and `ISamplerComparisonState`.
187+
187188
The actual definitions for the interfaces for resource types, and types are specified in 'slang-cpp-types.h' in the `prelude` directory.
188189

189-
The code that sets up the prelude for the test infrastucture and command line usage can be found in ```TestToolUtil::setSessionDefaultPrelude```.
190+
## Unsized arrays
191+
192+
Unsized arrays can be used, which are indicated by an array with no size as in `[]`. For example
193+
194+
```
195+
RWStructuredBuffer<int> arrayOfArrays[];
196+
```
197+
198+
With normal 'sized' arrays, the elements are just stored contiguously within wherever they are defined. With an unsized array they map to `Array<T>` which is...
199+
200+
```
201+
T* data;
202+
size_t count;
203+
```
204+
205+
Note that there is no method in the shader source to get the `count`, even though on the CPU target it is stored and easily available. This is because of the behavior on GPU targets
206+
207+
* That the count has to be stored elsewhere (unlike with CPU)
208+
* On some GPU targets there is no bounds checking - accessing outside the bound values can cause *undefined behavior*
209+
* The elements may be laid out *contiguously* on GPU
210+
211+
In practice this means if you want to access the `count` in shader code it will need to be passed by another mechanism - such as within a constant buffer. It is possible in the future support may be added to allow direct access of `count` work across targets transparently.
212+
213+
It is perhaps worth noting that the CPU allows us to have an indirection (a pointer to the unsized arrays contents) which has the potential for more flexibility than is possible on GPU targets. GPU target typically require the elements to be placed 'contiguously' from their location in their `container` - be that registers or in memory. This means on GPU targets there may be other restrictions on where unsized arrays can be placed in a structure for example, such as only at the end. If code needs to work across targets this means these restrictions will need to be followed across targets.
190214

191215
## Prelude
192216

@@ -228,6 +252,8 @@ It may be useful to be able to include `slang-cpp-types.h` in C++ code to access
228252

229253
Would wrap all the Slang prelude types in the namespace `CPPPrelude`, such that say a `StructuredBuffer<int32_t>` could be specified in C++ source code as `CPPPrelude::StructuredBuffer<int32_t>`.
230254

255+
The code that sets up the prelude for the test infrastucture and command line usage can be found in ```TestToolUtil::setSessionDefaultPrelude```. Essentially this determines what the absolute path is to `slang-cpp-prelude.h` is and then just makes the prelude `#include "the absolute path"`.
256+
231257
Language aspects
232258
================
233259

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//DISABLE_TEST:CPU_REFLECTION: -profile cs_5_0 -entry computeMain -target cpp
2+
//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute
3+
4+
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):dxbinding(0),glbinding(0),out,name outputBuffer
5+
RWStructuredBuffer<int> outputBuffer;
6+
7+
//TEST_INPUT:array(size=2):name g_aoa
8+
RWStructuredBuffer<int> g_aoa[];
9+
10+
//TEST_INPUT:ubuffer(data=[1 2 3 4], stride=4):name=g_aoa[0]
11+
//TEST_INPUT:ubuffer(data=[8 17 34], stride=4):name=g_aoa[1]
12+
13+
[numthreads(8, 1, 1)]
14+
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
15+
{
16+
int index = int(dispatchThreadID.x);
17+
18+
int baseIndex = index >> 2;
19+
int innerIndex = index & 3;
20+
21+
RWStructuredBuffer<int> buffer = g_aoa[baseIndex];
22+
23+
// Get the size
24+
uint bufferCount, bufferStride;
25+
buffer.GetDimensions(bufferCount, bufferStride);
26+
27+
if (innerIndex >= bufferCount)
28+
{
29+
innerIndex = bufferCount - 1;
30+
}
31+
outputBuffer[index] = buffer[innerIndex];
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
1
2+
2
3+
3
4+
4
5+
8
6+
11
7+
22
8+
22

0 commit comments

Comments
 (0)