From 3408c6f6b4cf61bbc7b28d178ef57466bac7489c Mon Sep 17 00:00:00 2001 From: Tanner Van De Walle Date: Sun, 7 Jun 2026 00:54:58 -0700 Subject: [PATCH] Fix dangling-pointer walk in ResidencySet during DiscardCommandList --- include/Residency.h | 16 +++++++++++++++- src/CommandListManager.cpp | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/Residency.h b/include/Residency.h index b0929ea..6daf6d8 100644 --- a/include/Residency.h +++ b/include/Residency.h @@ -116,7 +116,7 @@ namespace D3D12TranslationLayer }; // This represents a set of objects which are referenced by a command list i.e. every time a resource - // is bound for rendering, clearing, copy etc. the set must be updated to ensure the it is resident + // is bound for rendering, clearing, copy etc. the set must be updated to ensure the it is resident // for execution. class ResidencySet { @@ -155,6 +155,7 @@ namespace D3D12TranslationLayer Set.clear(); } + // Walks the set to clear CommandListsUsedOn for each object; callers must ensure the resources are still valid. void Close() { for (auto pObject : Set) @@ -166,6 +167,13 @@ namespace D3D12TranslationLayer } private: + // Used at teardown to clear the set without walking its resources; resources may already be destroyed at this time so we don't touch them. + void Discard() + { + Set.clear(); + CommandListIndex = InvalidIndex; + } + UINT32 CommandListIndex = InvalidIndex; std::vector Set; }; @@ -373,6 +381,12 @@ namespace D3D12TranslationLayer return PrepareToExecuteMasterSet(Queue, CommandListIndex, pMasterSet); } + // Teardown-only path: clear the set without walking its resources. + void DiscardResidencySet(ResidencySet* pSet) + { + pSet->Discard(); + } + private: HRESULT PrepareToExecuteMasterSet(ID3D12CommandQueue* Queue, UINT CommandListIndex, ResidencySet* pMasterSet) { diff --git a/src/CommandListManager.cpp b/src/CommandListManager.cpp index ee81fca..607936b 100644 --- a/src/CommandListManager.cpp +++ b/src/CommandListManager.cpp @@ -541,7 +541,7 @@ namespace D3D12TranslationLayer ResetCommandListTrackingData(); m_pCommandList = nullptr; - m_pResidencySet->Close(); + m_pParent->GetResidencyManager().DiscardResidencySet(m_pResidencySet.get()); } D3D12_COMMAND_LIST_TYPE CommandListManager::GetD3D12CommandListType(COMMAND_LIST_TYPE type)