diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index ca97547bf..3491a8872 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -267,6 +267,15 @@ class ResourceManager : public ResourceRecordHandler void Shutdown(); + struct InitialContentData + { + InitialContentData(ResourceType r, uint32_t n, byte *b) : resource(r), num(n), blob(b) {} + InitialContentData() : resource((ResourceType)RecordType::NullResource), num(0), blob(NULL) {} + ResourceType resource; + uint32_t num; + byte *blob; + }; + /////////////////////////////////////////// // Capture-side methods @@ -314,8 +323,8 @@ class ResourceManager : public ResourceRecordHandler // call callbacks to prepare initial contents for dirty resources void PrepareInitialContents(); - ResourceType GetInitialContents(ResourceId id); - void SetInitialContents(ResourceId id, ResourceType res, uint32_t data); + InitialContentData GetInitialContents(ResourceId id); + void SetInitialContents(ResourceId id, InitialContentData contents); // generate chunks for initial contents and insert. void InsertInitialContentsChunks(Serialiser *chunkSer, Serialiser *fileSer); @@ -378,7 +387,7 @@ class ResourceManager : public ResourceRecordHandler virtual bool Prepare_InitialState(ResourceType res) = 0; virtual bool Serialise_InitialState(ResourceType res) = 0; virtual void Create_InitialState(ResourceId id, ResourceType live, bool hasData) = 0; - virtual void Apply_InitialState(ResourceType live, ResourceType initial, uint32_t count) = 0; + virtual void Apply_InitialState(ResourceType live, InitialContentData initial) = 0; private: bool m_InFrame; @@ -403,8 +412,7 @@ class ResourceManager : public ResourceRecordHandler set m_PendingDirtyResources; // used during capture or replay - holds initial contents - map m_InitialContents; - map m_InitialCounts; + map m_InitialContents; // used during capture or replay - map of resources currently alive with their real IDs, used in capture and replay. map m_CurrentResourceMap; @@ -454,7 +462,8 @@ void ResourceManager::Shutdown() while(!m_InitialContents.empty()) { auto it = m_InitialContents.begin(); - ResourceTypeRelease(it->second); + ResourceTypeRelease(it->second.resource); + SAFE_DELETE_ARRAY(it->second.blob); if(!m_InitialContents.empty()) m_InitialContents.erase(m_InitialContents.begin()); } @@ -598,7 +607,7 @@ void ResourceManager::MarkCleanResource(ResourceId res } template -void ResourceManager::SetInitialContents(ResourceId id, ResourceType res, uint32_t data) +void ResourceManager::SetInitialContents(ResourceId id, InitialContentData contents) { SCOPED_LOCK(m_Lock); @@ -608,26 +617,26 @@ void ResourceManager::SetInitialContents(ResourceId id if(it != m_InitialContents.end()) { - ResourceTypeRelease(it->second); + ResourceTypeRelease(it->second.resource); + SAFE_DELETE_ARRAY(it->second.blob); m_InitialContents.erase(it); } - m_InitialContents[id] = res; - m_InitialCounts[id] = data; + m_InitialContents[id] = contents; } template -ResourceType ResourceManager::GetInitialContents(ResourceId id) +typename ResourceManager::InitialContentData ResourceManager::GetInitialContents(ResourceId id) { SCOPED_LOCK(m_Lock); if(id == ResourceId()) - return (ResourceType)RecordType::NullResource; + return InitialContentData(); if(m_InitialContents.find(id) != m_InitialContents.end()) return m_InitialContents[id]; - return (ResourceType)RecordType::NullResource; + return InitialContentData(); } template @@ -703,7 +712,8 @@ void ResourceManager::CreateInitialContents(Serialiser if(neededInitials.find(id) == neededInitials.end()) { - ResourceTypeRelease(it->second); + ResourceTypeRelease(it->second.resource); + SAFE_DELETE_ARRAY(it->second.blob); ++it; m_InitialContents.erase(id); } @@ -726,14 +736,10 @@ void ResourceManager::ApplyInitialContents() if(HasLiveResource(id)) { ResourceType live = GetLiveResource(id); - ResourceType initial = it->second; - uint32_t count = 0; - if(m_InitialCounts.find(id) != m_InitialCounts.end()) - count = m_InitialCounts[id]; numContents++; - Apply_InitialState(live, initial, count); + Apply_InitialState(live, it->second); } } RDCDEBUG("Applied %d", numContents); diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 085c46f20..b02c58368 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -1124,7 +1124,7 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven { ResourceId id = m_pDevice->GetResourceManager()->GetOriginalID(it->first); - if(m_pDevice->GetResourceManager()->GetInitialContents(id) == NULL) + if(m_pDevice->GetResourceManager()->GetInitialContents(id).resource == NULL) continue; RDCDEBUG("Resource %llu", id); diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index 3afc4b390..55edf0d01 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -6125,7 +6125,7 @@ bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT S { if(m_pDevice->GetResourceManager()->IsResourceDirty(Resource)) { - ID3D11DeviceChild *initial = m_pDevice->GetResourceManager()->GetInitialContents(Resource); + ID3D11DeviceChild *initial = m_pDevice->GetResourceManager()->GetInitialContents(Resource).resource; if(WrappedID3D11Buffer::IsAlloc(pResource)) { diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index a3a4f42df..361ff2c05 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -1038,7 +1038,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) { m_pImmediateContext->GetReal()->CopyStructureCount(stage, 0, UNWRAP(WrappedID3D11UnorderedAccessView, uav)); - m_ResourceManager->SetInitialContents(Id, stage, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); } } } @@ -1066,7 +1066,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) { m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Buffer, buf)); - m_ResourceManager->SetInitialContents(Id, stage, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); } } else if(type == Resource_Texture1D) @@ -1097,7 +1097,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) { m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture1D, tex1D)); - m_ResourceManager->SetInitialContents(Id, stage, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); } } else if(type == Resource_Texture2D) @@ -1173,7 +1173,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) SAFE_RELEASE(mutex); } - m_ResourceManager->SetInitialContents(Id, stage, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); } } else if(type == Resource_Texture3D) @@ -1204,7 +1204,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) { m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture3D, tex3D)); - m_ResourceManager->SetInitialContents(Id, stage, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); } } @@ -1280,7 +1280,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) { if(m_State >= WRITING) { - ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id); + ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); @@ -1304,7 +1304,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) { SERIALISE_ELEMENT(uint32_t, initCount, 0); - m_ResourceManager->SetInitialContents(Id, NULL, initCount); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(NULL, initCount, NULL)); } } else @@ -1325,7 +1325,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) desc.MiscFlags = 0; desc.StructureByteStride = 0; - ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id); + ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); @@ -1365,7 +1365,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) { if(m_State < WRITING) { - ID3D11Texture1D *contents = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id); + ID3D11Texture1D *contents = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; RDCASSERT(!contents); } @@ -1382,7 +1382,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; } - ID3D11Texture1D *stage = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id); + ID3D11Texture1D *stage = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; for(UINT sub = 0; sub < numSubresources; sub++) { @@ -1448,7 +1448,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) } else { - m_ResourceManager->SetInitialContents(Id, contents, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); } for(UINT sub = 0; sub < numSubresources; sub++) @@ -1500,7 +1500,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) { if(m_State < WRITING) { - ID3D11Texture2D *contents = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id); + ID3D11Texture2D *contents = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; RDCASSERT(!contents); } @@ -1517,7 +1517,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; } - ID3D11Texture2D *stage = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id); + ID3D11Texture2D *stage = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; for(UINT sub = 0; sub < numSubresources; sub++) { @@ -1634,7 +1634,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) contents = contentsMS; } - m_ResourceManager->SetInitialContents(Id, contents, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); } for(UINT sub = 0; sub < numSubresources; sub++) @@ -1661,7 +1661,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) { if(m_State < WRITING) { - ID3D11Texture3D *contents = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id); + ID3D11Texture3D *contents = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; RDCASSERT(!contents); } @@ -1678,7 +1678,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; } - ID3D11Texture3D *stage = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id); + ID3D11Texture3D *stage = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; for(UINT sub = 0; sub < numSubresources; sub++) { @@ -1760,7 +1760,7 @@ bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) } else { - m_ResourceManager->SetInitialContents(Id, contents, 0); + m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); } for(UINT sub = 0; sub < numSubresources; sub++) @@ -1848,7 +1848,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * m_pImmediateContext->GetReal()->Unmap(stage, 0); } - m_ResourceManager->SetInitialContents(id, NULL, countData); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(NULL, countData, NULL)); SAFE_RELEASE(stage); } @@ -1878,7 +1878,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * } else { - m_ResourceManager->SetInitialContents(id, initContents, 1); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearRTV, NULL)); } } else if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)) @@ -1899,7 +1899,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * } else { - m_ResourceManager->SetInitialContents(id, initContents, 2); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearDSV, NULL)); } } else if(desc.Usage != D3D11_USAGE_IMMUTABLE) @@ -1923,7 +1923,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * { m_pImmediateContext->GetReal()->CopyResource(initContents, UNWRAP(WrappedID3D11Texture1D, tex1D)); - m_ResourceManager->SetInitialContents(id, initContents, 0); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); } } } @@ -1955,7 +1955,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * } else { - m_ResourceManager->SetInitialContents(id, initContents, 1); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearRTV, NULL)); } } else if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)) @@ -1978,7 +1978,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * } else { - m_ResourceManager->SetInitialContents(id, initContents, 2); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearDSV, NULL)); } } else if(desc.Usage != D3D11_USAGE_IMMUTABLE) @@ -2002,7 +2002,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * { m_pImmediateContext->GetReal()->CopyResource(initContents, UNWRAP(WrappedID3D11Texture2D, tex2D)); - m_ResourceManager->SetInitialContents(id, initContents, 0); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); } } } @@ -2032,7 +2032,7 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * } else { - m_ResourceManager->SetInitialContents(id, initContents, 1); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearRTV, NULL)); } } else if(!hasData && desc.Usage != D3D11_USAGE_IMMUTABLE) @@ -2054,13 +2054,13 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * { m_pImmediateContext->GetReal()->CopyResource(initContents, UNWRAP(WrappedID3D11Texture3D, tex3D)); - m_ResourceManager->SetInitialContents(id, initContents, 0); + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); } } } } -void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, ID3D11DeviceChild *initial, uint32_t count) +void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial) { ResourceType type = IdentifyTypeByPtr(live); @@ -2068,25 +2068,29 @@ void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, ID3D11Devi { ID3D11UnorderedAccessView *uav = (ID3D11UnorderedAccessView *)live; - m_pImmediateContext->CSSetUnorderedAccessViews(0, 1, &uav, &count); + m_pImmediateContext->CSSetUnorderedAccessViews(0, 1, &uav, &initial.num); } else { - if(count == 1) + if(initial.num == eInitialContents_ClearRTV) { float emptyCol[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->GetReal()->ClearRenderTargetView((ID3D11RenderTargetView *)initial, emptyCol); + m_pImmediateContext->GetReal()->ClearRenderTargetView((ID3D11RenderTargetView *)initial.resource, emptyCol); } - else if(count == 2) + else if(initial.num == eInitialContents_ClearDSV) { - m_pImmediateContext->GetReal()->ClearDepthStencilView((ID3D11DepthStencilView *)initial, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); + m_pImmediateContext->GetReal()->ClearDepthStencilView((ID3D11DepthStencilView *)initial.resource, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); + } + else if(initial.num == eInitialContents_Copy) + { + ID3D11Resource *liveResource = (ID3D11Resource *)m_ResourceManager->UnwrapResource(live); + ID3D11Resource *initialResource = (ID3D11Resource *)initial.resource; + + m_pImmediateContext->GetReal()->CopyResource(liveResource, initialResource); } else { - ID3D11Resource *liveResource = (ID3D11Resource *)m_ResourceManager->UnwrapResource(live); - ID3D11Resource *initialResource = (ID3D11Resource *)initial; - - m_pImmediateContext->GetReal()->CopyResource(liveResource, initialResource); + RDCERR("Unexpected initial contents type"); } } } diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 03cf255d6..525ce0dce 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -140,6 +140,12 @@ private: // large-scale init until some point that we know we're the real device void LazyInit(); + enum { + eInitialContents_Copy = 0, + eInitialContents_ClearRTV = 1, + eInitialContents_ClearDSV = 2, + }; + D3D11Replay m_Replay; DummyID3D11InfoQueue m_DummyInfo; @@ -245,7 +251,7 @@ public: bool Prepare_InitialState(ID3D11DeviceChild *res); bool Serialise_InitialState(ID3D11DeviceChild *res); void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); - void Apply_InitialState(ID3D11DeviceChild *live, ID3D11DeviceChild *initial, uint32_t count); + void Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial); void ReadLogInitialisation(); void ProcessChunk(uint64_t offset, D3D11ChunkType context); diff --git a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp index 150638d6c..c74da92e1 100644 --- a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp @@ -123,7 +123,7 @@ bool WrappedID3D11Device::Serialise_CreateBuffer( } else { - m_ResourceManager->SetInitialContents(pBuffer, stage, 0); + m_ResourceManager->SetInitialContents(pBuffer, D3D11ResourceManager::InitialContentData(stage, eInitialContents_Copy, NULL)); } } @@ -2685,7 +2685,7 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource( } else { - m_ResourceManager->SetInitialContents(pResource, stage, 0); + m_ResourceManager->SetInitialContents(pResource, D3D11ResourceManager::InitialContentData(stage, eInitialContents_Copy, NULL)); } } diff --git a/renderdoc/driver/d3d11/d3d11_manager.cpp b/renderdoc/driver/d3d11/d3d11_manager.cpp index dbc3cde48..6ca57573d 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.cpp +++ b/renderdoc/driver/d3d11/d3d11_manager.cpp @@ -109,7 +109,7 @@ void D3D11ResourceManager::Create_InitialState(ResourceId id, ID3D11DeviceChild m_Device->Create_InitialState(id, live, hasData); } -void D3D11ResourceManager::Apply_InitialState(ID3D11DeviceChild *live, ID3D11DeviceChild *initial, uint32_t count) +void D3D11ResourceManager::Apply_InitialState(ID3D11DeviceChild *live, InitialContentData data) { - m_Device->Apply_InitialState(live, initial, count); + m_Device->Apply_InitialState(live, data); } diff --git a/renderdoc/driver/d3d11/d3d11_manager.h b/renderdoc/driver/d3d11/d3d11_manager.h index 45ae85213..6853a960a 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.h +++ b/renderdoc/driver/d3d11/d3d11_manager.h @@ -136,7 +136,7 @@ class D3D11ResourceManager : public ResourceManager bool Prepare_InitialState(GLResource res); bool Serialise_InitialState(GLResource res) { return true; } void Create_InitialState(ResourceId id, GLResource live, bool hasData) { } - void Apply_InitialState(GLResource live, GLResource initial, uint32_t count) { } + void Apply_InitialState(GLResource live, InitialContentData initial) { } map m_GLResourceRecords;