From fc956fee61f1e5f01fbf8c81311fdfdec6d461c0 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Fri, 9 May 2025 15:19:40 +0100 Subject: [PATCH] Improvements to *_Groupshared tests More checking of GSM local/global cache behaviour when debugging One test is not GPU stable and its results are verified against hard coded expectation (this is to test the expected behaviour of the local GSM cache on the active thread) --- util/test/demos/d3d11/d3d11_groupshared.cpp | 113 +++++++++++---- util/test/demos/d3d12/d3d12_groupshared.cpp | 144 +++++++++++++++----- util/test/demos/vk/vk_groupshared.cpp | 132 +++++++++++++----- util/test/rdtest/shared/Groupshared.py | 37 ++--- util/test/tests/D3D12/D3D12_Groupshared.py | 14 ++ 5 files changed, 331 insertions(+), 109 deletions(-) diff --git a/util/test/demos/d3d11/d3d11_groupshared.cpp b/util/test/demos/d3d11/d3d11_groupshared.cpp index 54a06dae9..01388647d 100644 --- a/util/test/demos/d3d11/d3d11_groupshared.cpp +++ b/util/test/demos/d3d11/d3d11_groupshared.cpp @@ -30,45 +30,93 @@ RD_TEST(D3D11_Groupshared, D3D11GraphicsTest) std::string comp = R"EOSHADER( +#define MAX_THREADS 64 + RWStructuredBuffer indata : register(u0); RWStructuredBuffer outdata : register(u1); -groupshared float tmp[64]; +groupshared float gsmData[MAX_THREADS]; -[numthreads(64,1,1)] -void main(uint3 tid : SV_GroupThreadID) +cbuffer consts : register(b0) { - if(tid.x == 0) + int inTest; +}; + +#define IsTest(x) (inTest == x) + +float GetGSMValue(uint i) +{ + return gsmData[i % MAX_THREADS]; +} + +[numthreads(MAX_THREADS,1,1)] +void main(uint3 gid : SV_GroupThreadID) +{ + if(gid.x == 0) { - for(int i=0; i < 64; i++) tmp[i] = 1.234f; + for(int i=0; i < MAX_THREADS; i++) gsmData[i] = 1.25f; } GroupMemoryBarrierWithGroupSync(); - float4 outval; + float4 outval = 0.0f.xxxx; - // first write, should be the init value for all threads - outval.x = tmp[tid.x]; + if (IsTest(0)) + { + // first write, should be the init value for all threads + outval.x = GetGSMValue(gid.x); - tmp[tid.x] = indata[tid.x]; + gsmData[gid.x] = indata[gid.x]; - // second write, should be the read value because we're reading our own value - outval.y = tmp[tid.x]; + // second write, should be the read value because we're reading our own value + outval.y = GetGSMValue(gid.x); - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); - // third write, should be our pairwise neighbour's value - outval.z = tmp[tid.x ^ 1]; + // third write, should be our pairwise neighbour's value + outval.z = GetGSMValue(gid.x ^ 1); - // do calculation with our neighbour - tmp[tid.x] = (1.0f + tmp[tid.x]) * (1.0f + tmp[tid.x ^ 1]); + // do calculation with our neighbour + gsmData[gid.x] = (1.0f + GetGSMValue(gid.x)) * (1.0f + GetGSMValue(gid.x ^ 1)); - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); - // fourth write, our neighbour should be identical to our value - outval.w = tmp[tid.x] == tmp[tid.x ^ 1] ? 9.99f : -9.99f; + // fourth write, our neighbour should be identical to our value + outval.w = GetGSMValue(gid.x) == GetGSMValue(gid.x ^ 1) ? 9.99f : -9.99f; + } + else if (IsTest(1)) + { + gsmData[gid.x] = (float)gid.x; + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); - outdata[tid.x] = outval; + outval.x = GetGSMValue(gid.x); + outval.y = GetGSMValue(gid.x + 1); + + GroupMemoryBarrierWithGroupSync(); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); + + outval.z = GetGSMValue(gid.x + 2); + + GroupMemoryBarrierWithGroupSync(); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); + + outval.w = GetGSMValue(gid.x + 3); + } + else if (IsTest(2)) + { + // Deliberately no sync to test debugger behaviour not GPU correctness + // Debugger should see the initial value of 1.25f for all of GSM + gsmData[gid.x] = (float)gid.x; + outval.x = GetGSMValue(gid.x); + outval.y = GetGSMValue(gid.x + 1); + outval.z = GetGSMValue(gid.x + 2); + outval.w = GetGSMValue(gid.x + 3); + } + + outdata[gid.x] = outval; } )EOSHADER"; @@ -90,18 +138,37 @@ void main(uint3 tid : SV_GroupThreadID) ID3D11ComputeShaderPtr shad = CreateCS(Compile(comp, "main", "cs_5_0", true)); + int cbufferdata[4]; + memset(cbufferdata, 0, sizeof(cbufferdata)); + ID3D11BufferPtr cb = MakeBuffer().Size(16).Constant().Data(&cbufferdata); + + int numCompTests = 0; + size_t pos = 0; + while(pos != std::string::npos) + { + pos = comp.find("IsTest(", pos); + if(pos == std::string::npos) + break; + pos += sizeof("IsTest(") - 1; + numCompTests = std::max(numCompTests, atoi(comp.c_str() + pos) + 1); + } + while(Running()) { ClearRenderTargetView(bbRTV, {0.2f, 0.2f, 0.2f, 1.0f}); - ClearUnorderedAccessView(outUAV, Vec4u()); - ctx->CSSetShader(shad, NULL, 0); ctx->CSSetUnorderedAccessViews(0, 1, &inUAV.GetInterfacePtr(), NULL); ctx->CSSetUnorderedAccessViews(1, 1, &outUAV.GetInterfacePtr(), NULL); pushMarker("Compute Tests"); - ctx->Dispatch(1, 1, 1); + for(int i = 0; i < numCompTests; ++i) + { + ClearUnorderedAccessView(outUAV, Vec4u()); + ctx->UpdateSubresource(cb, 0, NULL, &i, 4, 0); + ctx->CSSetConstantBuffers(0, 1, &cb.GetInterfacePtr()); + ctx->Dispatch(1, 1, 1); + } popMarker(); Present(); diff --git a/util/test/demos/d3d12/d3d12_groupshared.cpp b/util/test/demos/d3d12/d3d12_groupshared.cpp index 55c1c6e9c..fab1f8520 100644 --- a/util/test/demos/d3d12/d3d12_groupshared.cpp +++ b/util/test/demos/d3d12/d3d12_groupshared.cpp @@ -30,45 +30,93 @@ RD_TEST(D3D12_Groupshared, D3D12GraphicsTest) std::string comp = R"EOSHADER( +#define MAX_THREADS 64 + RWStructuredBuffer indata : register(u0); RWStructuredBuffer outdata : register(u1); -groupshared float tmp[64]; - -[numthreads(64,1,1)] -void main(uint3 tid : SV_GroupThreadID) +cbuffer rootconsts : register(b0) { - if(tid.x == 0) + uint root_test; +} + +groupshared float gsmData[MAX_THREADS]; + +#define IsTest(x) (root_test == x) + +float GetGSMValue(uint i) +{ + return gsmData[i % MAX_THREADS]; +} + +[numthreads(MAX_THREADS,1,1)] +void main(uint3 gid : SV_GroupThreadID) +{ + if(gid.x == 0) { - for(int i=0; i < 64; i++) tmp[i] = 1.234f; + for(int i=0; i < MAX_THREADS; i++) gsmData[i] = 1.25f; } GroupMemoryBarrierWithGroupSync(); - float4 outval; + float4 outval = 0.0f.xxxx; - // first write, should be the init value for all threads - outval.x = tmp[tid.x]; + if (IsTest(0)) + { + // first write, should be the init value for all threads + outval.x = GetGSMValue(gid.x); - tmp[tid.x] = indata[tid.x]; + gsmData[gid.x] = indata[gid.x]; - // second write, should be the read value because we're reading our own value - outval.y = tmp[tid.x]; + // second write, should be the read value because we're reading our own value + outval.y = GetGSMValue(gid.x); - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); - // third write, should be our pairwise neighbour's value - outval.z = tmp[tid.x ^ 1]; + // third write, should be our pairwise neighbour's value + outval.z = GetGSMValue(gid.x ^ 1); - // do calculation with our neighbour - tmp[tid.x] = (1.0f + tmp[tid.x]) * (1.0f + tmp[tid.x ^ 1]); + // do calculation with our neighbour + gsmData[gid.x] = (1.0f + GetGSMValue(gid.x)) * (1.0f + GetGSMValue(gid.x ^ 1)); - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); - // fourth write, our neighbour should be identical to our value - outval.w = tmp[tid.x] == tmp[tid.x ^ 1] ? 9.99f : -9.99f; + // fourth write, our neighbour should be identical to our value + outval.w = GetGSMValue(gid.x) == GetGSMValue(gid.x ^ 1) ? 9.99f : -9.99f; + } + else if (IsTest(1)) + { + gsmData[gid.x] = (float)gid.x; + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); - outdata[tid.x] = outval; + outval.x = GetGSMValue(gid.x); + outval.y = GetGSMValue(gid.x + 1); + + GroupMemoryBarrierWithGroupSync(); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); + + outval.z = GetGSMValue(gid.x + 2); + + GroupMemoryBarrierWithGroupSync(); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); + + outval.w = GetGSMValue(gid.x + 3); + } + else if (IsTest(2)) + { + // Deliberately no sync to test debugger behaviour not GPU correctness + // Debugger should see the initial value of 1.25f for all of GSM + gsmData[gid.x] = (float)gid.x; + outval.x = GetGSMValue(gid.x); + outval.y = GetGSMValue(gid.x + 1); + outval.z = GetGSMValue(gid.x + 2); + outval.w = GetGSMValue(gid.x + 3); + } + + outdata[gid.x] = outval; } )EOSHADER"; @@ -80,6 +128,7 @@ void main(uint3 tid : SV_GroupThreadID) return 3; ID3D12RootSignaturePtr rs = MakeSig({ + constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0, 1), uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0), uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 1), }); @@ -103,9 +152,20 @@ void main(uint3 tid : SV_GroupThreadID) ID3D12ResourcePtr outBuf = MakeBuffer().Size(sizeof(Vec4f) * 64 * 2).UAV(); D3D12_GPU_DESCRIPTOR_HANDLE outUAVGPU = - MakeUAV(outBuf).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateGPU(0); + MakeUAV(outBuf).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateGPU(10); D3D12_CPU_DESCRIPTOR_HANDLE outUAVClearCPU = - MakeUAV(outBuf).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateClearCPU(0); + MakeUAV(outBuf).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateClearCPU(10); + + int numCompTests = 0; + size_t pos = 0; + while(pos != std::string::npos) + { + pos = comp.find("IsTest(", pos); + if(pos == std::string::npos) + break; + pos += sizeof("IsTest(") - 1; + numCompTests = std::max(numCompTests, atoi(comp.c_str() + pos) + 1); + } while(Running()) { @@ -119,30 +179,42 @@ void main(uint3 tid : SV_GroupThreadID) UINT zero[4] = {}; D3D12_RECT rect = {0, 0, sizeof(Vec4f) * 64, 1}; - cmd->ClearUnorderedAccessViewUint(outUAVGPU, outUAVClearCPU, outBuf, zero, 1, &rect); - - ResourceBarrier(cmd); ClearRenderTargetView(cmd, BBRTV, {0.2f, 0.2f, 0.2f, 1.0f}); cmd->SetComputeRootSignature(rs); - cmd->SetComputeRootUnorderedAccessView(0, inBuf->GetGPUVirtualAddress()); - cmd->SetComputeRootUnorderedAccessView(1, outBuf->GetGPUVirtualAddress()); + cmd->SetComputeRootUnorderedAccessView(1, inBuf->GetGPUVirtualAddress()); + cmd->SetComputeRootUnorderedAccessView(2, outBuf->GetGPUVirtualAddress()); - pushMarker(cmd, "Compute Tests"); - setMarker(cmd, "SM5"); + pushMarker(cmd, "SM5"); cmd->SetPipelineState(pso50); - cmd->Dispatch(1, 1, 1); + + for(int i = 0; i < numCompTests; ++i) + { + ResourceBarrier(cmd); + cmd->ClearUnorderedAccessViewUint(outUAVGPU, outUAVClearCPU, outBuf, zero, 1, &rect); + ResourceBarrier(cmd); + cmd->SetComputeRoot32BitConstant(0, i, 0); + cmd->Dispatch(1, 1, 1); + } + + popMarker(cmd); if(pso60) { - setMarker(cmd, "SM6"); - cmd->SetComputeRootUnorderedAccessView(1, - outBuf->GetGPUVirtualAddress() + sizeof(Vec4f) * 64); + pushMarker(cmd, "SM6"); cmd->SetPipelineState(pso60); - cmd->Dispatch(1, 1, 1); + + for(int i = 0; i < numCompTests; ++i) + { + ResourceBarrier(cmd); + cmd->ClearUnorderedAccessViewUint(outUAVGPU, outUAVClearCPU, outBuf, zero, 1, &rect); + ResourceBarrier(cmd); + cmd->SetComputeRoot32BitConstant(0, i, 0); + cmd->Dispatch(1, 1, 1); + } + popMarker(cmd); } - popMarker(cmd); FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET); diff --git a/util/test/demos/vk/vk_groupshared.cpp b/util/test/demos/vk/vk_groupshared.cpp index f04cefdec..edf6df92d 100644 --- a/util/test/demos/vk/vk_groupshared.cpp +++ b/util/test/demos/vk/vk_groupshared.cpp @@ -31,57 +31,105 @@ RD_TEST(VK_Groupshared, VulkanGraphicsTest) std::string comp = R"EOSHADER( #version 460 core +#define MAX_THREADS 64 + +layout(push_constant) uniform PushData +{ + uint test; +} push; + layout(binding = 0, std430) buffer indataBuf { - float indata[64]; + float indata[MAX_THREADS]; }; layout(binding = 1, std430) buffer outdataBuf { - vec4 outdata[64]; + vec4 outdata[MAX_THREADS]; }; -shared float tmp[64]; +shared float gsmData[MAX_THREADS]; -layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; +#define IsTest(x) (push.test == x) + +float GetGSMValue(uint i) +{ + return gsmData[i % MAX_THREADS]; +} + +layout(local_size_x = MAX_THREADS, local_size_y = 1, local_size_z = 1) in; #define GroupMemoryBarrierWithGroupSync() memoryBarrierShared();groupMemoryBarrier();barrier(); void main() { - uvec3 tid = gl_LocalInvocationID; + uvec3 gid = gl_LocalInvocationID; if(gl_LocalInvocationID.x == 0) { - for(int i=0; i < 64; i++) tmp[i] = 1.234f; + for(int i=0; i < MAX_THREADS; i++) gsmData[i] = 1.25f; } GroupMemoryBarrierWithGroupSync(); - vec4 outval; + vec4 outval = vec4(0.0); - // first write, should be the init value for all threads - outval.x = tmp[tid.x]; + if (IsTest(0)) + { + // first write, should be the init value for all threads + outval.x = GetGSMValue(gid.x); - tmp[tid.x] = indata[tid.x]; + gsmData[gid.x] = indata[gid.x]; - // second write, should be the read value because we're reading our own value - outval.y = tmp[tid.x]; + // second write, should be the read value because we're reading our own value + outval.y = GetGSMValue(gid.x); - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); - // third write, should be our pairwise neighbour's value - outval.z = tmp[tid.x ^ 1]; + // third write, should be our pairwise neighbour's value + outval.z = GetGSMValue(gid.x ^ 1); - // do calculation with our neighbour - tmp[tid.x] = (1.0f + tmp[tid.x]) * (1.0f + tmp[tid.x ^ 1]); + // do calculation with our neighbour + gsmData[gid.x] = (1.0f + GetGSMValue(gid.x)) * (1.0f + GetGSMValue(gid.x ^ 1)); - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); - // fourth write, our neighbour should be identical to our value - outval.w = tmp[tid.x] == tmp[tid.x ^ 1] ? 9.99f : -9.99f; + // fourth write, our neighbour should be identical to our value + outval.w = GetGSMValue(gid.x) == GetGSMValue(gid.x ^ 1) ? 9.99f : -9.99f; + } + else if (IsTest(1)) + { + gsmData[gid.x] = float(gid.x); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); - outdata[tid.x] = outval; + outval.x = GetGSMValue(gid.x); + outval.y = GetGSMValue(gid.x + 1); + + GroupMemoryBarrierWithGroupSync(); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); + + outval.z = GetGSMValue(gid.x + 2); + + GroupMemoryBarrierWithGroupSync(); + gsmData[gid.x] += 10.0f; + GroupMemoryBarrierWithGroupSync(); + + outval.w = GetGSMValue(gid.x + 3); + } + else if (IsTest(2)) + { + // Deliberately no sync to test debugger behaviour not GPU correctness + // Debugger should see the initial value of 1.25f for all of GSM + gsmData[gid.x] = float(gid.x); + outval.x = GetGSMValue(gid.x); + outval.y = GetGSMValue(gid.x + 1); + outval.z = GetGSMValue(gid.x + 2); + outval.w = GetGSMValue(gid.x + 3); + } + + outdata[gid.x] = outval; } )EOSHADER"; @@ -96,7 +144,8 @@ void main() {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, })); - VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setLayout})); + VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo( + {setLayout}, {vkh::PushConstantRange(VK_SHADER_STAGE_ALL, 0, 4)})); VkPipeline pipe = createComputePipeline(vkh::ComputePipelineCreateInfo( layout, CompileShaderModule(comp, ShaderLang::glsl, ShaderStage::comp))); @@ -125,6 +174,17 @@ void main() {vkh::DescriptorBufferInfo(outBuf.buffer)}), }); + int numCompTests = 0; + size_t pos = 0; + while(pos != std::string::npos) + { + pos = comp.find("IsTest(", pos); + if(pos == std::string::npos) + break; + pos += sizeof("IsTest(") - 1; + numCompTests = std::max(numCompTests, atoi(comp.c_str() + pos) + 1); + } + while(Running()) { VkCommandBuffer cmd = GetCommandBuffer(); @@ -135,22 +195,26 @@ void main() vkh::cmdClearImage(cmd, swapimg, vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f)); - vkh::cmdPipelineBarrier( - cmd, {}, - {vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - outBuf.buffer)}); - - vkCmdFillBuffer(cmd, outBuf.buffer, 0, sizeof(Vec4f) * 64, 0); - - vkh::cmdPipelineBarrier(cmd, {}, - {vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, - VK_ACCESS_SHADER_WRITE_BIT, outBuf.buffer)}); - vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, {descSet}, {}); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipe); pushMarker(cmd, "Compute Tests"); - vkCmdDispatch(cmd, 1, 1, 1); + for(int i = 0; i < numCompTests; ++i) + { + vkh::cmdPipelineBarrier( + cmd, {}, + {vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + outBuf.buffer)}); + + vkCmdFillBuffer(cmd, outBuf.buffer, 0, sizeof(Vec4f) * 64, 0); + vkh::cmdPipelineBarrier( + cmd, {}, + {vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, + outBuf.buffer)}); + + vkh::cmdPushConstants(cmd, layout, i); + vkCmdDispatch(cmd, 1, 1, 1); + } popMarker(cmd); FinishUsingBackbuffer(cmd); diff --git a/util/test/rdtest/shared/Groupshared.py b/util/test/rdtest/shared/Groupshared.py index c461c36e7..999e7b33e 100644 --- a/util/test/rdtest/shared/Groupshared.py +++ b/util/test/rdtest/shared/Groupshared.py @@ -12,10 +12,8 @@ class Groupshared(rdtest.TestCase): return True, '' return False, 'Disabled test' - def check_compute_thread_result(self, test, action, x, y, z, dim, bufdata): + def check_compute_thread_result(self, test, action, x, y, z, expected): try: - real = struct.unpack_from("4f", bufdata, 16*x) - workgroup = (0, 0, 0) trace = self.controller.DebugThread(workgroup, (x, y, z)) @@ -45,12 +43,15 @@ class Groupshared(rdtest.TestCase): debuggedValue = list(debugged.value.f32v[0:4]) - if not rdtest.value_compare(real, debuggedValue, eps=5.0E-06): - raise rdtest.TestFailureException(f"EID:{action.eventId} TID:{x},{y},{z} debugged thread value {debuggedValue} does not match output {real}") + if not rdtest.value_compare(expected, debuggedValue, eps=5.0E-06): + raise rdtest.TestFailureException(f"EID:{action.eventId} TID:{x},{y},{z} debugged thread value {debuggedValue} does not match output {expected}") except rdtest.TestFailureException as ex: rdtest.log.error(f"Test {test} failed {ex}") return False + except Exception as ex: + rdtest.log.error(f"Test {test} exception {ex}") + return False finally: self.controller.FreeTrace(trace) @@ -72,7 +73,7 @@ class Groupshared(rdtest.TestCase): rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute) if len(rw) != 2: - rdtest.log.error("Unexpected number of RW resources") + rdtest.log.error(f"Unexpected number of RW resources {len(rw)}") return False outBuf = rw[1].descriptor.resource @@ -80,12 +81,17 @@ class Groupshared(rdtest.TestCase): maxThreads = 64 dataPerThread = 4 * 4 dataPerTest = dataPerThread * maxThreads - bufdata = self.controller.GetBufferData(outBuf, test*dataPerTest, dataPerTest) + bufdata = self.controller.GetBufferData(outBuf, 0, dataPerTest) for x in range(dim[0]): y = 0 z = 0 - if not self.check_compute_thread_result(test, action, x, y, z, dim, bufdata): + expected = struct.unpack_from("4f", bufdata, 16*x) + # Test 2 is a special case with hard coded results + if test == 2: + expected = [x, 1.25, 1.25, 1.25] + + if not self.check_compute_thread_result(test, action, x, y, z, expected): failed = True overallFailed |= failed @@ -97,18 +103,17 @@ class Groupshared(rdtest.TestCase): return overallFailed - def check_capture(self): - overallFailed = False - - action = self.find_action("Compute Tests") - sectionName = action.customName + def check_compute_section_tests(self, sectionAction): + sectionName = sectionAction.customName rdtest.log.begin_section(sectionName) - overallFailed |= self.check_compute_tests(action) + failed = self.check_compute_tests(sectionAction) rdtest.log.end_section(sectionName) - - if overallFailed: + if failed: raise rdtest.TestFailureException("Some tests were not as expected") + def check_capture(self): + action = self.find_action("Compute Tests") + self.check_compute_section_tests(action) self.check_renderdoc_log_asserts() rdtest.log.success("All tests matched") \ No newline at end of file diff --git a/util/test/tests/D3D12/D3D12_Groupshared.py b/util/test/tests/D3D12/D3D12_Groupshared.py index 7e0be49f1..14a8b6c51 100644 --- a/util/test/tests/D3D12/D3D12_Groupshared.py +++ b/util/test/tests/D3D12/D3D12_Groupshared.py @@ -3,3 +3,17 @@ import rdtest class D3D12_Groupshared(rdtest.Groupshared): internal = False demos_test_name = 'D3D12_Groupshared' + + def check_capture(self): + overallFailed = False + action = self.find_action("SM5") + self.check_compute_section_tests(action) + + action = self.find_action("SM6") + self.check_compute_section_tests(action) + if overallFailed: + raise rdtest.TestFailureException("Some tests were not as expected") + + self.check_renderdoc_log_asserts() + + rdtest.log.success("All tests matched") \ No newline at end of file