yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

skallweitNVMetal compute tests (#4292)004fe27a5

master
3.8 KiB132 linesraw
1// buffer-layout.slang
2
3// The goal of this test is to make sure that constant and structured
4// buffers obey the rules we expect of the each target API.
5
6//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx11 -shaderobj
7//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -shaderobj
8//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj
9//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cpu -shaderobj
10//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cuda -shaderobj
11
12//TEST_INPUT: ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
13RWStructuredBuffer<int> outputBuffer;
14
15struct A
16{
17    float x;
18    float y;
19}
20
21struct S
22{
23    // The first field in a struct isn't going to be that
24    // interesting, because it will always get offset zero,
25    // so we just use this to establish a poorly-aligned
26    // starting point for the next field.
27    //
28    //          offset  size    alignment
29    //
30    //          0       4       4
31    //
32    float z;
33
34    // The `std140` and D3D constant buffer ruless both
35    // ensure a minimum of 16-byte alignment on `struct`
36    // types, but differ in that D3D does not round up
37    // the total size of a type to its alignment.
38    //
39    // The `std430` and structured buffer rules don't
40    // perform any over-alignment on `struct` types and
41    // instead align them using the "natural" rules one
42    // might expect of, e.g., a C compiler.
43    //
44    //          offset  size    alignment
45    //
46    // cbuffer  16      8       16
47    // std140   16      16      16
48    //
49    // struct   4       8       4
50    // std430   4       8       4
51    //
52    A      a;
53
54    // Now we insert an ordinary `int` field just as
55    // a way to probe the offset so far.
56    //
57    //          offset  size    alignment
58    //
59    // cbuffer  24      4       4
60    // std140   32      4       4
61    //
62    // struct   12      4       4
63    // std430   12      4       4
64    //
65    int    b;
66
67    // As our next stress-test case, we will insert an
68    // array with elements that aren't a multiple of
69    // 16 bytes in size.
70    //
71    // The contant/uniform buffer rules will set the
72    // array stride to a multiple of 16 bytes in this case.
73    // The only difference between D3D rules and `std140`
74    // here is that D3D does not round up the size to
75    // the alignment.
76    //
77    // The structured/std430 rules don't do anything
78    // to over-align an array, so it is laid out relatively
79    // naturally, but note that D3D still follows its rule
80    // of not letting a vector "straddle" a 16-byte boundary,
81    // even if it doesn't bump up the alignment of
82    // vector types.
83    //
84    //          offset  size    alignment
85    //
86    // cbuffer  32      24      16
87    // std140   48      32      32
88    //
89    // struct   16      16      4
90    // std430   16      16      8
91    //
92    float2 c[2];
93
94    // Now we put in one more ordinary `int` field
95    // just to probe the offset computed so far.
96    //          offset  size    alignment
97    //
98    // cbuffer  56      4      4
99    // std140   80      4      4
100    //
101    // struct   32      4      4
102    // std430   32      4      4
103    //
104    int    d;
105}
106
107//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]):name=cb
108ConstantBuffer<S> cb;
109
110//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):name=sb
111RWStructuredBuffer<S> sb;
112
113int test(int val)
114{
115    val = val+1;
116    val = val*16  + cb.b;
117    val = val*256 + cb.d;
118    val = val*256 + sb[0].b;
119    val = val*256 + sb[0].d;
120    return val;
121}
122
123[numthreads(4, 1, 1)]
124void computeMain(
125    int3 dispatchThreadID : SV_DispatchThreadID)
126{
127    int tid = dispatchThreadID.x;
128
129    int inVal = tid;
130    int outVal = test(inVal);
131    outputBuffer[tid] = outVal;
132}