diff --git a/renderdoc/core/resource_manager.cpp b/renderdoc/core/resource_manager.cpp index 6001d5ee2..f43e997c2 100644 --- a/renderdoc/core/resource_manager.cpp +++ b/renderdoc/core/resource_manager.cpp @@ -47,11 +47,11 @@ void SetReplayResourceIDs() } }; -void ResourceRecord::MarkResourceFrameReferenced(ResourceId id, FrameRefType refType) +bool ResourceRecord::MarkResourceFrameReferenced(ResourceId id, FrameRefType refType) { if(id == ResourceId()) - return; - ResourceManager::MarkReferenced(m_FrameRefs, id, refType); + return false; + return ResourceManager::MarkReferenced(m_FrameRefs, id, refType); } void ResourceRecord::AddResourceReferences(ResourceRecordHandler *mgr) diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index d871204d4..93ef26990 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -243,7 +243,7 @@ struct ResourceRecord bool HasDataPtr() { return DataPtr != NULL; } void SetDataOffset(uint64_t offs) { DataOffset = offs; } void SetDataPtr(byte *ptr) { DataPtr = ptr; } - void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType); + bool MarkResourceFrameReferenced(ResourceId id, FrameRefType refType); void AddResourceReferences(ResourceRecordHandler *mgr); void AddReferencedIDs(std::set &ids) { diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 6b74a7d1d..9a835b044 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -367,7 +367,19 @@ void WrappedID3D11DeviceContext::MarkResourceReferenced(ResourceId id, FrameRefT } else { - m_ContextRecord->MarkResourceFrameReferenced(id, refType); + bool newRef = m_ContextRecord->MarkResourceFrameReferenced(id, refType); + + // we need to keep this resource alive so that we can insert its record on capture + // if this command list gets executed. + if(newRef) + { + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(id); + if(record) + { + record->AddRef(); + m_DeferredReferences.insert(id); + } + } } } diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index d29f93676..38b8b44e1 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -170,6 +170,7 @@ private: }; set m_DeferredDirty; + set m_DeferredReferences; set m_HighTrafficResources; map m_OpenMaps; diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index c877978f5..732c78ca9 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -5163,6 +5163,7 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex RDCASSERT(r); m_ContextRecord->SwapChunks(r); + wrapped->SetReferences(m_DeferredReferences); wrapped->SetDirtyResources(m_DeferredDirty); // if we're supposed to restore, save the state to restore to now diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 7e44d2e29..3d0cdffba 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -1252,6 +1252,7 @@ class WrappedID3D11CommandList : public WrappedDeviceChild11 // list set m_Dirty; + set m_References; public: ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11CommandList); @@ -1264,12 +1265,22 @@ public: } virtual ~WrappedID3D11CommandList() { + D3D11ResourceManager *manager = m_pDevice->GetResourceManager(); + // release the references we were holding + for(ResourceId id : m_References) + { + D3D11ResourceRecord *record = manager->GetResourceRecord(id); + if(record) + record->Delete(manager); + } + // context isn't defined type at this point. Shutdown(); } WrappedID3D11DeviceContext *GetContext() { return m_pContext; } bool IsCaptured() { return m_Successful; } + void SetReferences(set &refs) { m_References.swap(refs); } void SetDirtyResources(set &dirty) { m_Dirty.swap(dirty); } void MarkDirtyResources(D3D11ResourceManager *manager) {