//TEST_CATEGORY(wave, compute) //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-via-glsl //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-cuda -compute -shaderobj -xslang -DCUDA //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly -xslang -DUSE_GLSL_SYNTAX -allow-glsl //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 RWStructuredBuffer outputBuffer; #if defined(USE_GLSL_SYNTAX) #define __partitionedMin subgroupPartitionedMinNV #define __partitionedMax subgroupPartitionedMaxNV #else #define __partitionedMin WaveMultiMin #define __partitionedMax WaveMultiMax #endif static uint gMinResult = 0; static uint gMaxResult = 0; static uint gMinMaxValue = 0; __generic bool test1MinMax(uint4 mask) { let minResult = T(gMinResult); let maxResult = T(gMaxResult); let minMaxValue = T(gMinMaxValue); return true & all(__partitionedMin(minMaxValue, mask) == minResult) & all(__partitionedMax(minMaxValue, mask) == maxResult) ; } __generic bool testVMinMax(uint4 mask) { typealias GVec = vector; let minResult = GVec(T(gMinResult)); let maxResult = GVec(T(gMaxResult)); let minMaxValue = GVec(T(gMinMaxValue)); return true & all(__partitionedMin(minMaxValue, mask) == minResult) & all(__partitionedMax(minMaxValue, mask) == maxResult) ; } bool testMinMax(uint4 mask) { return true & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) #if !defined(CUDA) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & test1MinMax(mask) & testVMinMax(mask) & testVMinMax(mask) & testVMinMax(mask) #endif ; } [numthreads(32, 1, 1)] [shader("compute")] void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) { uint index = dispatchThreadID.x; // Split into two groups, first group has 15 invocations/lanes and second group has 17. let isSecondGroup = index >= 15; uint4 mask = isSecondGroup ? uint4(0xFFFF8000, 0, 0, 0) : uint4(0x0007FFF, 0, 0, 0); // Set min value on one invocation on each partition/mask. let isMinInvocation = (index == 0) || (index == 15); gMinResult = isSecondGroup ? uint(2) : uint(0); gMaxResult = isSecondGroup ? uint(3) : uint(1); gMinMaxValue = isMinInvocation ? gMinResult : gMaxResult; bool result = true && testMinMax(mask) ; // CHECK-COUNT-32: 1 outputBuffer[index] = uint(result); }