diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-10-11 14:35:07 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-11 14:35:07 -0400 |
| commit | 2420f47b56647d33e5dbb6730718905a767c7244 (patch) | |
| tree | 402e884c3664cdb7f2c58bf08fc9261b76de5707 | |
| parent | 9c17d0be79834a8ebe2888aed8905bae355cb674 (diff) | |
CPU unsized array documentation and another example (#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.
| -rw-r--r-- | docs/cpu-target.md | 30 | ||||
| -rw-r--r-- | tests/compute/unbounded-array-of-array-syntax.slang | 32 | ||||
| -rw-r--r-- | tests/compute/unbounded-array-of-array-syntax.slang.expected.txt | 8 |
3 files changed, 68 insertions, 2 deletions
diff --git a/docs/cpu-target.md b/docs/cpu-target.md index d9734ae90..413a71387 100644 --- a/docs/cpu-target.md +++ b/docs/cpu-target.md @@ -182,11 +182,35 @@ Notice that of the entry point parameters `dispatchThreadID` is not part of Unif size_t sizeInBytes; ``` -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`. +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`. + The actual definitions for the interfaces for resource types, and types are specified in 'slang-cpp-types.h' in the `prelude` directory. -The code that sets up the prelude for the test infrastucture and command line usage can be found in ```TestToolUtil::setSessionDefaultPrelude```. +## Unsized arrays + +Unsized arrays can be used, which are indicated by an array with no size as in `[]`. For example + +``` + RWStructuredBuffer<int> arrayOfArrays[]; +``` + +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... + +``` + T* data; + size_t count; +``` + +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 + +* That the count has to be stored elsewhere (unlike with CPU) +* On some GPU targets there is no bounds checking - accessing outside the bound values can cause *undefined behavior* +* The elements may be laid out *contiguously* on GPU + +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. + +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. ## Prelude @@ -228,6 +252,8 @@ It may be useful to be able to include `slang-cpp-types.h` in C++ code to access 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>`. +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"`. + Language aspects ================ diff --git a/tests/compute/unbounded-array-of-array-syntax.slang b/tests/compute/unbounded-array-of-array-syntax.slang new file mode 100644 index 000000000..fdc04c95e --- /dev/null +++ b/tests/compute/unbounded-array-of-array-syntax.slang @@ -0,0 +1,32 @@ +//DISABLE_TEST:CPU_REFLECTION: -profile cs_5_0 -entry computeMain -target cpp +//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):dxbinding(0),glbinding(0),out,name outputBuffer +RWStructuredBuffer<int> outputBuffer; + +//TEST_INPUT:array(size=2):name g_aoa +RWStructuredBuffer<int> g_aoa[]; + +//TEST_INPUT:ubuffer(data=[1 2 3 4], stride=4):name=g_aoa[0] +//TEST_INPUT:ubuffer(data=[8 17 34], stride=4):name=g_aoa[1] + +[numthreads(8, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int index = int(dispatchThreadID.x); + + int baseIndex = index >> 2; + int innerIndex = index & 3; + + RWStructuredBuffer<int> buffer = g_aoa[baseIndex]; + + // Get the size + uint bufferCount, bufferStride; + buffer.GetDimensions(bufferCount, bufferStride); + + if (innerIndex >= bufferCount) + { + innerIndex = bufferCount - 1; + } + outputBuffer[index] = buffer[innerIndex]; +}
\ No newline at end of file diff --git a/tests/compute/unbounded-array-of-array-syntax.slang.expected.txt b/tests/compute/unbounded-array-of-array-syntax.slang.expected.txt new file mode 100644 index 000000000..aeec8496c --- /dev/null +++ b/tests/compute/unbounded-array-of-array-syntax.slang.expected.txt @@ -0,0 +1,8 @@ +1 +2 +3 +4 +8 +11 +22 +22 |
