diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 4afeb18ad..64f22b4de 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -1822,6 +1822,9 @@ void WrappedID3D12Device::StartFrameCapture(void *dev, void *wnd) GetResourceManager()->MarkResourceFrameReferenced((*it)->GetCreationRecord()->GetResourceID(), eFrameRef_Read); } + + // also keep buffers alive + WrappedID3D12Resource1::AddRefBuffersBeforeCapture(GetResourceManager()); } GetResourceManager()->MarkResourceFrameReferenced(m_ResourceID, eFrameRef_Read); @@ -2134,6 +2137,8 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd) (*it)->Release(); } + WrappedID3D12Resource1::ReleaseBuffersAfterCapture(GetResourceManager()); + GetResourceManager()->MarkUnwrittenResources(); GetResourceManager()->ClearReferencedResources(); diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index ee8e39f0d..0a231eb96 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -463,6 +463,28 @@ void WrappedID3D12Resource1::RefBuffers(D3D12ResourceManager *rm) rm->MarkResourceFrameReferenced(m_Addresses.addresses[i].id, eFrameRef_Read); } +void WrappedID3D12Resource1::AddRefBuffersBeforeCapture(D3D12ResourceManager *rm) +{ + SCOPED_READLOCK(m_Addresses.addressLock); + for(size_t i = 0; i < m_Addresses.addresses.size(); i++) + rm->GetCurrentResource(m_Addresses.addresses[i].id)->AddRef(); +} + +void WrappedID3D12Resource1::ReleaseBuffersAfterCapture(D3D12ResourceManager *rm) +{ + // make a copy because we might release the last reference on a buffer which will need to modify + // the actual m_Addresses + rdcarray addresses; + + { + SCOPED_READLOCK(m_Addresses.addressLock); + addresses = m_Addresses.addresses; + } + + for(size_t i = 0; i < addresses.size(); i++) + rm->GetCurrentResource(addresses[i].id)->Release(); +} + WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *real, WrappedID3D12Device *device, const D3D12_DESCRIPTOR_HEAP_DESC &desc) diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 721bf8e07..43396b12e 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -879,6 +879,9 @@ public: static void RefBuffers(D3D12ResourceManager *rm); + static void AddRefBuffersBeforeCapture(D3D12ResourceManager *rm); + static void ReleaseBuffersAfterCapture(D3D12ResourceManager *rm); + static void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) { m_Addresses.GetResIDFromAddr(addr, id, offs); @@ -921,6 +924,12 @@ public: range.id = GetResourceID(); m_Addresses.AddTo(range); + + // while actively capturing we keep all buffers around to prevent the address lookup from + // losing addresses we might need (or the manageable but annoying problem of an address being + // re-used) + if(IsActiveCapturing(device->GetState())) + AddRef(); } } virtual ~WrappedID3D12Resource1();