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-param3.slang` by putting 4// resources into the concrete types that satisfy interface-type 5// shader parameters. 6// 7 8//DISABLED_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute 9 10//DISABLED_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile sm_6_0 11//DISABLED_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute 12 13// A lot of the setup is the same as for `interface-shader-param`, 14// so look there if you want the comments. 15 16interface IRandomNumberGenerator 17{ 18 [mutating] 19 int randomInt(); 20} 21 22interface IRandomNumberGenerationStrategy 23{ 24 associatedtype Generator : IRandomNumberGenerator; 25 Generator makeGenerator(int seed); 26} 27 28interface IModifier 29{ 30 int modify(int val); 31} 32 33int test( 34 int seed, 35 IRandomNumberGenerationStrategy inStrategy, 36 IModifier modifier) 37{ 38 let strategy = inStrategy; 39 var generator = strategy.makeGenerator(seed); 40 let unused = generator.randomInt(); 41 let val = generator.randomInt(); 42 let modifiedVal = modifier.modify(val); 43 return modifiedVal; 44} 45 46 47//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=gOutputBuffer 48RWStructuredBuffer<int> gOutputBuffer; 49 50// Note: a constant buffer register/binding is always claimed 51// for `gStrategy` during initial compilation (before specialization) 52// because the layout logic has no way of knowing if the type 53// that gets plugged in will involve uniform/ordinary data 54// or not. 55// 56//TEST_INPUT:cbuffer(data=[0]):name=gStrategy 57// 58ConstantBuffer<IRandomNumberGenerationStrategy> gStrategy; 59 60// The concrete types we plug in for `gStrategy` and `modifier` 61// have buffer resources in them, so we need to assign them 62// data. The registers/bindings for these parameters will 63// always come after all other shader parameters in the same 64// scope (global or entry-point). 65// 66// Here's the data for `gStrategy`: 67// 68//TEST_INPUT: globalExistentialType MyStrategy 69//TEST_INPUT:ubuffer(data=[1 2 4 8], stride=4): 70 71 72[numthreads(4, 1, 1)] 73void computeMain( 74 75// Similarly to the previous test, we are declaring two `uniform` 76// parameters on the entry point, where one will be plugged in 77// with a concrete type, and thus get laid out second. 78// 79 uniform IModifier modifier, 80 uniform int extra, 81// 82// The uniform/ordinary data for these two parameters will end 83// up in the constant buffers, so let's declare that. Unlike 84// the previous test, the concrete type plugged in for `modifier` 85// has no uniform/ordinary data, so we don't need to fill it in. 86// 87// We *do* need to reserve space in the constant buffer for the 88// existential value (RTTI, witness table, any-value) and that 89// needs to come *before* the value for `extra`. 90// 91//TEST_INPUT:root_constants(data=[0 0 0 0 0 0 0 0 256]): 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 RWStructuredBuffer<int> globalSeeds; 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 = { globalSeeds[seed] }; 126 return generator; 127 } 128} 129 130struct MyModifier : IModifier 131{ 132 RWStructuredBuffer<int> localModifiers; 133 134 int modify(int val) 135 { 136 return val ^ localModifiers[val & 3]; 137 } 138} 139 140// Here's the data for `modifier`: 141// 142//TEST_INPUT: entryPointExistentialType MyModifier 143//TEST_INPUT:ubuffer(data=[16 32 64 128], stride=4):