// 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 -emit-spirv-directly // TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-slang -compute -vk -shaderobj -emit-spirv-via-glsl -profile sm_6_0 -Xslang... -capability GL_KHR_shader_subgroup_rotate -X. //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-metal -compute -shaderobj -xslang -DMETAL //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):-slang -compute -vk -shaderobj -emit-spirv-via-glsl -allow-glsl -profile sm_6_0 -Xslang... -DUSE_GLSL_SYNTAX -capability GL_KHR_shader_subgroup_rotate -X. //TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-metal -compute -shaderobj -xslang -DMETAL -xslang -DUSE_GLSL_SYNTAX -allow-glsl #if defined(USE_GLSL_SYNTAX) #define __rotate subgroupRotate #else #define __rotate WaveRotate #endif //TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer; #define SUBGROUP_SIZE 32 #define DELTA 3 static uint threadIndex; static uint rotatedValue; __generic bool test1Rotate() { return __rotate(T(threadIndex), DELTA) == T(rotatedValue); } __generic bool testVRotate() { typealias gvec = vector; #if defined(USE_GLSL_SYNTAX) return (__rotate(gvec(T(threadIndex)), DELTA) == gvec(T(rotatedValue))); #else return (__rotate(gvec(T(threadIndex)), DELTA) == gvec(T(rotatedValue)))[0]; #endif } bool test1RotateBool() { bool currentValue = (threadIndex % 2 == 0) ? true : false; bool rotatedValueBool = (threadIndex % 2 == 0) ? false : true; return __rotate(currentValue, DELTA) == rotatedValueBool; } __generic bool testVRotateBool() { typealias gvec = vector; bool currentValue = (threadIndex % 2 == 0) ? true : false; bool rotatedValueBool = (threadIndex % 2 == 0) ? false : true; #if defined(USE_GLSL_SYNTAX) return (__rotate(gvec(currentValue), DELTA) == gvec(rotatedValueBool)); #else return (__rotate(gvec(currentValue), DELTA) == gvec(rotatedValueBool))[0]; #endif } bool testRotate() { return true & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() // Subgroup rotate operations on these builtin types are not supported on Metal. #if !defined(METAL) & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1Rotate() & testVRotate() & testVRotate() & testVRotate() & test1RotateBool() & testVRotateBool<2>() & testVRotateBool<3>() & testVRotateBool<4>() #endif ; } [shader("compute")] [numthreads(SUBGROUP_SIZE, 1, 1)] void computeMain(uint3 dispatchID : SV_DispatchThreadID) { threadIndex = dispatchID.x; rotatedValue = (threadIndex + DELTA) % SUBGROUP_SIZE; bool result = true & testRotate() ; // CHECK: 1 outputBuffer[0] = uint(result); }