Fix query tracking to be per-cmdbuf on replay. Closes #3797

This commit is contained in:
baldurk
2026-02-12 17:56:39 +00:00
parent 5ce2e4ae6d
commit a4b8179794
5 changed files with 51 additions and 21 deletions
@@ -185,20 +185,6 @@ private:
// the list is reset, and each time the list is submitted the queue takes an additional reference
rdcarray<PatchedRayDispatch::Resources> m_RayDispatches;
struct OutstandingQuery
{
ID3D12QueryHeap *heap;
D3D12_QUERY_TYPE Type;
UINT Index;
bool operator==(const OutstandingQuery &q) const
{
return heap == q.heap && Type == q.Type && Index == q.Index;
}
};
rdcarray<OutstandingQuery> m_OutstandingQueries;
CaptureState &m_State;
WrappedID3D12DebugCommandList m_WrappedDebug;
@@ -67,15 +67,15 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Close(SerialiserType &ser)
ToStr(BakedCommandList).c_str());
#endif
int &markerCount = m_Cmd->m_BakedCmdListInfo[BakedCommandList].markerCount;
BakedCmdListInfo &bakedInfo = m_Cmd->m_BakedCmdListInfo[BakedCommandList];
for(int i = 0; i < markerCount; i++)
for(int i = 0; i < bakedInfo.markerCount; i++)
D3D12MarkerRegion::End(list);
for(OutstandingQuery &q : m_OutstandingQueries)
for(BakedCmdListInfo::OutstandingQuery &q : bakedInfo.m_OutstandingQueries)
Unwrap(list)->EndQuery(Unwrap(q.heap), q.Type, q.Index);
m_OutstandingQueries.clear();
bakedInfo.m_OutstandingQueries.clear();
if(m_Cmd->m_ActionCallback)
m_Cmd->m_ActionCallback->PreCloseCommandList(list);
@@ -2851,7 +2851,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BeginQuery(SerialiserType &ser,
Unwrap(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID))
->BeginQuery(Unwrap(pQueryHeap), Type, Index);
m_OutstandingQueries.push_back({pQueryHeap, Type, Index});
m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].m_OutstandingQueries.push_back(
{pQueryHeap, Type, Index});
}
}
}
@@ -2912,7 +2913,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_EndQuery(SerialiserType &ser,
Unwrap(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID))
->EndQuery(Unwrap(pQueryHeap), Type, Index);
m_OutstandingQueries.removeOne({pQueryHeap, Type, Index});
m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].m_OutstandingQueries.removeOne(
{pQueryHeap, Type, Index});
}
}
}
+14
View File
@@ -214,6 +214,20 @@ struct BakedCmdListInfo
rdcflatmap<uint32_t, PatchRaytracing> m_patchRaytracingInfo;
struct OutstandingQuery
{
ID3D12QueryHeap *heap;
D3D12_QUERY_TYPE Type;
UINT Index;
bool operator==(const OutstandingQuery &q) const
{
return heap == q.heap && Type == q.Type && Index == q.Index;
}
};
rdcarray<OutstandingQuery> m_OutstandingQueries;
ResourceId allocator;
D3D12_COMMAND_LIST_TYPE type;
UINT nodeMask;
+21 -1
View File
@@ -45,6 +45,14 @@ RD_TEST(D3D12_Predication, D3D12GraphicsTest)
ID3D12QueryHeapPtr qh;
dev->CreateQueryHeap(&desc, __uuidof(ID3D12QueryHeap), (void **)&qh);
desc.Count = 16;
ID3D12QueryHeapPtr qh2;
dev->CreateQueryHeap(&desc, __uuidof(ID3D12QueryHeap), (void **)&qh2);
ID3D12CommandAllocatorPtr alloc2;
CHECK_HR(dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
__uuidof(ID3D12CommandAllocator), (void **)&alloc2));
ID3D12ResourcePtr queryData = MakeBuffer().Size(sizeof(uint64_t) * (desc.Count + 1) * 3);
uint64_t val = 1;
@@ -98,6 +106,7 @@ RD_TEST(D3D12_Predication, D3D12GraphicsTest)
while(Running())
{
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
ID3D12GraphicsCommandListPtr cmd2 = GetCommandBuffer();
Reset(cmd);
@@ -177,9 +186,20 @@ RD_TEST(D3D12_Predication, D3D12GraphicsTest)
FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
// check for queries being "imbalanced" between command buffers
cmd2->Reset(alloc2, NULL);
cmd2->BeginQuery(qh2, D3D12_QUERY_TYPE_OCCLUSION, 0);
// this is fine, because the query is open on cmd2
cmd->Close();
Submit({cmd});
cmd2->EndQuery(qh2, D3D12_QUERY_TYPE_OCCLUSION, 0);
cmd2->Close();
Submit({cmd, cmd2});
Present();
}
@@ -54,3 +54,11 @@ class D3D12_Predication(rdtest.TestCase):
self.check(self.controller.GetD3D12PipelineState().predication.offset > 0)
rdtest.log.success("Failing predicated triangle is correct")
for eid in range(self.get_last_action().eventId):
self.controller.SetFrameEvent(eid, False)
if not self.controller.GetFatalErrorStatus().OK():
raise rdtest.TestFailureException(self.controller.GetFatalErrorStatus().Message())
rdtest.log.success("All events replay correctly")