From 08696443a0a11a4178dccf849d25dcd08780a99e Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Fri, 18 Jul 2025 09:58:08 +0100 Subject: [PATCH] Added workgroup performance tests and basic D3D11 Workgroup test Added D3D11_Workgroup_Zoo, D3D12 Workgroup Zoo, Vk Workgroup Zoo performance tests Performance tests primarily for performance testing workgroup debugging speed Changed workgroup and subgroup result variable from "data" -> "testResult" to help to reduce conflicts --- util/test/demos/d3d11/d3d11_workgroup_zoo.cpp | 272 ++++++++++++++++++ util/test/demos/d3d12/d3d12_subgroup_zoo.cpp | 94 +++--- util/test/demos/d3d12/d3d12_workgroup_zoo.cpp | 243 ++++++++++++---- util/test/demos/demos.vcxproj | 1 + util/test/demos/demos.vcxproj.filters | 3 + util/test/demos/vk/vk_subgroup_zoo.cpp | 76 ++--- util/test/demos/vk/vk_workgroup_zoo.cpp | 230 ++++++++++++--- util/test/rdtest/shared/Subgroup_Zoo.py | 11 +- util/test/tests/D3D11/D3D11_Workgroup_Zoo.py | 5 + 9 files changed, 737 insertions(+), 198 deletions(-) create mode 100644 util/test/demos/d3d11/d3d11_workgroup_zoo.cpp create mode 100644 util/test/tests/D3D11/D3D11_Workgroup_Zoo.py diff --git a/util/test/demos/d3d11/d3d11_workgroup_zoo.cpp b/util/test/demos/d3d11/d3d11_workgroup_zoo.cpp new file mode 100644 index 000000000..6c9a62dd7 --- /dev/null +++ b/util/test/demos/d3d11/d3d11_workgroup_zoo.cpp @@ -0,0 +1,272 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2019-2025 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "3rdparty/fmt/core.h" +#include "d3d11_test.h" + +RD_TEST(D3D11_Workgroup_Zoo, D3D11GraphicsTest) +{ + static constexpr const char *Description = + "Test of behaviour around workgroup operations in shaders."; + + const std::string common = R"EOSHADER( + +cbuffer rootconsts : register(b0) +{ + uint root_test; + uint root_two; +} + +uint GetTest() { return root_test; } + +#define IsTest(x) (GetTest() == x) + +)EOSHADER"; + + const std::string compCommon = common + R"EOSHADER( + +RWStructuredBuffer outbuf : register(u0); + +static uint3 tid; +static uint flatId; + +groupshared uint4 gsmUint4[1024]; + +void SetOutput(float4 val) +{ + outbuf[GetTest() * 1024 + flatId] = val; +} + +void Init(float4 val) +{ + flatId = tid.x + GROUP_SIZE_X * tid.y + GROUP_SIZE_X * GROUP_SIZE_Y * tid.z; + gsmUint4[flatId].xyz = tid; + gsmUint4[flatId].z = tid.x; + SetOutput(val); +} + +)EOSHADER"; + + const std::string testShader = compCommon + R"EOSHADER( + +[numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, 1)] +void main(uint3 inGTid : SV_GroupThreadID) +{ + tid = inGTid; + float4 testResult = 0.0f.xxxx; + Init(testResult); + uint id = flatId; + + if(IsTest(0)) + { + testResult.x = id; + AllMemoryBarrierWithGroupSync(); + } + + SetOutput(testResult); +} + +)EOSHADER"; + + const std::string perfShader = compCommon + R"EOSHADER( + +[numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, GROUP_SIZE_Z)] +void main(uint3 inGTid : SV_GroupThreadID) +{ + tid = inGTid; + float4 testResult = 0.0f.xxxx; + Init(testResult); + uint id = flatId; + + // TEST CASES: + // 0: GPU math : loops 100 + // 1: CPU math : loops 100 + // 2: GPU math : loops 200 + // 3: CPU math : loops 200 + // 4: GPU math : loops 400 + // 5: CPU math : loops 400 + // 6: GPU math : loops 5000 + // 7: CPU math : loops 5000 + bool useCpu = GetTest() & 0x1; + + uint count = 0; + { + uint temp = GetTest() >> 1; + if(temp == 0) + count = 100U; + if(temp == 1) + count = 200U; + if(temp == 2) + count = 400U; + if(temp == 3) + count = 5000U; + } + + if(useCpu) + { + for (uint i = 0; i < count; ++i) + { + gsmUint4[id].x += i; + gsmUint4[id].y += i * i; + testResult.x = testResult.x * testResult.x; + testResult.x += dot(gsmUint4[id], gsmUint4[id]); + } + } + else + { + for (uint i = 0; i < count; ++i) + { + gsmUint4[id].x += i; + gsmUint4[id].y += i * i; + testResult.x = pow(testResult.x, float(root_two)); + testResult.x += dot(gsmUint4[id], gsmUint4[id]); + } + } + + AllMemoryBarrierWithGroupSync(); + + SetOutput(testResult); +} + +)EOSHADER"; + + int main() + { + // initialise, create window, create device, etc + if(!Init()) + return 3; + + ID3D11BufferPtr outBuf = MakeBuffer().Size(sizeof(Vec4f) * 1024).UAV().Structured(sizeof(Vec4f)); + ID3D11UnorderedAccessViewPtr outUAV = MakeUAV(outBuf); + + int cbufferdata[4]; + memset(cbufferdata, 0, sizeof(cbufferdata)); + ID3D11BufferPtr cb = MakeBuffer().Size(16).Constant().Data(&cbufferdata); + + int32_t countCompTests = 0; + size_t pos = 0; + while(pos != std::string::npos) + { + pos = testShader.find("IsTest(", pos); + if(pos == std::string::npos) + break; + pos += sizeof("IsTest(") - 1; + countCompTests = std::max(countCompTests, atoi(testShader.c_str() + pos) + 1); + } + + const int32_t countPerfTests = 8; + + struct CompSize + { + int x, y, z; + }; + CompSize compsizes[] = { + {70, 1, 1}, + }; + std::string comppipe_name[ARRAY_COUNT(compsizes)]; + ID3D11ComputeShaderPtr testShaders[ARRAY_COUNT(compsizes)]; + ID3D11ComputeShaderPtr perfShaders[ARRAY_COUNT(compsizes)]; + + std::string defines; + + for(int i = 0; i < ARRAY_COUNT(compsizes); i++) + { + std::string sizedefine; + sizedefine = + fmt::format("#define GROUP_SIZE_X {}\n#define GROUP_SIZE_Y {}\n#define GROUP_SIZE_Z {}", + compsizes[i].x, compsizes[i].y, compsizes[i].z); + comppipe_name[i] = fmt::format("{}x{}x{}", compsizes[i].x, compsizes[i].y, compsizes[i].z); + + testShaders[i] = CreateCS(Compile(defines + sizedefine + testShader, "main", "cs_5_0", true)); + perfShaders[i] = CreateCS(Compile(defines + sizedefine + perfShader, "main", "cs_5_0", true)); + } + + while(Running()) + { + ClearRenderTargetView(bbRTV, {0.2f, 0.2f, 0.2f, 1.0f}); + + pushMarker("Compute Tests"); + for(size_t p = 0; p < ARRAY_COUNT(compsizes); p++) + { + pushMarker(comppipe_name[p]); + ctx->CSSetShader(testShaders[p], NULL, 0); + ctx->CSSetUnorderedAccessViews(0, 1, &outUAV.GetInterfacePtr(), NULL); + + for(int i = 0; i < countCompTests; ++i) + { + ClearUnorderedAccessView(outUAV, Vec4u()); + ctx->UpdateSubresource(cb, 0, NULL, &i, 8, 0); + ctx->CSSetConstantBuffers(0, 1, &cb.GetInterfacePtr()); + ctx->Dispatch(2, 1, 1); + popMarker(); + } + popMarker(); + } + + pushMarker("Perf Tests"); + for(size_t p = 0; p < ARRAY_COUNT(compsizes); p++) + { + pushMarker(comppipe_name[p]); + ctx->CSSetShader(perfShaders[p], NULL, 0); + ctx->CSSetUnorderedAccessViews(0, 1, &outUAV.GetInterfacePtr(), NULL); + + for(int i = 0; i < countPerfTests; ++i) + { + cbufferdata[0] = i; + cbufferdata[1] = 2; + + bool useCpu = (i & 0x1); + int count = 0; + { + int temp = i >> 1; + if(temp == 0) + count = 100U; + if(temp == 1) + count = 200U; + if(temp == 2) + count = 400U; + if(temp == 3) + count = 5000U; + } + std::string perfTestName = + fmt::format("{} Iterations {} Math", count, useCpu ? "CPU" : "GPU"); + pushMarker(perfTestName); + ClearUnorderedAccessView(outUAV, Vec4u()); + ctx->UpdateSubresource(cb, 0, NULL, cbufferdata, 8, 0); + ctx->CSSetConstantBuffers(0, 1, &cb.GetInterfacePtr()); + ctx->Dispatch(2, 1, 1); + popMarker(); + } + popMarker(); + } + popMarker(); + + Present(); + } + + return 0; + } +}; + +REGISTER_TEST(); diff --git a/util/test/demos/d3d12/d3d12_subgroup_zoo.cpp b/util/test/demos/d3d12/d3d12_subgroup_zoo.cpp index 08f7e4711..d54897eb6 100644 --- a/util/test/demos/d3d12/d3d12_subgroup_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_subgroup_zoo.cpp @@ -57,9 +57,9 @@ RWStructuredBuffer outbuf : register(u0); static uint3 tid; -void SetOutput(float4 data) +void SetOutput(float4 val) { - outbuf[root_test * 1024 + tid.y * GROUP_SIZE_X + tid.x] = data; + outbuf[root_test * 1024 + tid.y * GROUP_SIZE_X + tid.x] = val; } )EOSHADER"; @@ -176,7 +176,7 @@ float4 main(IN input) : SV_Target0 [numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, 1)] void main(uint3 inTid : SV_DispatchThreadID) { - float4 data = 0.0f.xxxx; + float4 testResult = 0.0f.xxxx; tid = inTid; uint id = WaveGetLaneIndex(); @@ -186,26 +186,26 @@ void main(uint3 inTid : SV_DispatchThreadID) if(IsTest(0)) { // Query functions : unit tests - data.x = float(WaveGetLaneCount()); - data.y = float(WaveGetLaneIndex()); - data.z = float(WaveIsFirstLane()); + testResult.x = float(WaveGetLaneCount()); + testResult.y = float(WaveGetLaneIndex()); + testResult.z = float(WaveIsFirstLane()); } else if(IsTest(1)) { // Vote functions : unit tests - data.x = float(WaveActiveAnyTrue(id*2 > id+10)); - data.y = float(WaveActiveAllTrue(id < WaveGetLaneCount())); + testResult.x = float(WaveActiveAnyTrue(id*2 > id+10)); + testResult.y = float(WaveActiveAllTrue(id < WaveGetLaneCount())); if (id > 10) { - data.z = float(WaveActiveAllTrue(id > 10)); + testResult.z = float(WaveActiveAllTrue(id > 10)); uint4 ballot = WaveActiveBallot(id > 20); - data.w = countbits(ballot.x) + countbits(ballot.y) + countbits(ballot.z) + countbits(ballot.w); + testResult.w = countbits(ballot.x) + countbits(ballot.y) + countbits(ballot.z) + countbits(ballot.w); } else { - data.z = float(WaveActiveAllTrue(id > 3)); + testResult.z = float(WaveActiveAllTrue(id > 3)); uint4 ballot = WaveActiveBallot(id > 4); - data.w = countbits(ballot.x) + countbits(ballot.y) + countbits(ballot.z) + countbits(ballot.w); + testResult.w = countbits(ballot.x) + countbits(ballot.y) + countbits(ballot.z) + countbits(ballot.w); } } else if(IsTest(2)) @@ -213,10 +213,10 @@ void main(uint3 inTid : SV_DispatchThreadID) // Broadcast functions : unit tests if (id >= 2 && id <= 20) { - data.x = WaveReadLaneFirst(id); - data.y = WaveReadLaneAt(id, 5); - data.z = WaveReadLaneAt(id, id); - data.w = WaveReadLaneAt(data.x, 2+id%3); + testResult.x = WaveReadLaneFirst(id); + testResult.y = WaveReadLaneAt(id, 5); + testResult.z = WaveReadLaneAt(id, id); + testResult.w = WaveReadLaneAt(testResult.x, 2+id%3); } } else if(IsTest(3)) @@ -224,17 +224,17 @@ void main(uint3 inTid : SV_DispatchThreadID) // Scan and Prefix functions : unit tests if (id >= 2 && id <= 20) { - data.x = WavePrefixCountBits(id > 4); - data.y = WavePrefixCountBits(id > 10); - data.z = WavePrefixSum(data.x); - data.w = WavePrefixProduct(1 + data.y); + testResult.x = WavePrefixCountBits(id > 4); + testResult.y = WavePrefixCountBits(id > 10); + testResult.z = WavePrefixSum(testResult.x); + testResult.w = WavePrefixProduct(1 + testResult.y); } else { - data.x = WavePrefixCountBits(id > 23); - data.y = WavePrefixCountBits(id < 1); - data.z = WavePrefixSum(data.x); - data.w = WavePrefixSum(data.y); + testResult.x = WavePrefixCountBits(id > 23); + testResult.y = WavePrefixCountBits(id < 1); + testResult.z = WavePrefixSum(testResult.x); + testResult.w = WavePrefixSum(testResult.y); } } else if(IsTest(4)) @@ -242,10 +242,10 @@ void main(uint3 inTid : SV_DispatchThreadID) // Reduction functions : unit tests if (id >= 2 && id <= 20) { - data.x = float(WaveActiveMax(id)); - data.y = float(WaveActiveMin(id)); - data.z = float(WaveActiveProduct(id)); - data.w = float(WaveActiveSum(id)); + testResult.x = float(WaveActiveMax(id)); + testResult.y = float(WaveActiveMin(id)); + testResult.z = float(WaveActiveProduct(id)); + testResult.w = float(WaveActiveSum(id)); } } else if(IsTest(5)) @@ -253,10 +253,10 @@ void main(uint3 inTid : SV_DispatchThreadID) // Reduction functions : unit tests if (id >= 2 && id <= 20) { - data.x = float(WaveActiveCountBits(id > 23)); - data.y = float(WaveActiveBitAnd(id)); - data.z = float(WaveActiveBitOr(id)); - data.w = float(WaveActiveBitXor(id)); + testResult.x = float(WaveActiveCountBits(id > 23)); + testResult.y = float(WaveActiveBitAnd(id)); + testResult.z = float(WaveActiveBitOr(id)); + testResult.w = float(WaveActiveBitXor(id)); } } else if(IsTest(6)) @@ -269,13 +269,13 @@ void main(uint3 inTid : SV_DispatchThreadID) bool3 test3 = bool3(test1, (id < 23), (id >= 25)); bool4 test4 = bool4(test1, (id < 23), (id >= 25), (id >= 28)); - data.x = float(WaveActiveAllEqual(test1).x); - data.y = float(WaveActiveAllEqual(test2).y); - data.z = float(WaveActiveAllEqual(test3).z); - data.w = float(WaveActiveAllEqual(test4).w); + testResult.x = float(WaveActiveAllEqual(test1).x); + testResult.y = float(WaveActiveAllEqual(test2).y); + testResult.z = float(WaveActiveAllEqual(test3).z); + testResult.w = float(WaveActiveAllEqual(test4).w); } } - SetOutput(data); + SetOutput(testResult); } )EOSHADER"; @@ -285,7 +285,7 @@ void main(uint3 inTid : SV_DispatchThreadID) [numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, 1)] void main(uint3 inTid : SV_DispatchThreadID) { - float4 data = 0.0f.xxxx; + float4 testResult = 0.0f.xxxx; tid = inTid; uint id = WaveGetLaneIndex(); @@ -296,23 +296,23 @@ void main(uint3 inTid : SV_DispatchThreadID) { // SM6.5 functions : unit tests uint4 mask = WaveMatch(id); - data.x = countbits(mask.x) + countbits(mask.y) + countbits(mask.z) + countbits(mask.w); + testResult.x = countbits(mask.x) + countbits(mask.y) + countbits(mask.z) + countbits(mask.w); mask = WaveMatch(id%3 == 1); - data.y = countbits(mask.x) + countbits(mask.y) + countbits(mask.z) + countbits(mask.w); + testResult.y = countbits(mask.x) + countbits(mask.y) + countbits(mask.z) + countbits(mask.w); mask = WaveMatch(id%5 == 1); - data.z = WaveMultiPrefixSum(id, mask); - data.w = WaveMultiPrefixProduct(id, mask); + testResult.z = WaveMultiPrefixSum(id, mask); + testResult.w = WaveMultiPrefixProduct(id, mask); } if(IsTest(1)) { // SM6.5 functions : unit tests uint4 mask = WaveMatch(id%7 == 1); - data.x = WaveMultiPrefixCountBits(id, mask); - data.y = WaveMultiPrefixBitAnd((id+7)*3, mask); - data.z = WaveMultiPrefixBitOr(id, mask); - data.w = WaveMultiPrefixBitXor(id, mask); + testResult.x = WaveMultiPrefixCountBits(id, mask); + testResult.y = WaveMultiPrefixBitAnd((id+7)*3, mask); + testResult.z = WaveMultiPrefixBitOr(id, mask); + testResult.w = WaveMultiPrefixBitXor(id, mask); } - SetOutput(data); + SetOutput(testResult); } )EOSHADER"; diff --git a/util/test/demos/d3d12/d3d12_workgroup_zoo.cpp b/util/test/demos/d3d12/d3d12_workgroup_zoo.cpp index a18e75839..c72f1f942 100644 --- a/util/test/demos/d3d12/d3d12_workgroup_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_workgroup_zoo.cpp @@ -35,9 +35,12 @@ RD_TEST(D3D12_Workgroup_Zoo, D3D12GraphicsTest) cbuffer rootconsts : register(b0) { uint root_test; + uint root_two; } -#define IsTest(x) (root_test == x) +uint GetTest() { return root_test; } + +#define IsTest(x) (GetTest() == x) )EOSHADER"; @@ -46,17 +49,26 @@ cbuffer rootconsts : register(b0) RWStructuredBuffer outbuf : register(u0); static uint3 tid; +static uint flatId; groupshared uint4 gsmUint4[1024]; -void SetOutput(float4 data) +void SetOutput(float4 val) { - outbuf[root_test * 1024 + tid.y * GROUP_SIZE_X + tid.x] = data; + outbuf[root_test * 1024 + tid.y * GROUP_SIZE_X + tid.x] = val; +} + +void Init(float4 val) +{ + flatId = WaveGetLaneIndex(); + gsmUint4[flatId].xyz = tid; + gsmUint4[flatId].z = tid.x; + SetOutput(val); } )EOSHADER"; - const std::string comp = compCommon + R"EOSHADER( + const std::string testShader = compCommon + R"EOSHADER( float4 funcD(uint id) { @@ -130,19 +142,18 @@ float4 ComplexPartialReconvergence(uint id) void main(uint3 inTid : SV_DispatchThreadID) { tid = inTid; - float4 data = 0.0f.xxxx; - uint id = WaveGetLaneIndex(); - gsmUint4[id] = id.xxxx; - SetOutput(data); + float4 testResult = 0.0f.xxxx; + Init(testResult); + uint id = flatId; if(IsTest(0)) { - data.x = id; + testResult.x = id; AllMemoryBarrierWithGroupSync(); } else if(IsTest(1)) { - data.x = WaveActiveSum(id); + testResult.x = WaveActiveSum(id); AllMemoryBarrierWithGroupSync(); } else if(IsTest(2)) @@ -151,35 +162,35 @@ void main(uint3 inTid : SV_DispatchThreadID) if (id < 10) { // active threads 0-9 - data.x = WaveActiveSum(id); + testResult.x = WaveActiveSum(id); if ((id % 2) == 0) - data.y = WaveActiveSum(id); + testResult.y = WaveActiveSum(id); else - data.y = WaveActiveSum(id); + testResult.y = WaveActiveSum(id); - data.x += WaveActiveSum(id); + testResult.x += WaveActiveSum(id); } else { // active threads 10... - data.x = WaveActiveSum(id); + testResult.x = WaveActiveSum(id); } - data.y = WaveActiveSum(id); + testResult.y = WaveActiveSum(id); AllMemoryBarrierWithGroupSync(); } else if(IsTest(3)) { // Converged threads calling a function - data = funcTest(id); - data.y = WaveActiveSum(id); + testResult = funcTest(id); + testResult.y = WaveActiveSum(id); AllMemoryBarrierWithGroupSync(); } else if(IsTest(4)) { // Converged threads calling a function which has a nested function call in it - data = nestedFunc(id); - data.y = WaveActiveSum(id); + testResult = nestedFunc(id); + testResult.y = WaveActiveSum(id); AllMemoryBarrierWithGroupSync(); } else if(IsTest(5)) @@ -187,13 +198,13 @@ void main(uint3 inTid : SV_DispatchThreadID) // Diverged threads calling the same function if (id < 10) { - data = funcD(id); + testResult = funcD(id); } else { - data = funcD(id); + testResult = funcD(id); } - data.y = WaveActiveSum(id); + testResult.y = WaveActiveSum(id); AllMemoryBarrierWithGroupSync(); } else if(IsTest(6)) @@ -201,13 +212,13 @@ void main(uint3 inTid : SV_DispatchThreadID) // Diverged threads calling the same function which has a nested function call in it if (id < 10) { - data = funcA(id); + testResult = funcA(id); } else { - data = funcB(id); + testResult = funcB(id); } - data.y = WaveActiveSum(id); + testResult.y = WaveActiveSum(id); AllMemoryBarrierWithGroupSync(); } else if(IsTest(7)) @@ -215,37 +226,99 @@ void main(uint3 inTid : SV_DispatchThreadID) // Diverged threads which early exit if (id < 10) { - data.x = WaveActiveSum(id+10); - SetOutput(data); + testResult.x = WaveActiveSum(id+10); + SetOutput(testResult); return; } - data.x = WaveActiveSum(id); + testResult.x = WaveActiveSum(id); } else if(IsTest(8)) { // Loops with different number of iterations per thread for (uint i = 0; i < id; i++) { - data.x += WaveActiveSum(id); + testResult.x += WaveActiveSum(id); } AllMemoryBarrierWithGroupSync(); } else if(IsTest(9)) { // Query functions : unit tests - data.x = float(WaveGetLaneCount()); - data.y = float(WaveGetLaneIndex()); - data.z = float(WaveIsFirstLane()); + testResult.x = float(WaveGetLaneCount()); + testResult.y = float(WaveGetLaneIndex()); + testResult.z = float(WaveIsFirstLane()); AllMemoryBarrierWithGroupSync(); } else if(IsTest(10)) { - data = ComplexPartialReconvergence(id); + testResult = ComplexPartialReconvergence(id); AllMemoryBarrierWithGroupSync(); } - SetOutput(data); + SetOutput(testResult); +} + +)EOSHADER"; + + const std::string perfShader = compCommon + R"EOSHADER( + +[numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, GROUP_SIZE_Z)] +void main(uint3 inTid : SV_DispatchThreadID) +{ + tid = inTid; + float4 testResult = 0.0f.xxxx; + Init(testResult); + uint id = flatId; + + // TEST CASES: + // 0: GPU math : loops 100 + // 1: CPU math : loops 100 + // 2: GPU math : loops 200 + // 3: CPU math : loops 200 + // 4: GPU math : loops 400 + // 5: CPU math : loops 400 + // 6: GPU math : loops 5000 + // 7: CPU math : loops 5000 + bool useCpu = GetTest() & 0x1; + + uint count = 0; + { + uint temp = GetTest() >> 1; + if(temp == 0) + count = 100U; + if(temp == 1) + count = 200U; + if(temp == 2) + count = 400U; + if(temp == 3) + count = 5000U; + } + + if(useCpu) + { + for (uint i = 0; i < count; ++i) + { + gsmUint4[id].x += i; + gsmUint4[id].y += i * i; + testResult.x = testResult.x * testResult.x; + testResult.x += dot(gsmUint4[id], gsmUint4[id]); + } + } + else + { + for (uint i = 0; i < count; ++i) + { + gsmUint4[id].x += i; + gsmUint4[id].y += i * i; + testResult.x = pow(testResult.x, float(root_two)); + testResult.x += dot(gsmUint4[id], gsmUint4[id]); + } + } + + AllMemoryBarrierWithGroupSync(); + + SetOutput(testResult); } )EOSHADER"; @@ -268,51 +341,49 @@ void main(uint3 inTid : SV_DispatchThreadID) if(!Init()) return 3; - ID3D12RootSignaturePtr sig = MakeSig({constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0, 1), + ID3D12RootSignaturePtr sig = MakeSig({constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0, 2), uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0)}); - const uint32_t imgDim = 128; - - ID3D12ResourcePtr fltTex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, imgDim, imgDim) - .RTV() - .InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET); - fltTex->SetName(L"fltTex"); - D3D12_CPU_DESCRIPTOR_HANDLE fltRTV = MakeRTV(fltTex).CreateCPU(0); - D3D12_GPU_DESCRIPTOR_HANDLE fltSRV = MakeSRV(fltTex).CreateGPU(8); - int32_t numCompTests = 0; - size_t pos = 0; while(pos != std::string::npos) { - pos = comp.find("IsTest(", pos); + pos = testShader.find("IsTest(", pos); if(pos == std::string::npos) break; pos += sizeof("IsTest(") - 1; - numCompTests = std::max(numCompTests, atoi(comp.c_str() + pos) + 1); + numCompTests = std::max(numCompTests, atoi(testShader.c_str() + pos) + 1); } - struct + const int32_t countPerfTests = 8; + + struct CompSize { - int x, y; - } compsize[] = { - {70, 1}, + int x, y, z; }; - std::string comppipe_name[ARRAY_COUNT(compsize)]; - ID3D12PipelineStatePtr comppipe[ARRAY_COUNT(compsize)]; + CompSize compsizes[] = { + {70, 1, 1}, + }; + std::string comppipe_name[ARRAY_COUNT(compsizes)]; + ID3D12PipelineStatePtr testPipes[ARRAY_COUNT(compsizes)]; + ID3D12PipelineStatePtr perfPipes[ARRAY_COUNT(compsizes)]; std::string defines; - for(int i = 0; i < ARRAY_COUNT(comppipe); i++) + for(int i = 0; i < ARRAY_COUNT(compsizes); i++) { std::string sizedefine; - sizedefine = fmt::format("#define GROUP_SIZE_X {}\n#define GROUP_SIZE_Y {}\n", compsize[i].x, - compsize[i].y); - comppipe_name[i] = fmt::format("{}x{}", compsize[i].x, compsize[i].y); + sizedefine = + fmt::format("#define GROUP_SIZE_X {}\n#define GROUP_SIZE_Y {}\n#define GROUP_SIZE_Z {}", + compsizes[i].x, compsizes[i].y, compsizes[i].z); + comppipe_name[i] = fmt::format("{}x{}x{}", compsizes[i].x, compsizes[i].y, compsizes[i].z); - comppipe[i] = - MakePSO().RootSig(sig).CS(Compile(defines + sizedefine + comp, "main", "cs_6_0")); - comppipe[i]->SetName(UTF82Wide(comppipe_name[i]).c_str()); + testPipes[i] = + MakePSO().RootSig(sig).CS(Compile(defines + sizedefine + testShader, "main", "cs_6_0")); + testPipes[i]->SetName(UTF82Wide(comppipe_name[i]).c_str()); + perfPipes[i] = + MakePSO().RootSig(sig).CS(Compile(defines + sizedefine + perfShader, "main", "cs_6_0")); + perfPipes[i]->SetName(UTF82Wide(comppipe_name[i]).c_str()); } ID3D12ResourcePtr bufOut = MakeBuffer().Size(sizeof(Vec4f) * 1024 * numCompTests).UAV(); @@ -337,7 +408,7 @@ void main(uint3 inTid : SV_DispatchThreadID) pushMarker(cmd, "Compute Tests"); - for(size_t p = 0; p < ARRAY_COUNT(comppipe); p++) + for(size_t p = 0; p < ARRAY_COUNT(testPipes); p++) { ResourceBarrier(cmd); @@ -347,7 +418,7 @@ void main(uint3 inTid : SV_DispatchThreadID) ResourceBarrier(cmd); pushMarker(cmd, comppipe_name[p]); - cmd->SetPipelineState(comppipe[p]); + cmd->SetPipelineState(testPipes[p]); cmd->SetComputeRootSignature(sig); cmd->SetComputeRootUnorderedAccessView(1, bufOut->GetGPUVirtualAddress()); @@ -362,6 +433,52 @@ void main(uint3 inTid : SV_DispatchThreadID) popMarker(cmd); + pushMarker(cmd, "Perf Tests"); + + for(size_t p = 0; p < ARRAY_COUNT(testPipes); p++) + { + ResourceBarrier(cmd); + + UINT zero[4] = {}; + cmd->ClearUnorderedAccessViewUint(uavgpu, uavcpu, bufOut, zero, 0, NULL); + + ResourceBarrier(cmd); + pushMarker(cmd, comppipe_name[p]); + + cmd->SetPipelineState(perfPipes[p]); + cmd->SetComputeRootSignature(sig); + cmd->SetComputeRootUnorderedAccessView(1, bufOut->GetGPUVirtualAddress()); + + for(int i = 0; i < countPerfTests; ++i) + { + bool useCpu = (i & 0x1); + int count = 0; + { + int temp = i >> 1; + if(temp == 0) + count = 100U; + if(temp == 1) + count = 200U; + if(temp == 2) + count = 400U; + if(temp == 3) + count = 5000U; + } + std::string perfTestName = + fmt::format("{} Iterations {} Math", count, useCpu ? "CPU" : "GPU"); + pushMarker(cmd, perfTestName); + int two = 2; + cmd->SetComputeRoot32BitConstant(0, i, 0); + cmd->SetComputeRoot32BitConstant(0, two, 1); + cmd->Dispatch(2, 1, 1); + popMarker(cmd); + } + + popMarker(cmd); + } + + popMarker(cmd); + FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET); cmd->Close(); diff --git a/util/test/demos/demos.vcxproj b/util/test/demos/demos.vcxproj index c605881a2..2be76bbe6 100644 --- a/util/test/demos/demos.vcxproj +++ b/util/test/demos/demos.vcxproj @@ -190,6 +190,7 @@ + diff --git a/util/test/demos/demos.vcxproj.filters b/util/test/demos/demos.vcxproj.filters index bdf21c654..3806e14da 100644 --- a/util/test/demos/demos.vcxproj.filters +++ b/util/test/demos/demos.vcxproj.filters @@ -727,6 +727,9 @@ D3D12\demos + + D3D11\demos + diff --git a/util/test/demos/vk/vk_subgroup_zoo.cpp b/util/test/demos/vk/vk_subgroup_zoo.cpp index 826154c9f..bf98c888d 100644 --- a/util/test/demos/vk/vk_subgroup_zoo.cpp +++ b/util/test/demos/vk/vk_subgroup_zoo.cpp @@ -151,39 +151,39 @@ layout(binding = 0, std430) buffer outbuftype { layout(local_size_x = GROUP_SIZE_X, local_size_y = GROUP_SIZE_Y, local_size_z = 1) in; -void SetOutput(vec4 data) +void SetOutput(vec4 val) { - outbuf.data[push.test].vals[gl_LocalInvocationID.y * GROUP_SIZE_X + gl_LocalInvocationID.x] = data; + outbuf.data[push.test].vals[gl_LocalInvocationID.y * GROUP_SIZE_X + gl_LocalInvocationID.x] = val; } void main() { - vec4 data = vec4(0); + vec4 testResult = vec4(0); uint id = gl_SubgroupInvocationID; - SetOutput(data); + SetOutput(testResult); if(IsTest(0)) { // Query functions : unit tests - data.x = float(gl_SubgroupSize); - data.y = float(gl_SubgroupInvocationID); - data.z = float(subgroupElect()); + testResult.x = float(gl_SubgroupSize); + testResult.y = float(gl_SubgroupInvocationID); + testResult.z = float(subgroupElect()); } else if(IsTest(1)) { // Vote functions : unit tests - data.x = float(subgroupAny(id*2 > id+10)); - data.y = float(subgroupAll(id < gl_SubgroupSize)); + testResult.x = float(subgroupAny(id*2 > id+10)); + testResult.y = float(subgroupAll(id < gl_SubgroupSize)); if (id > 10) { - data.z = float(subgroupAll(id > 10)); + testResult.z = float(subgroupAll(id > 10)); uvec4 ballot = subgroupBallot(id > 20); - data.w = bitCount(ballot.x) + bitCount(ballot.y) + bitCount(ballot.z) + bitCount(ballot.w); + testResult.w = bitCount(ballot.x) + bitCount(ballot.y) + bitCount(ballot.z) + bitCount(ballot.w); } else { - data.z = float(subgroupAll(id > 3)); + testResult.z = float(subgroupAll(id > 3)); uvec4 ballot = subgroupBallot(id > 4); - data.w = bitCount(ballot.x) + bitCount(ballot.y) + bitCount(ballot.z) + bitCount(ballot.w); + testResult.w = bitCount(ballot.x) + bitCount(ballot.y) + bitCount(ballot.z) + bitCount(ballot.w); } } else if(IsTest(2)) @@ -191,10 +191,10 @@ void main() // Broadcast functions : unit tests if (id >= 2 && id <= 20) { - data.x = subgroupBroadcastFirst(id); - data.y = subgroupBroadcast(id, 5); - data.z = subgroupShuffle(id, id); - data.w = subgroupShuffle(data.x, 2+id%3); + testResult.x = subgroupBroadcastFirst(id); + testResult.y = subgroupBroadcast(id, 5); + testResult.z = subgroupShuffle(id, id); + testResult.w = subgroupShuffle(testResult.x, 2+id%3); } } else if(IsTest(3)) @@ -203,20 +203,20 @@ void main() if (id >= 2 && id <= 20) { uvec4 bits = subgroupBallot(id > 4); - data.x = subgroupBallotExclusiveBitCount(bits); + testResult.x = subgroupBallotExclusiveBitCount(bits); bits = subgroupBallot(id > 10); - data.y = subgroupBallotExclusiveBitCount(bits); - data.z = subgroupExclusiveAdd(data.x); - data.w = subgroupExclusiveMul(1 + data.y); + testResult.y = subgroupBallotExclusiveBitCount(bits); + testResult.z = subgroupExclusiveAdd(testResult.x); + testResult.w = subgroupExclusiveMul(1 + testResult.y); } else { uvec4 bits = subgroupBallot(id > 23); - data.x = subgroupBallotExclusiveBitCount(bits); + testResult.x = subgroupBallotExclusiveBitCount(bits); bits = subgroupBallot(id < 1); - data.y = subgroupBallotExclusiveBitCount(bits); - data.z = subgroupExclusiveAdd(data.x); - data.w = subgroupExclusiveAdd(data.y); + testResult.y = subgroupBallotExclusiveBitCount(bits); + testResult.z = subgroupExclusiveAdd(testResult.x); + testResult.w = subgroupExclusiveAdd(testResult.y); } } else if(IsTest(4)) @@ -224,10 +224,10 @@ void main() // Reduction functions : unit tests if (id >= 2 && id <= 20) { - data.x = float(subgroupMax(id)); - data.y = float(subgroupMin(id)); - data.z = float(subgroupMul(id)); - data.w = float(subgroupAdd(id)); + testResult.x = float(subgroupMax(id)); + testResult.y = float(subgroupMin(id)); + testResult.z = float(subgroupMul(id)); + testResult.w = float(subgroupAdd(id)); } } else if(IsTest(5)) @@ -236,10 +236,10 @@ void main() if (id >= 2 && id <= 20) { uvec4 bits = subgroupBallot(id > 23); - data.x = float(subgroupBallotBitCount(bits)); - data.y = float(subgroupAnd(id)); - data.z = float(subgroupOr(id)); - data.w = float(subgroupXor(id)); + testResult.x = float(subgroupBallotBitCount(bits)); + testResult.y = float(subgroupAnd(id)); + testResult.z = float(subgroupOr(id)); + testResult.w = float(subgroupXor(id)); } } else if(IsTest(6)) @@ -247,13 +247,13 @@ void main() // Reduction functions : unit tests if (id > 13) { - data.x = float(subgroupAllEqual(id > 15)); - data.y = float(subgroupAllEqual(id < 23)); - data.z = float(subgroupAllEqual(id >= 25)); - data.w = float(subgroupAllEqual(id >= 28)); + testResult.x = float(subgroupAllEqual(id > 15)); + testResult.y = float(subgroupAllEqual(id < 23)); + testResult.z = float(subgroupAllEqual(id >= 25)); + testResult.w = float(subgroupAllEqual(id >= 28)); } } - SetOutput(data); + SetOutput(testResult); } )EOSHADER"; diff --git a/util/test/demos/vk/vk_workgroup_zoo.cpp b/util/test/demos/vk/vk_workgroup_zoo.cpp index 069d03c2d..17d21a7d6 100644 --- a/util/test/demos/vk/vk_workgroup_zoo.cpp +++ b/util/test/demos/vk/vk_workgroup_zoo.cpp @@ -61,13 +61,19 @@ RD_TEST(VK_Workgroup_Zoo, VulkanGraphicsTest) layout(push_constant) uniform PushData { uint test; + uint two; } push; -#define IsTest(x) (push.test == x) +uint GetTest() { return push.test; } + +#define IsTest(x) (GetTest() == x) )EOSHADER"; - const std::string comp = common + R"EOSHADER( + const std::string compCommon = common + R"EOSHADER( + +uvec3 tid; +uint flatId; shared uvec4 gsmUint4[1024]; @@ -80,7 +86,25 @@ layout(binding = 0, std430) buffer outbuftype { Output data[COMP_TESTS]; } outbuf; -layout(local_size_x = GROUP_SIZE_X, local_size_y = GROUP_SIZE_Y, local_size_z = 1) in; +layout(local_size_x = GROUP_SIZE_X, local_size_y = GROUP_SIZE_Y, local_size_z = GROUP_SIZE_Z) in; + +void SetOutput(vec4 val) +{ + outbuf.data[push.test].vals[gl_LocalInvocationID.y * GROUP_SIZE_X + gl_LocalInvocationID.x] = val; +} + +void Init(vec4 val) +{ + tid = gl_GlobalInvocationID; + flatId = gl_SubgroupInvocationID; + gsmUint4[flatId].xyz = tid; + gsmUint4[flatId].z = tid.x; + SetOutput(val); +} + +)EOSHADER"; + + const std::string testShader = compCommon + R"EOSHADER( vec4 funcD(uint id) { @@ -122,26 +146,20 @@ vec4 funcTest(uint id) } } -void SetOutput(vec4 data) -{ - outbuf.data[push.test].vals[gl_LocalInvocationID.y * GROUP_SIZE_X + gl_LocalInvocationID.x] = data; -} - void main() { - vec4 data = vec4(0); - uint id = gl_SubgroupInvocationID; - gsmUint4[id] = id.xxxx; - SetOutput(data); + vec4 testResult = vec4(0); + Init(testResult); + uint id = flatId; if(IsTest(0)) { - data.x = id; + testResult.x = id; barrier(); } else if(IsTest(1)) { - data.x = subgroupAdd(id); + testResult.x = subgroupAdd(id); barrier(); } else if(IsTest(2)) @@ -150,35 +168,35 @@ void main() if (id < 10) { // active threads 0-9 - data.x = subgroupAdd(id); + testResult.x = subgroupAdd(id); if ((id % 2) == 0) - data.y = subgroupAdd(id); + testResult.y = subgroupAdd(id); else - data.y = subgroupAdd(id); + testResult.y = subgroupAdd(id); - data.x += subgroupAdd(id); + testResult.x += subgroupAdd(id); } else { // active threads 10... - data.x = subgroupAdd(id); + testResult.x = subgroupAdd(id); } - data.y = subgroupAdd(id); + testResult.y = subgroupAdd(id); barrier(); } else if(IsTest(3)) { // Converged threads calling a function - data = funcTest(id); - data.y = subgroupAdd(id); + testResult = funcTest(id); + testResult.y = subgroupAdd(id); barrier(); } else if(IsTest(4)) { // Converged threads calling a function which has a nested function call in it - data = nestedFunc(id); - data.y = subgroupAdd(id); + testResult = nestedFunc(id); + testResult.y = subgroupAdd(id); barrier(); } else if(IsTest(5)) @@ -186,13 +204,13 @@ void main() // Diverged threads calling the same function if (id < 10) { - data = funcD(id); + testResult = funcD(id); } else { - data = funcD(id); + testResult = funcD(id); } - data.y = subgroupAdd(id); + testResult.y = subgroupAdd(id); barrier(); } else if(IsTest(6)) @@ -200,13 +218,13 @@ void main() // Diverged threads calling the same function which has a nested function call in it if (id < 10) { - data = funcA(id); + testResult = funcA(id); } else { - data = funcB(id); + testResult = funcB(id); } - data.y = subgroupAdd(id); + testResult.y = subgroupAdd(id); barrier(); } else if(IsTest(7)) @@ -214,32 +232,92 @@ void main() // Diverged threads which early exit if (id < 10) { - data.x = subgroupAdd(id+10); - SetOutput(data); + testResult.x = subgroupAdd(id+10); + SetOutput(testResult); return; } - data.x = subgroupAdd(id); + testResult.x = subgroupAdd(id); } else if(IsTest(8)) { // Loops with different number of iterations per thread for (uint i = 0; i < id; i++) { - data.x += subgroupAdd(id); + testResult.x += subgroupAdd(id); } barrier(); } else if(IsTest(9)) { // Query functions : unit tests - data.x = float(gl_SubgroupSize); - data.y = float(gl_SubgroupInvocationID); - data.z = float(subgroupElect()); + testResult.x = float(gl_SubgroupSize); + testResult.y = float(gl_SubgroupInvocationID); + testResult.z = float(subgroupElect()); barrier(); } - SetOutput(data); + SetOutput(testResult); +} + +)EOSHADER"; + + const std::string perfShader = compCommon + R"EOSHADER( + +void main() +{ + vec4 testResult = vec4(0); + Init(testResult); + uint id = flatId; + + // TEST CASES: + // 0: GPU math : loops 100 + // 1: CPU math : loops 100 + // 2: GPU math : loops 200 + // 3: CPU math : loops 200 + // 4: GPU math : loops 400 + // 5: CPU math : loops 400 + // 6: GPU math : loops 5000 + // 7: CPU math : loops 5000 + bool useCpu = ((GetTest() & 1) == 1) ? true : false; + + uint count = 0; + { + uint temp = GetTest() >> 1; + if(temp == 0) + count = 100U; + if(temp == 1) + count = 200U; + if(temp == 2) + count = 400U; + if(temp == 3) + count = 5000U; + } + + if(useCpu) + { + for (uint i = 0; i < count; ++i) + { + gsmUint4[id].x += i; + gsmUint4[id].y += i * i; + testResult.x = testResult.x * testResult.x; + testResult.x += dot(gsmUint4[id], gsmUint4[id]); + } + } + else + { + for (uint i = 0; i < count; ++i) + { + gsmUint4[id].x += i; + gsmUint4[id].y += i * i; + testResult.x = pow(testResult.x, float(push.two)); + testResult.x += dot(gsmUint4[id], gsmUint4[id]); + } + } + + barrier(); + + SetOutput(testResult); } )EOSHADER"; @@ -290,7 +368,7 @@ void main() })); VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo( - {setlayout}, {vkh::PushConstantRange(VK_SHADER_STAGE_ALL, 0, 4)})); + {setlayout}, {vkh::PushConstantRange(VK_SHADER_STAGE_ALL, 0, 8)})); std::map macros; @@ -299,13 +377,15 @@ void main() size_t pos = 0; while(pos != std::string::npos) { - pos = comp.find("IsTest(", pos); + pos = testShader.find("IsTest(", pos); if(pos == std::string::npos) break; pos += sizeof("IsTest(") - 1; - numCompTests = std::max(numCompTests, atoi(comp.c_str() + pos) + 1); + numCompTests = std::max(numCompTests, atoi(testShader.c_str() + pos) + 1); } + const int32_t countPerfTests = 8; + if(ops & VK_SUBGROUP_FEATURE_SHUFFLE_BIT) macros["FEAT_SHUFFLE"] = "1"; else @@ -332,19 +412,28 @@ void main() macros["FEAT_ROTATE_CLUSTERED"] = "0"; std::string comppipe_name[1]; - VkPipeline comppipe[1]; + VkPipeline compPipes[1]; uint32_t countPipes = 0; + VkPipeline perfPipes[1]; + uint32_t countPerfPipes = 0; macros["COMP_TESTS"] = fmt::format("{}", numCompTests); macros["GROUP_SIZE_X"] = "70"; macros["GROUP_SIZE_Y"] = "1"; - comppipe_name[countPipes] = "70x1"; - comppipe[countPipes] = createComputePipeline(vkh::ComputePipelineCreateInfo( - layout, CompileShaderModule(comp, ShaderLang::glsl, ShaderStage::comp, "main", macros, + macros["GROUP_SIZE_Z"] = "1"; + comppipe_name[countPipes] = "70x1x1"; + + compPipes[countPipes] = createComputePipeline(vkh::ComputePipelineCreateInfo( + layout, CompileShaderModule(testShader, ShaderLang::glsl, ShaderStage::comp, "main", macros, SPIRVTarget::vulkan11))); ++countPipes; + perfPipes[0] = createComputePipeline(vkh::ComputePipelineCreateInfo( + layout, CompileShaderModule(perfShader, ShaderLang::glsl, ShaderStage::comp, "main", macros, + SPIRVTarget::vulkan11))); + ++countPerfPipes; + AllocatedBuffer bufout( this, vkh::BufferCreateInfo(sizeof(Vec4f) * 1024 * numCompTests, @@ -388,7 +477,7 @@ void main() pushMarker(cmd, comppipe_name[p]); - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, comppipe[p]); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, compPipes[p]); vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, {set}, {}); for(int i = 0; i < numCompTests; i++) @@ -402,6 +491,55 @@ void main() popMarker(cmd); + pushMarker(cmd, "Perf Tests"); + + for(size_t p = 0; p < countPerfPipes; p++) + { + vkh::cmdPipelineBarrier( + cmd, {}, + {vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + bufout.buffer, 0, sizeof(Vec4f) * 1024 * numCompTests)}); + + vkCmdFillBuffer(cmd, bufout.buffer, 0, sizeof(Vec4f) * 1024 * numCompTests, 0); + + vkh::cmdPipelineBarrier( + cmd, {}, + {vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, + bufout.buffer, 0, sizeof(Vec4f) * 1024 * numCompTests)}); + + pushMarker(cmd, comppipe_name[p]); + + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, perfPipes[p]); + vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, {set}, {}); + + for(int i = 0; i < countPerfTests; i++) + { + bool useCpu = (i & 0x1); + int count = 0; + { + int temp = i >> 1; + if(temp == 0) + count = 100U; + if(temp == 1) + count = 200U; + if(temp == 2) + count = 400U; + if(temp == 3) + count = 5000U; + } + std::string perfTestName = + fmt::format("{} Iterations {} Math", count, useCpu ? "CPU" : "GPU"); + pushMarker(cmd, perfTestName); + vkh::cmdPushConstants(cmd, layout, i); + vkCmdDispatch(cmd, 2, 1, 1); + popMarker(cmd); + } + + popMarker(cmd); + } + + popMarker(cmd); + FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL); vkEndCommandBuffer(cmd); diff --git a/util/test/rdtest/shared/Subgroup_Zoo.py b/util/test/rdtest/shared/Subgroup_Zoo.py index 99c9dcb83..6aed0a4c7 100644 --- a/util/test/rdtest/shared/Subgroup_Zoo.py +++ b/util/test/rdtest/shared/Subgroup_Zoo.py @@ -18,17 +18,20 @@ class Subgroup_Zoo(rdtest.TestCase): try: real = struct.unpack_from( "4f", bufdata, 16*y*dim[0] + 16*x) + except Exception as ex: + rdtest.log.error(f"Exception Test {test} failed {ex}") + return False - trace = self.controller.DebugThread( - self.workgroup, (x, y, z)) + try: + trace = self.controller.DebugThread(self.workgroup, (x, y, z)) _, variables = self.process_trace(trace) if trace.debugger is None: raise rdtest.TestFailureException(f"Test {test} at {action.eventId} got no debug result at {x},{y},{z}") - # Find the source variable 'data' at the highest instruction index - name = 'data' + # Find the source variable 'testResult' at the highest instruction index + name = 'testResult' debugged = None countInst = len(trace.instInfo) for inst in range(countInst): diff --git a/util/test/tests/D3D11/D3D11_Workgroup_Zoo.py b/util/test/tests/D3D11/D3D11_Workgroup_Zoo.py new file mode 100644 index 000000000..81dfe4338 --- /dev/null +++ b/util/test/tests/D3D11/D3D11_Workgroup_Zoo.py @@ -0,0 +1,5 @@ +import rdtest + +class D3D11_Workgroup_Zoo(rdtest.Workgroup_Zoo): + demos_test_name = 'D3D11_Workgroup_Zoo' + internal = False