//TEST_CATEGORY(wave, compute) //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-cuda -compute -shaderobj -profile sm_6_0 //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-via-glsl -profile sm_6_0 -Xslang... -capability GL_KHR_shader_subgroup_rotate -X. //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly -xslang -DUSE_GLSL_SYNTAX -allow-glsl //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-via-glsl -profile sm_6_0 -allow-glsl -Xslang... -DUSE_GLSL_SYNTAX -capability GL_KHR_shader_subgroup_rotate -X. #if defined(USE_GLSL_SYNTAX) #define __clusteredRotate subgroupClusteredRotate #else #define __clusteredRotate WaveClusteredRotate #endif //TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer; #define SUBGROUP_SIZE 32 #define DELTA 3 #define CLUSTER_SIZE 8 static uint threadIndex; static uint clusterIndex; static uint rotatedValue; __generic bool test1ClusteredRotate() { return __clusteredRotate(T(threadIndex), DELTA, CLUSTER_SIZE) == T(rotatedValue); } __generic bool testVRClusteredRotate() { typealias gvec = vector; #if defined(USE_GLSL_SYNTAX) return (__clusteredRotate(gvec(T(threadIndex)), DELTA, CLUSTER_SIZE) == gvec(T(rotatedValue))); #else return (__clusteredRotate(gvec(T(threadIndex)), DELTA, CLUSTER_SIZE) == gvec(T(rotatedValue)))[0]; #endif } bool test1ClusteredRotateBool() { bool currentValue = (threadIndex % 2 == 0) ? true : false; bool rotatedValueBool = (threadIndex % 2 == 0) ? false : true; return __clusteredRotate(currentValue, DELTA, CLUSTER_SIZE) == rotatedValueBool; } __generic bool testVRClusteredRotateBool() { typealias gvec = vector; bool currentValue = (threadIndex % 2 == 0) ? true : false; bool rotatedValueBool = (threadIndex % 2 == 0) ? false : true; #if defined(USE_GLSL_SYNTAX) return (__clusteredRotate(gvec(currentValue), DELTA, CLUSTER_SIZE) == gvec(rotatedValueBool)); #else return (__clusteredRotate(gvec(currentValue), DELTA, CLUSTER_SIZE) == gvec(rotatedValueBool))[0]; #endif } bool testClusteredRotate() { return true & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & testVRClusteredRotate() & test1ClusteredRotateBool() & testVRClusteredRotateBool<2>() & testVRClusteredRotateBool<3>() & testVRClusteredRotateBool<4>() ; } [shader("compute")] [numthreads(SUBGROUP_SIZE, 1, 1)] void computeMain(uint3 dispatchID : SV_DispatchThreadID) { threadIndex = dispatchID.x; clusterIndex = dispatchID.x % CLUSTER_SIZE; // Determine expected value of clustered rotate in current invocation. // The values passed in are global invocation ids, and we rotate them withina cluster of size `CLUSTER_SIZE`. uint clusterStart = (threadIndex / CLUSTER_SIZE) * CLUSTER_SIZE; rotatedValue = clusterStart + ((threadIndex - clusterStart + DELTA) % CLUSTER_SIZE); bool result = true & testClusteredRotate() ; // CHECK: 1 outputBuffer[0] = uint(result); }