diff options
Diffstat (limited to 'tests/compute/buffer-layout.slang')
| -rw-r--r-- | tests/compute/buffer-layout.slang | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/tests/compute/buffer-layout.slang b/tests/compute/buffer-layout.slang new file mode 100644 index 000000000..145da99c8 --- /dev/null +++ b/tests/compute/buffer-layout.slang @@ -0,0 +1,131 @@ +// buffer-layout.slang + +// The goal of this test is to make sure that constant and structured +// buffers obey the rules we expect of the each target API. + +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute + + +//TEST_INPUT: ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out +RWStructuredBuffer<int> outputBuffer; + +struct A +{ + float x; + float y; +} + +struct S +{ + // The first field in a struct isn't going to be that + // interesting, because it will always get offset zero, + // so we just use this to establish a poorly-aligned + // starting point for the next field. + // + // offset size alignment + // + // 0 4 4 + // + float z; + + // The `std140` and D3D constant buffer ruless both + // ensure a minimum of 16-byte alignment on `struct` + // types, but differ in that D3D does not round up + // the total size of a type to its alignment. + // + // The `std430` and structured buffer rules don't + // perform any over-alignment on `struct` types and + // instead align them using the "natural" rules one + // might expect of, e.g., a C compiler. + // + // offset size alignment + // + // cbuffer 16 8 16 + // std140 16 16 16 + // + // struct 4 8 4 + // std430 4 8 4 + // + A a; + + // Now we insert an ordinary `int` field just as + // a way to probe the offset so far. + // + // offset size alignment + // + // cbuffer 24 4 4 + // std140 32 4 4 + // + // struct 12 4 4 + // std430 12 4 4 + // + int b; + + // As our next stress-test case, we will insert an + // array with elements that aren't a multiple of + // 16 bytes in size. + // + // The contant/uniform buffer rules will set the + // array stride to a multiple of 16 bytes in this case. + // The only difference between D3D rules and `std140` + // here is that D3D does not round up the size to + // the alignment. + // + // The structured/std430 rules don't do anything + // to over-align an array, so it is laid out relatively + // naturally, but note that D3D still follows its rule + // of not letting a vector "straddle" a 16-byte boundary, + // even if it doesn't bump up the alignment of + // vector types. + // + // offset size alignment + // + // cbuffer 32 24 16 + // std140 48 32 32 + // + // struct 16 16 4 + // std430 16 16 8 + // + float2 c[2]; + + // Now we put in one more ordinary `int` field + // just to probe the offset computed so far. + // offset size alignment + // + // cbuffer 56 4 4 + // std140 80 4 4 + // + // struct 32 4 4 + // std430 32 4 4 + // + int d; +} + +//TEST_INPUT:cbuffer(data=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32]):dxbinding(0),glbinding(0) +ConstantBuffer<S> cb; + +//TEST_INPUT:ubuffer(data=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32],stride=4):dxbinding(0),glbinding(1) +RWStructuredBuffer<S> sb; + +int test(int val) +{ + val = val+1; + val = val*16 + cb.b; + val = val*256 + cb.d; + val = val*256 + sb[0].b; + val = val*256 + sb[0].d; + return val; +} + +[numthreads(4, 1, 1)] +void computeMain( + uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + int inVal = tid; + int outVal = test(inVal); + outputBuffer[tid] = outVal; +}
\ No newline at end of file |
