From b27f5d5872ab335f33df6c176b39a167d1d6766d Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Sat, 15 Mar 2025 10:46:38 +0000 Subject: [PATCH] Extend D3D12_PrimitiveID test to SM6 To test the DXIL debugger --- util/test/demos/d3d12/d3d12_primitiveid.cpp | 56 ++++++++++++++++----- util/test/tests/D3D12/D3D12_PrimitiveID.py | 56 ++++++++++++++------- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/util/test/demos/d3d12/d3d12_primitiveid.cpp b/util/test/demos/d3d12/d3d12_primitiveid.cpp index 5de7f78db..6f2771610 100644 --- a/util/test/demos/d3d12/d3d12_primitiveid.cpp +++ b/util/test/demos/d3d12/d3d12_primitiveid.cpp @@ -137,20 +137,50 @@ float4 main(in prim2f IN) : SV_Target0 ID3D12ResourcePtr vb = MakeBuffer().Data(DefaultTri); ID3D12RootSignaturePtr sig = MakeSig({}); - ID3D12PipelineStatePtr pso[4] = { - MakePSO().RootSig(sig).InputLayout().VS(vsBlob).PS(psNoPrimBlob), - MakePSO().RootSig(sig).InputLayout().VS(vsBlob).PS(psPrimBlob), - MakePSO().RootSig(sig).InputLayout().VS(vsBlob).GS(gsNoPrimBlob).PS(psNoPrimBlob), - MakePSO().RootSig(sig).InputLayout().VS(vsBlob).GS(gsPrimBlob).PS(psPrimBlob)}; + + size_t countPSOs = 0; + ID3D12PipelineStatePtr psos[8]; + psos[countPSOs++] = MakePSO().RootSig(sig).InputLayout().VS(vsBlob).PS(psNoPrimBlob); + psos[countPSOs++] = MakePSO().RootSig(sig).InputLayout().VS(vsBlob).PS(psPrimBlob); + psos[countPSOs++] = + MakePSO().RootSig(sig).InputLayout().VS(vsBlob).GS(gsNoPrimBlob).PS(psNoPrimBlob); + psos[countPSOs++] = MakePSO().RootSig(sig).InputLayout().VS(vsBlob).GS(gsPrimBlob).PS(psPrimBlob); + size_t sm6start = countPSOs; + + if(m_DXILSupport) + { + ID3DBlobPtr vs6Blob = Compile(D3DDefaultVertex, "main", "vs_6_0"); + ID3DBlobPtr gs6NoPrimBlob = Compile(common + geomNoPrim, "main", "gs_6_0"); + ID3DBlobPtr gs6PrimBlob = Compile(common + geomPrim, "main", "gs_6_0"); + ID3DBlobPtr ps6NoPrimBlob = Compile(common + pixelNoPrim, "main", "ps_6_0"); + ID3DBlobPtr ps6PrimBlob = Compile(common + pixelPrim, "main", "ps_6_0"); + + psos[countPSOs++] = MakePSO().RootSig(sig).InputLayout().VS(vs6Blob).PS(ps6NoPrimBlob); + psos[countPSOs++] = MakePSO().RootSig(sig).InputLayout().VS(vs6Blob).PS(ps6PrimBlob); + psos[countPSOs++] = + MakePSO().RootSig(sig).InputLayout().VS(vs6Blob).GS(gs6NoPrimBlob).PS(ps6NoPrimBlob), + psos[countPSOs++] = + MakePSO().RootSig(sig).InputLayout().VS(vs6Blob).GS(gs6PrimBlob).PS(ps6PrimBlob); + } ResourceBarrier(vb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); float halfWidth = (float)screenWidth * 0.5f; float halfHeight = (float)screenHeight * 0.5f; - D3D12_VIEWPORT views[4] = {{0.0f, 0.0f, halfWidth, halfHeight, 0.0f, 1.0f}, - {halfWidth, 0.0f, halfWidth, halfHeight, 0.0f, 1.0f}, - {0.0f, halfHeight, halfWidth, halfHeight, 0.0f, 1.0f}, - {halfWidth, halfHeight, halfWidth, halfHeight, 0.0f, 1.0f}}; + float quarterHeight = halfHeight * 0.5f; + D3D12_VIEWPORT views[] = { + {0.0f, 0.0f, halfWidth, quarterHeight, 0.0f, 1.0f}, + {halfWidth, 0.0f, halfWidth, quarterHeight, 0.0f, 1.0f}, + {0.0f, quarterHeight, halfWidth, quarterHeight, 0.0f, 1.0f}, + {halfWidth, quarterHeight, halfWidth, quarterHeight, 0.0f, 1.0f}, + {0.0f, 0.0f + halfHeight, halfWidth, quarterHeight, 0.0f, 1.0f}, + {halfWidth, 0.0f + halfHeight, halfWidth, quarterHeight, 0.0f, 1.0f}, + {0.0f, quarterHeight + halfHeight, halfWidth, quarterHeight, 0.0f, 1.0f}, + {halfWidth, quarterHeight + halfHeight, halfWidth, quarterHeight, 0.0f, 1.0f}, + }; + + static_assert(ARRAYSIZE(psos) == ARRAYSIZE(views), "Mismatched array sizes"); + while(Running()) { ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer(); @@ -167,11 +197,13 @@ float4 main(in prim2f IN) : SV_Target0 ClearRenderTargetView(cmd, rtv, {0.2f, 0.2f, 0.2f, 1.0f}); RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight}); - cmd->SetMarker(1, "Test", (UINT)strlen("Test")); - for(int i = 0; i < 4; ++i) + setMarker(cmd, "SM5.0"); + for(int i = 0; i < countPSOs; ++i) { + if(i == sm6start) + setMarker(cmd, "SM6.0"); RSSetViewport(cmd, views[i]); - cmd->SetPipelineState(pso[i]); + cmd->SetPipelineState(psos[i]); cmd->DrawInstanced(3, 1, 0, 0); } diff --git a/util/test/tests/D3D12/D3D12_PrimitiveID.py b/util/test/tests/D3D12/D3D12_PrimitiveID.py index b8a521938..070ff22ac 100644 --- a/util/test/tests/D3D12/D3D12_PrimitiveID.py +++ b/util/test/tests/D3D12/D3D12_PrimitiveID.py @@ -31,7 +31,18 @@ class D3D12_PrimitiveID(rdtest.TestCase): else: # Look up the matching register in the inputs, and see if the expected value matches inputs: List[rd.ShaderVariable] = list(trace.inputs) - primValue = [var for var in inputs if var.name == primInput.variables[0].name][0] + primInputName = primInput.variables[0].name + if inputs[0].name.startswith('_IN') and primInputName.startswith('_IN.'): + # Walk the DXIL input structure + inputVars = inputs[0].members + # Remove the input name prefix + primInputName = primInputName[4:] + else: + inputVars = inputs + + primVars = [var for var in inputVars if var.name == primInputName] + + primValue = primVars[0] if primValue.value.u32v[0] not in expected_prim: rdtest.log.error("Expected prim {} at {},{} did not match actual prim {}.".format( str(expected_prim), x, y, primValue.value.u32v[0])) @@ -59,27 +70,36 @@ class D3D12_PrimitiveID(rdtest.TestCase): success = True - # Jump to the action - test_marker: rd.ActionDescription = self.find_action("Test") + markers = ["SM5.0", "SM6.0"] + for i in range(2): + rdtest.log.begin_section(markers[i]) + # Jump to the action + test_marker: rd.ActionDescription = self.find_action(markers[i]) + if test_marker is None: + rdtest.log.print(f"No {markers[i]} actions to test") + return - # Draw 1: No GS, PS without prim - action = test_marker.next - success &= self.test_action(action, 100, 80, rd.ReplayController.NoPreference, [0], [0, 1, 0, 1]) + y = 40 + i * 150 + # Draw 1: No GS, PS without prim + action = test_marker.next + success &= self.test_action(action, 100, y, rd.ReplayController.NoPreference, [0], [0, 1, 0, 1]) - # Draw 2: No GS, PS with prim - action = action.next - success &= self.test_action(action, 300, 80, rd.ReplayController.NoPreference, [0], [0, 1, 0, 1]) + # Draw 2: No GS, PS with prim + action = action.next + success &= self.test_action(action, 300, y, rd.ReplayController.NoPreference, [0], [0, 1, 0, 1]) - # Draw 3: GS, PS without prim - action = action.next - success &= self.test_action(action, 125, 250, rd.ReplayController.NoPreference, [0], [0, 1, 0, 1]) + # Draw 3: GS, PS without prim + y = 125 + i * 150 + action = action.next + success &= self.test_action(action, 125, y, rd.ReplayController.NoPreference, [0], [0, 1, 0, 1]) - # Draw 4: GS, PS with prim - action = action.next - success &= self.test_action(action, 325, 250, 2, [2], [0.5, 1, 0, 1]) - success &= self.test_action(action, 325, 250, 3, [3], [0.75, 1, 0, 1]) - # No expected output here, since it's nondeterministic which primitive gets selected - success &= self.test_action(action, 325, 250, rd.ReplayController.NoPreference, [2, 3], None) + # Draw 4: GS, PS with prim + action = action.next + success &= self.test_action(action, 325, y, 2, [2], [0.5, 1, 0, 1]) + success &= self.test_action(action, 325, y, 3, [3], [0.75, 1, 0, 1]) + # No expected output here, since it's nondeterministic which primitive gets selected + success &= self.test_action(action, 325, y, rd.ReplayController.NoPreference, [2, 3], None) + rdtest.log.end_section(markers[i]) if not success: raise rdtest.TestFailureException("Some tests were not as expected")