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:
baldurk
2017-04-17 13:37:19 +01:00
parent d81f708f8c
commit faa1b6ced5
6 changed files with 30 additions and 5 deletions
+3 -3
View File
@@ -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)
+1 -1
View File
@@ -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)
{
+13 -1
View File
@@ -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);
}
}
}
}
+1
View File
@@ -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
+11
View File
@@ -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)
{