yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f02b08490
master
1// interface-shader-param3.slang 2 3// This test builds on `interface-shader-param2.slang` by putting 4// interface types at more complicated places in the overall layout. 5// 6 7//DISABLED_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute 8 9//DISABLED_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile sm_6_0 10//DISABLED_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute 11 12// A lot of the setup is the same as for `interface-shader-param`, 13// so look there if you want the comments. 14 15interface IRandomNumberGenerator 16{ 17 [mutating] 18 int randomInt(); 19} 20 21interface IRandomNumberGenerationStrategy 22{ 23 associatedtype Generator : IRandomNumberGenerator; 24 Generator makeGenerator(int seed); 25} 26 27interface IModifier 28{ 29 int modify(int val); 30} 31 32int test( 33 int seed, 34 IRandomNumberGenerationStrategy inStrategy, 35 IModifier modifier) 36{ 37 let strategy = inStrategy; 38 var generator = strategy.makeGenerator(seed); 39 let unused = generator.randomInt(); 40 let val = generator.randomInt(); 41 let modifiedVal = modifier.modify(val); 42 return modifiedVal; 43} 44 45 46//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out 47RWStructuredBuffer<int> gOutputBuffer; 48 49ConstantBuffer<IRandomNumberGenerationStrategy> gStrategy; 50 51// Note: The current strategy we use for laying out shader 52// parameters in the presence of existential/interface types 53// is to always put global-scope parameters before any 54// entry-point parameters. As a result we need to provide 55// the buffer for the specialized version of `gStrategy` 56// here, and we will go ahead and provide the concrete 57// type argument at the same time. 58// 59//TEST_INPUT: globalExistentialType MyStrategy 60//TEST_INPUT:cbuffer(data=[0 0 0 0 1 0 0 0], stride=4): 61 62[numthreads(4, 1, 1)] 63void computeMain( 64 65// We will be declaring two different `uniform` parameters in the 66// entry-point parameter list, which will both get allocated to 67// the same constant buffer. 68// 69// The first parameter will use an interface type, while the second 70// will be plain-old-data. 71// 72 uniform IModifier modifier, 73 uniform int extra, 74// 75// The computed layout for the entry-point constant buffer will 76// always place the non-interface-type data first, so the first 77// four bytes of our buffer represent the `extra` field. 78// 79// After all the non-interface-type data is laid out, we lay out 80// the contents of extistential value slots in order, using the 81// ordinary constant buffer packing rules. Because the concrete 82// type we'll be plugging in for `modifier` is a `struct` type, 83// it will need to start on a 16-byte-aligned boundary. 84// 85// Here's the incantation to make the test runner fill in the constant buffer: 86// 87//TEST_INPUT:root_constants(data=[0 0 0 0 16 0 0 0 256], stride=4): 88// 89// So, the value `256` will be used for `extra` and the value `16` 90// will be written to the first four bytes of the concrete value 91// being used for `modifier`. 92 93 uint3 dispatchThreadID : SV_DispatchThreadID) 94{ 95 let tid = dispatchThreadID.x; 96 97 let inputVal : int = tid; 98 let outputVal = test(inputVal, gStrategy, modifier) 99 + extra*extra; 100 101 gOutputBuffer[tid] = outputVal; 102} 103 104// Okay, now we get to the part that is unique starting 105// in this test: we add data to the concrete types 106// that we will use as parameters. 107 108struct MyStrategy : IRandomNumberGenerationStrategy 109{ 110 int globalSeed; 111 112 struct Generator : IRandomNumberGenerator 113 { 114 int state; 115 116 [mutating] 117 int randomInt() 118 { 119 return state++; 120 } 121 } 122 123 Generator makeGenerator(int seed) 124 { 125 Generator generator = { seed ^ globalSeed }; 126 return generator; 127 } 128} 129 130struct MyModifier : IModifier 131{ 132 int localModifier; 133 134 int modify(int val) 135 { 136 return val * localModifier; 137 } 138} 139 140//TEST_INPUT: entryPointExistentialType MyModifier