mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 21:10:42 +00:00
Hold references to used resources on deferred command lists
* We need to keep any resources used on deferred contexts alive until the produced command list is released. Otherwise the resource might be destroyed before we replay it, and we'll have lost that information.
This commit is contained in:
@@ -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<void *, void *, ResourceRecord>::MarkReferenced(m_FrameRefs, id, refType);
|
||||
return false;
|
||||
return ResourceManager<void *, void *, ResourceRecord>::MarkReferenced(m_FrameRefs, id, refType);
|
||||
}
|
||||
|
||||
void ResourceRecord::AddResourceReferences(ResourceRecordHandler *mgr)
|
||||
|
||||
@@ -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<ResourceId> &ids)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ private:
|
||||
};
|
||||
|
||||
set<ResourceId> m_DeferredDirty;
|
||||
set<ResourceId> m_DeferredReferences;
|
||||
|
||||
set<ResourceId> m_HighTrafficResources;
|
||||
map<MappedResource, MapIntercept> m_OpenMaps;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1252,6 +1252,7 @@ class WrappedID3D11CommandList : public WrappedDeviceChild11<ID3D11CommandList>
|
||||
// list
|
||||
|
||||
set<ResourceId> m_Dirty;
|
||||
set<ResourceId> 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<ResourceId> &refs) { m_References.swap(refs); }
|
||||
void SetDirtyResources(set<ResourceId> &dirty) { m_Dirty.swap(dirty); }
|
||||
void MarkDirtyResources(D3D11ResourceManager *manager)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user