yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
004fe27a5
master
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}