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, compute) 2//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly 3//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-via-glsl 4//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-slang -compute -dx12 -profile sm_6_5 -shaderobj 5//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-cuda -compute -shaderobj -xslang -DCUDA 6 7//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly -xslang -DUSE_GLSL_SYNTAX -allow-glsl 8 9//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer 10RWStructuredBuffer<uint> outputBuffer; 11 12#if defined(USE_GLSL_SYNTAX) 13#define __partitionedInclusiveAnd subgroupPartitionedInclusiveAndNV 14#define __partitionedInclusiveOr subgroupPartitionedInclusiveOrNV 15#define __partitionedInclusiveXor subgroupPartitionedInclusiveXorNV 16#define __partitionedExclusiveAnd subgroupPartitionedExclusiveAndNV 17#define __partitionedExclusiveOr subgroupPartitionedExclusiveOrNV 18#define __partitionedExclusiveXor subgroupPartitionedExclusiveXorNV 19#else 20#define __partitionedInclusiveAnd WaveMultiPrefixInclusiveBitAnd 21#define __partitionedInclusiveOr WaveMultiPrefixInclusiveBitOr 22#define __partitionedInclusiveXor WaveMultiPrefixInclusiveBitXor 23#define __partitionedExclusiveAnd WaveMultiPrefixExclusiveBitAnd 24#define __partitionedExclusiveOr WaveMultiPrefixExclusiveBitOr 25#define __partitionedExclusiveXor WaveMultiPrefixExclusiveBitXor 26#endif 27 28 29static uint gAndValue = 0; 30static uint gAndResultExclusive = 0; 31static uint gOrValue = 0; 32static uint gOrResult = 0; 33static uint gXorValue = 0; 34static uint gXorResultInclusive = 0; 35static uint gXorResultExclusive = 0; 36 37__generic<T : __BuiltinLogicalType> 38bool test1Bitwise(uint4 mask) 39{ 40 let andValue = T(gAndValue); 41 let orValue = T(gOrValue); 42 let xorValue = T(gXorValue); 43 44 return true 45 & (__partitionedInclusiveAnd(andValue, mask) == andValue) 46 & (__partitionedExclusiveAnd(andValue, mask) == T(gAndResultExclusive)) 47 & (__partitionedInclusiveOr(orValue, mask) == orValue) 48 & (__partitionedExclusiveOr(orValue, mask) == T(0)) 49 & (__partitionedInclusiveXor(xorValue, mask) == T(gXorResultInclusive)) 50 & (__partitionedExclusiveXor(xorValue, mask) == T(gXorResultExclusive)) 51 ; 52} 53 54__generic<T : __BuiltinLogicalType, let N : int> 55bool testVBitwise(uint4 mask) { 56 typealias GVec = vector<T, N>; 57 58 let andValue = GVec(T(gAndValue)); 59 let orValue = GVec(T(gOrValue)); 60 let xorValue = GVec(T(gXorValue)); 61 62 return true 63 & all(__partitionedInclusiveAnd(andValue, mask) == andValue) 64 & all(__partitionedExclusiveAnd(andValue, mask) == GVec(T(gAndResultExclusive))) 65 & all(__partitionedInclusiveOr(orValue, mask) == orValue) 66 & all(__partitionedExclusiveOr(orValue, mask) == GVec(T(0))) 67 & all(__partitionedInclusiveXor(xorValue, mask) == GVec(T(gXorResultInclusive))) 68 & all(__partitionedExclusiveXor(xorValue, mask) == GVec(T(gXorResultExclusive))) 69 ; 70} 71 72bool testBitwise(uint4 mask) 73{ 74 return true 75 & test1Bitwise<int>(mask) 76 & testVBitwise<int, 2>(mask) 77 & testVBitwise<int, 3>(mask) 78 & testVBitwise<int, 4>(mask) 79 & test1Bitwise<uint>(mask) 80 & testVBitwise<uint, 2>(mask) 81 & testVBitwise<uint, 3>(mask) 82 & testVBitwise<uint, 4>(mask) 83 84 // TODO: these are failing SPIRV validation and should be fixed. 85 // SPIRV's ops do not directly accept/return bool. 86 // & test1Bitwise<bool>(mask) 87 // & testVBitwise<bool, 2>(mask) 88 // & testVBitwise<bool, 3>(mask) 89 // & testVBitwise<bool, 4>(mask) 90 91#if defined(VK) 92 & test1Bitwise<int8_t>(mask) 93 & testVBitwise<int8_t, 2>(mask) 94 & testVBitwise<int8_t, 3>(mask) 95 & testVBitwise<int8_t, 4>(mask) 96 & test1Bitwise<uint8_t>(mask) 97 & testVBitwise<uint8_t, 2>(mask) 98 & testVBitwise<uint8_t, 3>(mask) 99 & testVBitwise<uint8_t, 4>(mask) 100#endif 101 102#if !defined(CUDA) 103 & test1Bitwise<int16_t>(mask) 104 & testVBitwise<int16_t, 2>(mask) 105 & testVBitwise<int16_t, 3>(mask) 106 & testVBitwise<int16_t, 4>(mask) 107 & test1Bitwise<int64_t>(mask) 108 & testVBitwise<int64_t, 2>(mask) 109 & testVBitwise<int64_t, 3>(mask) 110 & testVBitwise<int64_t, 4>(mask) 111 & test1Bitwise<uint16_t>(mask) 112 & testVBitwise<uint16_t, 2>(mask) 113 & testVBitwise<uint16_t, 3>(mask) 114 & testVBitwise<uint16_t, 4>(mask) 115 & test1Bitwise<uint64_t>(mask) 116 & testVBitwise<uint64_t, 2>(mask) 117 & testVBitwise<uint64_t, 3>(mask) 118 & testVBitwise<uint64_t, 4>(mask) 119#endif 120 ; 121} 122 123[numthreads(32, 1, 1)] 124[shader("compute")] 125void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) 126{ 127 let index = dispatchThreadID.x; 128 129 let isSecondGroup = index >= 15; 130 let mask = isSecondGroup ? uint4(0xFFFF8000, 0, 0, 0) : uint4(0x0007FFF, 0, 0, 0); 131 let isLastInvocation = (index == 31); 132 let isLastInPartition = (index == 14) || (index == 31); 133 let isFirstInPartition = (index == 0) || (index == 15); 134 135 // 136 // Prefix and. 137 // - Both groups use 1 except for the last invocation in each partition where input is 0. 138 // - For inclusive ops, result is 1 except for last invocation in each partition. 139 // - For exclusive ops, first in partition is always results to ~0(identity). Otherwise exclusive ops result to 1. 140 gAndValue = isLastInPartition ? uint(0) : uint(1); 141 gAndResultExclusive = isFirstInPartition ? uint(~0) : uint(1); 142 143 // 144 // Prefix or. 145 // - Both groups use 0 except for the last invocation in each partition where input is 1. 146 // - For inclusive ops, result is 0 except for last invocation in each partition. 147 // - For exclusive ops, result is always 0. 148 gOrValue = isLastInPartition ? uint(1) : uint(0); 149 150 // Prefix xor. 151 // - First group input is always 1. Inclusive results alternate between 1 and 0, starting at 1. Exclusive result is also alternates but starts at 0 (opposite of inclusive result). 152 // - Second group is always 0. Results are all 0. 153 gXorValue = isSecondGroup ? uint(0) : uint(1); 154 gXorResultInclusive = (isSecondGroup || (index % 2 != 0)) ? uint(0) : uint(1); 155 gXorResultExclusive = isSecondGroup ? uint(0) : (uint(1) - gXorResultInclusive); 156 157 bool result = true 158 & testBitwise(mask) 159 ; 160 161 // CHECK-COUNT-32: 1 162 outputBuffer[index] = uint(result); 163}