yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f02b08490
master
1//TEST_CATEGORY(wave-mask, compute) 2//DISABLE_TEST:COMPARE_COMPUTE_EX:-cpu -compute -shaderobj 3//DISABLE_TEST:COMPARE_COMPUTE_EX:-slang -compute -shaderobj 4//TEST:COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile cs_6_0 -shaderobj -render-feature hardware-device 5//TEST(vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -render-feature hardware-device 6//TEST:COMPARE_COMPUTE_EX:-cuda -compute -shaderobj 7 8//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer 9RWStructuredBuffer<int> outputBuffer; 10 11//TEST_INPUT:ubuffer(data=[3 10 2 -1 4 53 4 6 1 2 3 4 7 5 3 1], stride=4):name inputBuffer 12RWStructuredBuffer<int> inputBuffer; 13 14groupshared int sharedMem[32]; 15 16int exclusivePrefixSum(WaveMask mask, int index, int waveLaneId, int originalValue, int elementCount) 17{ 18 WaveMask localMask = WaveMaskBallot(mask, index < elementCount); 19 20 sharedMem[index] = 0; 21 22 if(waveLaneId < elementCount) 23 { 24 int temp = 0; 25 int val = originalValue; 26 27 for(int i = 1; i < elementCount; i += i) 28 { 29 int temp = WaveMaskShuffle(localMask, val, waveLaneId - i); 30 if(waveLaneId >= i) 31 { 32 val += temp; 33 } 34 } 35 36 // Make it an exclusive prefix sum 37 val -= originalValue; 38 39 // Write to shared memory 40 sharedMem[index] = val; 41 return val; 42 } 43 44 return 0; 45} 46 47// It matters how kernels with WaveMask intrinsics are launched(!). 48// TODO(JS): 49// If I launch with an numthreads amount that is not the size of the Wave on the device, then some 50// lanes will not be executing at startup, and the kernel will have to know that is the case. 51// This works currently though because the mask is only used 52// on CUDA, and it's Wave size is 32. 53[numthreads(32, 1, 1)] 54void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) 55{ 56 // Assumes all threads in the Wave are active at start. 57 WaveMask waveMask = ~WaveMask(0); 58 59 int index = int(dispatchThreadID.x); 60 const int waveLaneId = int(WaveGetLaneIndex()); 61 62 const int value = inputBuffer[index]; 63 const int elementCount = 9; 64 65 exclusivePrefixSum(waveMask, index, waveLaneId, value, elementCount); 66 67 // We don't read from any other lane, so we don't actually need any sync 68 //WaveMaskSharedSync(waveMask); 69 70 // It returns the result, but we are going to read from shared memory, to check that aspect worked 71 int prefixValue = sharedMem[index]; 72 73 outputBuffer[index] = prefixValue; 74}