From 0ae245c4a8e87f3bc769b1b2813e0336b67eb90a Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 14 May 2019 13:45:07 +0100 Subject: [PATCH] Refactor initial state callbacks to always allow deleted resources * Instead of passing the resource handle itself to GetSize_InitialState or Serialise_InitialState, we pass the Id, ResourceRecord, and prepared initial contents. All of these can survive past the destruction of the resource. * Removes the need for AllowDeletedResource_InitialState() - it's always allowed now. * Need_InitialStateChunk is also refactored but it's only used on D3D11 currently and potentially will be removed in future. --- renderdoc/core/resource_manager.h | 47 ++-- renderdoc/driver/d3d11/d3d11_context.cpp | 1 + renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 1 + renderdoc/driver/d3d11/d3d11_device.cpp | 4 +- renderdoc/driver/d3d11/d3d11_device.h | 7 +- renderdoc/driver/d3d11/d3d11_device1_wrap.cpp | 2 + renderdoc/driver/d3d11/d3d11_device3_wrap.cpp | 5 + renderdoc/driver/d3d11/d3d11_device_wrap.cpp | 23 ++ renderdoc/driver/d3d11/d3d11_initstate.cpp | 206 +++++++----------- renderdoc/driver/d3d11/d3d11_manager.cpp | 16 +- renderdoc/driver/d3d11/d3d11_manager.h | 12 +- renderdoc/driver/d3d12/d3d12_device.cpp | 2 +- renderdoc/driver/d3d12/d3d12_initstate.cpp | 131 ++++++----- renderdoc/driver/d3d12/d3d12_manager.h | 39 +++- renderdoc/driver/d3d12/d3d12_serialise.cpp | 54 ++--- renderdoc/driver/d3d8/d3d8_manager.cpp | 13 +- renderdoc/driver/d3d8/d3d8_manager.h | 8 +- renderdoc/driver/gl/gl_driver.cpp | 3 +- renderdoc/driver/gl/gl_initstate.cpp | 158 +++++++------- renderdoc/driver/gl/gl_initstate.h | 2 + renderdoc/driver/gl/gl_manager.h | 13 +- renderdoc/driver/vulkan/vk_core.cpp | 2 +- renderdoc/driver/vulkan/vk_core.h | 17 +- renderdoc/driver/vulkan/vk_initstate.cpp | 86 +++----- renderdoc/driver/vulkan/vk_manager.cpp | 18 +- renderdoc/driver/vulkan/vk_manager.h | 9 +- .../driver/vulkan/vk_sparse_initstate.cpp | 44 ++-- 27 files changed, 453 insertions(+), 470 deletions(-) diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index f781e7423..6d7416485 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -569,14 +569,16 @@ protected: virtual bool ResourceTypeRelease(WrappedResourceType res) = 0; - virtual bool AllowDeletedResource_InitialState() { return false; } - virtual bool Need_InitialStateChunk(WrappedResourceType res) = 0; + virtual bool Need_InitialStateChunk(ResourceId id, const InitialContentData &initial) + { + return true; + } virtual bool Prepare_InitialState(WrappedResourceType res) = 0; - virtual uint64_t GetSize_InitialState(ResourceId id, WrappedResourceType res) = 0; - virtual bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, - WrappedResourceType res) = 0; + virtual uint64_t GetSize_InitialState(ResourceId id, const InitialContentData &initial) = 0; + virtual bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, RecordType *record, + const InitialContentData *initialData) = 0; virtual void Create_InitialState(ResourceId id, WrappedResourceType live, bool hasData) = 0; - virtual void Apply_InitialState(WrappedResourceType live, InitialContentData initial) = 0; + virtual void Apply_InitialState(WrappedResourceType live, const InitialContentData &initial) = 0; virtual std::vector InitialContentResources(); // very coarse lock, protects EVERYTHING. This could certainly be improved and it may be a @@ -1083,20 +1085,6 @@ void ResourceManager::InsertInitialContentsChunks(WriteSerialiser continue; } - WrappedResourceType res = (WrappedResourceType)RecordType::NullResource; - bool isAlive = HasCurrentResource(id); - - if(!AllowDeletedResource_InitialState() && !isAlive) - { -#if ENABLED(VERBOSE_DIRTY_RESOURCES) - RDCDEBUG("Resource %llu no longer exists - skipping", id); -#endif - continue; - } - - if(isAlive) - res = GetCurrentResource(id); - RecordType *record = GetResourceRecord(id); if(record == NULL) @@ -1121,7 +1109,7 @@ void ResourceManager::InsertInitialContentsChunks(WriteSerialiser dirty++; - if(!Need_InitialStateChunk(res)) + if(!Need_InitialStateChunk(id, it->second.data)) { // this was handled in ApplyInitialContentsNonChunks(), do nothing as there's no point copying // the data again (it's already been serialised). @@ -1134,11 +1122,11 @@ void ResourceManager::InsertInitialContentsChunks(WriteSerialiser } else { - uint64_t size = GetSize_InitialState(id, res); + uint64_t size = GetSize_InitialState(id, it->second.data); SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContents, size); - Serialise_InitialState(ser, id, res); + Serialise_InitialState(ser, id, record, &it->second.data); } } @@ -1160,22 +1148,13 @@ void ResourceManager::ApplyInitialContentsNonChunks(WriteSerialis continue; } - WrappedResourceType res = (WrappedResourceType)RecordType::NullResource; - bool isAlive = HasCurrentResource(id); - - if(!AllowDeletedResource_InitialState() && !isAlive) - continue; - - if(isAlive) - res = GetCurrentResource(id); - RecordType *record = GetResourceRecord(id); if(!record || record->InternalResource) continue; - if(!Need_InitialStateChunk(res)) - Serialise_InitialState(ser, id, res); + if(!Need_InitialStateChunk(id, it->second.data)) + Serialise_InitialState(ser, id, record, &it->second.data); } } diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index dda8d987d..7515df67a 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -147,6 +147,7 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real if(!RenderDoc::Inst().IsReplayApp()) { m_ContextRecord = m_pDevice->GetResourceManager()->AddResourceRecord(m_ResourceID); + m_ContextRecord->ResType = Resource_DeviceContext; m_ContextRecord->DataInSerialiser = false; m_ContextRecord->InternalResource = true; m_ContextRecord->Length = 0; diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index a2f342eee..102b3d68f 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -5400,6 +5400,7 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->ResType = Resource_CommandList; record->Length = 0; record->InternalResource = true; diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index fdf373ae3..35c61ffca 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -140,6 +140,7 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara if(!RenderDoc::Inst().IsReplayApp()) { m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_ResourceID); + m_DeviceRecord->ResType = Resource_Unknown; m_DeviceRecord->DataInSerialiser = false; m_DeviceRecord->InternalResource = true; m_DeviceRecord->Length = 0; @@ -999,7 +1000,7 @@ bool WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context) } else if(system == SystemChunk::InitialContents) { - return Serialise_InitialState(ser, ResourceId(), NULL); + return Serialise_InitialState(ser, ResourceId(), NULL, NULL); } else if(system == SystemChunk::CaptureScope) { @@ -1401,6 +1402,7 @@ IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap, if(IsCaptureMode(m_State)) { D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = Resource_Texture2D; record->DataInSerialiser = false; record->Length = 0; record->NumSubResources = 0; diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index dbb666989..781581054 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -494,12 +494,13 @@ public: // log replaying bool Prepare_InitialState(ID3D11DeviceChild *res); - uint64_t GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res); + uint64_t GetSize_InitialState(ResourceId id, const D3D11InitialContents &initial); template - bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, ID3D11DeviceChild *res); + bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, D3D11ResourceRecord *record, + const D3D11InitialContents *initial); void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); - void Apply_InitialState(ID3D11DeviceChild *live, D3D11InitialContents initial); + void Apply_InitialState(ID3D11DeviceChild *live, const D3D11InitialContents &initial); void SetStructuredExport(uint64_t sectionVersion) { diff --git a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp index 19e7bb824..061ecf500 100644 --- a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp @@ -163,6 +163,7 @@ HRESULT WrappedID3D11Device::CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendSt RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -271,6 +272,7 @@ HRESULT WrappedID3D11Device::CreateRasterizerState1(const D3D11_RASTERIZER_DESC1 RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); diff --git a/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp index c36d2c3f3..0ee07111a 100644 --- a/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp @@ -438,6 +438,7 @@ HRESULT WrappedID3D11Device::CreateShaderResourceView1(ID3D11Resource *pResource RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -583,6 +584,7 @@ HRESULT WrappedID3D11Device::CreateRenderTargetView1(ID3D11Resource *pResource, RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -698,6 +700,7 @@ HRESULT WrappedID3D11Device::CreateUnorderedAccessView1(ID3D11Resource *pResourc RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -816,6 +819,7 @@ HRESULT WrappedID3D11Device::CreateRasterizerState2(const D3D11_RASTERIZER_DESC2 RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -897,6 +901,7 @@ HRESULT WrappedID3D11Device::CreateQuery1(const D3D11_QUERY_DESC1 *pQueryDesc, I RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); diff --git a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp index 2750aefd0..936f32b67 100644 --- a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp @@ -83,6 +83,7 @@ bool WrappedID3D11Device::Serialise_CreateBuffer(SerialiserType &ser, const D3D1 RDCASSERT(GetResourceManager()->GetResourceRecord(pBuffer) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(pBuffer); + record->ResType = Resource_Buffer; record->SetDataOffset(offs); record->DataInSerialiser = true; record->Length = Descriptor.ByteWidth; @@ -281,6 +282,7 @@ std::vector WrappedID3D11Device::Serialise_CreateTexture RDCASSERT(record == NULL); record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(tex); record->Length = 1; if(HasData) @@ -291,6 +293,7 @@ std::vector WrappedID3D11Device::Serialise_CreateTexture for(UINT s = 0; s < numSubresources; s++) { record->SubResources[s] = new D3D11ResourceRecord(ResourceId()); + record->SubResources[s]->ResType = record->ResType; record->SubResources[s]->DataInSerialiser = HasData; } } @@ -879,6 +882,7 @@ HRESULT WrappedID3D11Device::CreateShaderResourceView(ID3D11Resource *pResource, RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -1011,6 +1015,7 @@ HRESULT WrappedID3D11Device::CreateUnorderedAccessView(ID3D11Resource *pResource RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -1151,6 +1156,7 @@ HRESULT WrappedID3D11Device::CreateRenderTargetView(ID3D11Resource *pResource, RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -1254,6 +1260,7 @@ HRESULT WrappedID3D11Device::CreateDepthStencilView(ID3D11Resource *pResource, RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddParent(parent); @@ -1364,6 +1371,7 @@ HRESULT WrappedID3D11Device::CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *p RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -1453,6 +1461,7 @@ HRESULT WrappedID3D11Device::CreateVertexShader(const void *pShaderBytecode, SIZ RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -1548,6 +1557,7 @@ HRESULT WrappedID3D11Device::CreateGeometryShader(const void *pShaderBytecode, S RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -1654,6 +1664,7 @@ HRESULT WrappedID3D11Device::CreateGeometryShaderWithStreamOutput( RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -1747,6 +1758,7 @@ HRESULT WrappedID3D11Device::CreatePixelShader(const void *pShaderBytecode, SIZE RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -1838,6 +1850,7 @@ HRESULT WrappedID3D11Device::CreateHullShader(const void *pShaderBytecode, SIZE_ RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -1933,6 +1946,7 @@ HRESULT WrappedID3D11Device::CreateDomainShader(const void *pShaderBytecode, SIZ RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2028,6 +2042,7 @@ HRESULT WrappedID3D11Device::CreateComputeShader(const void *pShaderBytecode, SI RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2348,6 +2363,7 @@ HRESULT WrappedID3D11Device::CreateBlendState(const D3D11_BLEND_DESC *pBlendStat RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2451,6 +2467,7 @@ HRESULT WrappedID3D11Device::CreateDepthStencilState(const D3D11_DEPTH_STENCIL_D RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2554,6 +2571,7 @@ HRESULT WrappedID3D11Device::CreateRasterizerState(const D3D11_RASTERIZER_DESC * RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2657,6 +2675,7 @@ HRESULT WrappedID3D11Device::CreateSamplerState(const D3D11_SAMPLER_DESC *pSampl RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2730,6 +2749,7 @@ HRESULT WrappedID3D11Device::CreateQuery(const D3D11_QUERY_DESC *pQueryDesc, ID3 RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2814,6 +2834,7 @@ HRESULT WrappedID3D11Device::CreatePredicate(const D3D11_QUERY_DESC *pPredicateD RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -2894,6 +2915,7 @@ HRESULT WrappedID3D11Device::CreateCounter(const D3D11_COUNTER_DESC *pCounterDes RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->ResType = IdentifyTypeByPtr(wrapped); record->Length = 0; record->AddChunk(scope.Get()); @@ -3023,6 +3045,7 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource(SerialiserType &ser, HAND RDCASSERT(GetResourceManager()->GetResourceRecord(pResource) == NULL); D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(pResource); + record->ResType = Type; record->SetDataOffset(offs); record->DataInSerialiser = true; record->Length = Descriptor.ByteWidth; diff --git a/renderdoc/driver/d3d11/d3d11_initstate.cpp b/renderdoc/driver/d3d11/d3d11_initstate.cpp index 170a4b562..67ec95047 100644 --- a/renderdoc/driver/d3d11/d3d11_initstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_initstate.cpp @@ -257,7 +257,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) return true; } -uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res) +uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, const D3D11InitialContents &initial) { // This function provides an upper bound on how much data Serialise_InitialState will write, so // that the chunk can be pre-allocated and not require seeking to fix-up the length. @@ -267,16 +267,14 @@ uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ResourcePitch pitch = {}; - D3D11ResourceType type = IdentifyTypeByPtr(res); - - if(type == Resource_UnorderedAccessView) + if(initial.resourceType == Resource_UnorderedAccessView) { // no data stored, just a counter. ret += 8; } - else if(type == Resource_Buffer) + else if(initial.resourceType == Resource_Buffer) { - WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)res; + WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)initial.resource; D3D11_BUFFER_DESC desc = {}; buf->GetDesc(&desc); @@ -285,9 +283,9 @@ uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ret += desc.ByteWidth; ret += WriteSerialiser::GetChunkAlignment(); } - else if(type == Resource_Texture1D) + else if(initial.resourceType == Resource_Texture1D) { - WrappedID3D11Texture1D *tex = (WrappedID3D11Texture1D *)res; + WrappedID3D11Texture1D *tex = (WrappedID3D11Texture1D *)initial.resource; D3D11_TEXTURE1D_DESC desc = {}; tex->GetDesc(&desc); @@ -307,9 +305,9 @@ uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ret += WriteSerialiser::GetChunkAlignment(); } } - else if(type == Resource_Texture2D) + else if(initial.resourceType == Resource_Texture2D) { - WrappedID3D11Texture2D1 *tex = (WrappedID3D11Texture2D1 *)res; + WrappedID3D11Texture2D1 *tex = (WrappedID3D11Texture2D1 *)initial.resource; D3D11_TEXTURE2D_DESC desc = {}; tex->GetDesc(&desc); @@ -325,8 +323,6 @@ uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ret += 4; // number of subresources ret += 4 * NumSubresources; // RowPitch for each subresource - ID3D11Resource *stage = (ID3D11Resource *)m_ResourceManager->GetInitialContents(id).resource; - // Subresource contents: for(UINT sub = 0; sub < NumSubresources; sub++) { @@ -338,19 +334,16 @@ uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh else if(IsYUVPlanarFormat(desc.Format)) numRows = GetYUVNumRows(desc.Format, numRows); - if(stage) - { - pitch = GetResourcePitchForSubresource(m_pImmediateContext->GetReal(), stage, sub); - ret += pitch.m_RowPitch * numRows; - } + pitch = GetResourcePitchForSubresource(m_pImmediateContext->GetReal(), tex, sub); + ret += pitch.m_RowPitch * numRows; ret += WriteSerialiser::GetChunkAlignment(); } } } - else if(type == Resource_Texture3D) + else if(initial.resourceType == Resource_Texture3D) { - WrappedID3D11Texture3D1 *tex = (WrappedID3D11Texture3D1 *)res; + WrappedID3D11Texture3D1 *tex = (WrappedID3D11Texture3D1 *)initial.resource; D3D11_TEXTURE3D_DESC desc = {}; tex->GetDesc(&desc); @@ -360,58 +353,51 @@ uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ret += 4; // number of subresources ret += 8 * NumSubresources; // RowPitch and DepthPitch for each subresource - ID3D11Resource *stage = (ID3D11Resource *)m_ResourceManager->GetInitialContents(id).resource; - // Subresource contents: for(UINT sub = 0; sub < NumSubresources; sub++) { UINT mip = GetMipForSubresource(tex, sub); - if(stage) - { - pitch = GetResourcePitchForSubresource(m_pImmediateContext->GetReal(), stage, sub); - ret += pitch.m_DepthPitch * RDCMAX(1U, desc.Depth >> mip); - } + pitch = GetResourcePitchForSubresource(m_pImmediateContext->GetReal(), tex, sub); + ret += pitch.m_DepthPitch * RDCMAX(1U, desc.Depth >> mip); ret += WriteSerialiser::GetChunkAlignment(); } } else { - RDCERR("Trying to serialise initial state of unsupported resource type %s", ToStr(type).c_str()); + RDCERR("Trying to serialise initial state of unsupported resource type %s", + ToStr(initial.resourceType).c_str()); } return ret; } template -bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId resid, - ID3D11DeviceChild *res) +bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId id, + D3D11ResourceRecord *record, + const D3D11InitialContents *initial) { D3D11ResourceType type = Resource_Unknown; - ResourceId Id = ResourceId(); - - bool ret = true; if(IsCaptureMode(m_State)) - { - type = IdentifyTypeByPtr(res); - Id = GetIDForResource(res); - } + type = record->ResType; + + bool ret = true; if(type != Resource_Buffer) { SERIALISE_ELEMENT(type); - SERIALISE_ELEMENT(Id).TypedAs("ID3D11DeviceChild *"); + SERIALISE_ELEMENT(id).TypedAs("ID3D11DeviceChild *"); } if(IsReplayingAndReading()) { - AddResourceCurChunk(Id); + AddResourceCurChunk(id); } { - RDCDEBUG("Serialise_InitialState(%llu)", Id); + RDCDEBUG("Serialise_InitialState(%llu)", id); if(type == Resource_Buffer) RDCDEBUG(" .. buffer"); @@ -434,37 +420,14 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId { uint32_t InitialHiddenCount = 0; - WrappedID3D11UnorderedAccessView1 *uav = (WrappedID3D11UnorderedAccessView1 *)res; - if(IsReplayMode(m_State)) + if(ser.IsWriting()) { - if(m_ResourceManager->HasLiveResource(Id)) - uav = (WrappedID3D11UnorderedAccessView1 *)m_ResourceManager->GetLiveResource(Id); - } + ID3D11Buffer *stage = initial ? (ID3D11Buffer *)initial->resource : NULL; - D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; - if(uav) - uav->GetDesc(&desc); - - bool bufferUAVWithCounter = - (desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && - (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER | D3D11_BUFFER_UAV_FLAG_APPEND)) != 0); - - if(bufferUAVWithCounter && ser.IsWriting()) - { - ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; - - if(stage != NULL) + if(stage) { D3D11_MAPPED_SUBRESOURCE mapped = {}; - HRESULT hr = E_INVALIDARG; - - if(stage) - hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); - else - RDCERR( - "Didn't have stage resource for %llu when serialising initial state! " - "Dirty tracking is incorrect", - Id); + HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); if(FAILED(hr)) { @@ -483,18 +446,15 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId SERIALISE_CHECK_READ_ERRORS(); - if(bufferUAVWithCounter && IsReplayingAndReading()) + if(IsReplayingAndReading()) { - m_ResourceManager->SetInitialContents(Id, D3D11InitialContents(type, InitialHiddenCount)); + m_ResourceManager->SetInitialContents(id, D3D11InitialContents(type, InitialHiddenCount)); } } else if(type == Resource_Buffer) { if(ser.IsWriting()) { - WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)res; - D3D11ResourceRecord *record = m_ResourceManager->GetResourceRecord(Id); - RDCASSERT(record); D3D11_BUFFER_DESC desc; @@ -503,7 +463,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId desc.MiscFlags = 0; desc.StructureByteStride = 0; - ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; + ID3D11Buffer *stage = initial ? (ID3D11Buffer *)initial->resource : NULL; D3D11_MAPPED_SUBRESOURCE mapped = {}; HRESULT hr = E_INVALIDARG; @@ -514,7 +474,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId RDCERR( "Didn't have stage resource for %llu when serialising initial state! " "Dirty tracking is incorrect", - Id); + id); if(FAILED(hr)) { @@ -526,7 +486,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId MapIntercept intercept; intercept.SetD3D(mapped); - intercept.Init(buf, record->GetDataPtr()); + intercept.Init(stage, record->GetDataPtr()); intercept.CopyFromD3D(); m_pImmediateContext->GetReal()->Unmap(stage, 0); @@ -535,21 +495,21 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId } else if(type == Resource_Texture1D) { - WrappedID3D11Texture1D *tex = (WrappedID3D11Texture1D *)res; - if(IsReplayingAndReading() && m_ResourceManager->HasLiveResource(Id)) - tex = (WrappedID3D11Texture1D *)m_ResourceManager->GetLiveResource(Id); + ID3D11Texture1D *prepared = initial ? (ID3D11Texture1D *)initial->resource : NULL; + + ID3D11Texture1D *tex = NULL; + D3D11_TEXTURE1D_DESC desc = {0}; - D3D11ResourceRecord *record = NULL; if(ser.IsWriting()) { - record = m_ResourceManager->GetResourceRecord(Id); - - RDCASSERT(record); - } - - D3D11_TEXTURE1D_DESC desc = {0}; - if(tex) + tex = prepared; tex->GetDesc(&desc); + } + else if(IsReplayingAndReading() && m_ResourceManager->HasLiveResource(id)) + { + tex = (WrappedID3D11Texture1D *)m_ResourceManager->GetLiveResource(id); + tex->GetDesc(&desc); + } uint32_t NumSubresources = desc.MipLevels * desc.ArraySize; SERIALISE_ELEMENT(NumSubresources); @@ -559,8 +519,6 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId if(IsReplayingAndReading() && tex) subData = new D3D11_SUBRESOURCE_DATA[NumSubresources]; - ID3D11Texture1D *prepared = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; - for(UINT sub = 0; sub < NumSubresources; sub++) { UINT mip = tex ? GetMipForSubresource(tex, sub) : 0; @@ -579,7 +537,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId RDCERR( "Didn't have stage resource for %llu when serialising initial state! " "Dirty tracking is incorrect", - Id); + id); if(FAILED(hr)) RDCERR("Failed to map in initial states %s", ToStr(hr).c_str()); @@ -636,7 +594,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId } else { - m_ResourceManager->SetInitialContents(Id, D3D11InitialContents(type, dataTex)); + m_ResourceManager->SetInitialContents(id, D3D11InitialContents(type, dataTex)); } // free the buffers we stole @@ -648,21 +606,21 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId } else if(type == Resource_Texture2D) { - WrappedID3D11Texture2D1 *tex = (WrappedID3D11Texture2D1 *)res; - if(IsReplayingAndReading() && m_ResourceManager->HasLiveResource(Id)) - tex = (WrappedID3D11Texture2D1 *)m_ResourceManager->GetLiveResource(Id); + ID3D11Texture2D *prepared = initial ? (ID3D11Texture2D *)initial->resource : NULL; + + ID3D11Texture2D *tex = NULL; + D3D11_TEXTURE2D_DESC desc = {0}; - D3D11ResourceRecord *record = NULL; if(ser.IsWriting()) { - record = m_ResourceManager->GetResourceRecord(Id); - - RDCASSERT(record); - } - - D3D11_TEXTURE2D_DESC desc = {0}; - if(tex) + tex = prepared; tex->GetDesc(&desc); + } + else if(IsReplayingAndReading() && m_ResourceManager->HasLiveResource(id)) + { + tex = (WrappedID3D11Texture2D1 *)m_ResourceManager->GetLiveResource(id); + tex->GetDesc(&desc); + } uint32_t NumSubresources = desc.MipLevels * desc.ArraySize; bool multisampled = desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0; @@ -703,9 +661,6 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId if(IsReplayingAndReading() && tex) subData = new D3D11_SUBRESOURCE_DATA[NumSubresources]; - ID3D11Texture2D *prepared = - (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; - for(UINT sub = 0; sub < NumSubresources; sub++) { UINT mip = tex ? GetMipForSubresource(tex, sub) : 0; @@ -731,7 +686,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId RDCERR( "Didn't have stage resource for %llu when serialising initial state! " "Dirty tracking is incorrect", - Id); + id); if(FAILED(hr)) { @@ -840,7 +795,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId dataTex = contentsMS; } - m_ResourceManager->SetInitialContents(Id, D3D11InitialContents(type, dataTex)); + m_ResourceManager->SetInitialContents(id, D3D11InitialContents(type, dataTex)); } // free the buffers we stole @@ -853,21 +808,21 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId } else if(type == Resource_Texture3D) { - WrappedID3D11Texture3D1 *tex = (WrappedID3D11Texture3D1 *)res; - if(IsReplayingAndReading() && m_ResourceManager->HasLiveResource(Id)) - tex = (WrappedID3D11Texture3D1 *)m_ResourceManager->GetLiveResource(Id); + ID3D11Texture3D *prepared = initial ? (ID3D11Texture3D *)initial->resource : NULL; + + ID3D11Texture3D *tex = NULL; + D3D11_TEXTURE3D_DESC desc = {0}; - D3D11ResourceRecord *record = NULL; if(ser.IsWriting()) { - record = m_ResourceManager->GetResourceRecord(Id); - - RDCASSERT(record); - } - - D3D11_TEXTURE3D_DESC desc = {0}; - if(tex) + tex = prepared; tex->GetDesc(&desc); + } + else if(IsReplayingAndReading() && m_ResourceManager->HasLiveResource(id)) + { + tex = (WrappedID3D11Texture3D1 *)m_ResourceManager->GetLiveResource(id); + tex->GetDesc(&desc); + } uint32_t NumSubresources = desc.MipLevels; SERIALISE_ELEMENT(NumSubresources); @@ -877,8 +832,6 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId if(IsReplayingAndReading() && tex) subData = new D3D11_SUBRESOURCE_DATA[NumSubresources]; - ID3D11Texture3D *prepared = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; - for(UINT sub = 0; sub < NumSubresources; sub++) { UINT mip = tex ? GetMipForSubresource(tex, sub) : 0; @@ -905,7 +858,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId RDCERR( "Didn't have stage resource for %llu when serialising initial state! " "Dirty tracking is incorrect", - Id); + id); if(FAILED(hr)) { @@ -974,7 +927,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId } else { - m_ResourceManager->SetInitialContents(Id, D3D11InitialContents(type, dataTex)); + m_ResourceManager->SetInitialContents(id, D3D11InitialContents(type, dataTex)); } // free the buffers we stole @@ -1321,7 +1274,8 @@ void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild * } } -void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, D3D11InitialContents initial) +void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, + const D3D11InitialContents &initial) { if(initial.resourceType == Resource_UnorderedAccessView) { @@ -1361,7 +1315,9 @@ void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, D3D11Initi } } -template bool WrappedID3D11Device::Serialise_InitialState(ReadSerialiser &ser, ResourceId resid, - ID3D11DeviceChild *res); -template bool WrappedID3D11Device::Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, - ID3D11DeviceChild *res); \ No newline at end of file +template bool WrappedID3D11Device::Serialise_InitialState(ReadSerialiser &ser, ResourceId id, + D3D11ResourceRecord *record, + const D3D11InitialContents *initial); +template bool WrappedID3D11Device::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, + D3D11ResourceRecord *record, + const D3D11InitialContents *initial); \ No newline at end of file diff --git a/renderdoc/driver/d3d11/d3d11_manager.cpp b/renderdoc/driver/d3d11/d3d11_manager.cpp index a9ef452c9..fad19c353 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.cpp +++ b/renderdoc/driver/d3d11/d3d11_manager.cpp @@ -72,9 +72,9 @@ bool D3D11ResourceManager::ResourceTypeRelease(ID3D11DeviceChild *res) return true; } -bool D3D11ResourceManager::Need_InitialStateChunk(ID3D11DeviceChild *res) +bool D3D11ResourceManager::Need_InitialStateChunk(ResourceId id, const InitialContentData &initial) { - return IdentifyTypeByPtr(res) != Resource_Buffer; + return initial.resourceType != Resource_Buffer; } bool D3D11ResourceManager::Prepare_InitialState(ID3D11DeviceChild *res) @@ -82,15 +82,16 @@ bool D3D11ResourceManager::Prepare_InitialState(ID3D11DeviceChild *res) return m_Device->Prepare_InitialState(res); } -uint64_t D3D11ResourceManager::GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res) +uint64_t D3D11ResourceManager::GetSize_InitialState(ResourceId id, const D3D11InitialContents &initial) { - return m_Device->GetSize_InitialState(id, res); + return m_Device->GetSize_InitialState(id, initial); } bool D3D11ResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, - ID3D11DeviceChild *res) + D3D11ResourceRecord *record, + const D3D11InitialContents *initial) { - return m_Device->Serialise_InitialState(ser, id, res); + return m_Device->Serialise_InitialState(ser, id, record, initial); } void D3D11ResourceManager::Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData) @@ -98,7 +99,8 @@ void D3D11ResourceManager::Create_InitialState(ResourceId id, ID3D11DeviceChild m_Device->Create_InitialState(id, live, hasData); } -void D3D11ResourceManager::Apply_InitialState(ID3D11DeviceChild *live, D3D11InitialContents data) +void D3D11ResourceManager::Apply_InitialState(ID3D11DeviceChild *live, + const D3D11InitialContents &data) { m_Device->Apply_InitialState(live, data); } diff --git a/renderdoc/driver/d3d11/d3d11_manager.h b/renderdoc/driver/d3d11/d3d11_manager.h index b0c2c8d98..1517301fc 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.h +++ b/renderdoc/driver/d3d11/d3d11_manager.h @@ -71,7 +71,7 @@ struct D3D11ResourceRecord : public ResourceRecord }; D3D11ResourceRecord(ResourceId id) - : ResourceRecord(id, true), NumSubResources(0), SubResources(NULL) + : ResourceRecord(id, true), ResType(Resource_Unknown), NumSubResources(0), SubResources(NULL) { RDCEraseEl(ImmediateShadow); } @@ -181,6 +181,7 @@ struct D3D11ResourceRecord : public ResourceRecord } } + D3D11ResourceType ResType; int NumSubResources; D3D11ResourceRecord **SubResources; @@ -304,12 +305,13 @@ private: bool ResourceTypeRelease(ID3D11DeviceChild *res); - bool Need_InitialStateChunk(ID3D11DeviceChild *res); + bool Need_InitialStateChunk(ResourceId id, const InitialContentData &initial); bool Prepare_InitialState(ID3D11DeviceChild *res); - uint64_t GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res); - bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, ID3D11DeviceChild *res); + uint64_t GetSize_InitialState(ResourceId id, const D3D11InitialContents &initial); + bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, D3D11ResourceRecord *record, + const D3D11InitialContents *initial); void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); - void Apply_InitialState(ID3D11DeviceChild *live, D3D11InitialContents data); + void Apply_InitialState(ID3D11DeviceChild *live, const D3D11InitialContents &data); WrappedID3D11Device *m_Device; }; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 3f0fde0ef..0173f6c25 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -2727,7 +2727,7 @@ bool WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context) } else if(system == SystemChunk::InitialContents) { - return GetResourceManager()->Serialise_InitialState(ser, ResourceId(), NULL); + return GetResourceManager()->Serialise_InitialState(ser, ResourceId(), NULL, NULL); } else if(system == SystemChunk::CaptureScope) { diff --git a/renderdoc/driver/d3d12/d3d12_initstate.cpp b/renderdoc/driver/d3d12/d3d12_initstate.cpp index e8043d6ec..26d0c2059 100644 --- a/renderdoc/driver/d3d12/d3d12_initstate.cpp +++ b/renderdoc/driver/d3d12/d3d12_initstate.cpp @@ -30,11 +30,6 @@ #include "d3d12_manager.h" #include "d3d12_resources.h" -bool D3D12ResourceManager::Need_InitialStateChunk(ID3D12DeviceChild *res) -{ - return true; -} - bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) { ResourceId id = GetResID(res); @@ -68,10 +63,31 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) D3D12_HEAP_PROPERTIES heapProps; r->GetHeapProperties(&heapProps, NULL); + HRESULT hr = S_OK; + if(heapProps.Type == D3D12_HEAP_TYPE_READBACK) { - // already on readback heap, just mark that we can map it directly and continue - SetInitialContents(GetResID(r), D3D12InitialContents(D3D12InitialContents::MapDirect)); + // readback resources can't be copied by the GPU but are always immediately CPU readable, so + // copy to a buffer now + size_t size = size_t(desc.Width); + byte *buffer = AllocAlignedBuffer(RDCMAX(desc.Width, 64ULL)); + + byte *bufData = NULL; + hr = r->GetReal()->Map(0, NULL, (void **)&bufData); + + if(SUCCEEDED(hr)) + { + memcpy(buffer, bufData, size); + + D3D12_RANGE range = {}; + r->GetReal()->Unmap(0, &range); + } + else + { + RDCERR("Couldn't map directly readback buffer: HRESULT: %s", ToStr(hr).c_str()); + } + + SetInitialContents(GetResID(r), D3D12InitialContents(buffer, size)); return true; } @@ -84,9 +100,9 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) desc.Flags = D3D12_RESOURCE_FLAG_NONE; ID3D12Resource *copyDst = NULL; - HRESULT hr = m_Device->GetReal()->CreateCommittedResource( - &heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_DEST, NULL, - __uuidof(ID3D12Resource), (void **)©Dst); + hr = m_Device->GetReal()->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_COPY_DEST, NULL, + __uuidof(ID3D12Resource), (void **)©Dst); if(nonresident) m_Device->MakeResident(1, &pageable); @@ -342,69 +358,55 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) return false; } -uint64_t D3D12ResourceManager::GetSize_InitialState(ResourceId id, ID3D12DeviceChild *res) +uint64_t D3D12ResourceManager::GetSize_InitialState(ResourceId id, const D3D12InitialContents &data) { - D3D12ResourceRecord *record = GetResourceRecord(id); - D3D12InitialContents initContents = GetInitialContents(id); - - if(record->type == Resource_DescriptorHeap) + if(data.resourceType == Resource_DescriptorHeap) { // the initial contents are just the descriptors. Estimate the serialise size here const uint64_t descriptorSerSize = 40 + sizeof(D3D12_SAMPLER_DESC); // add a little extra room for fixed overhead - return 64 + initContents.numDescriptors * descriptorSerSize; + return 64 + data.numDescriptors * descriptorSerSize; } - else if(record->type == Resource_Resource) + else if(data.resourceType == Resource_Resource) { - ID3D12Resource *buf = (ID3D12Resource *)initContents.resource; + ID3D12Resource *buf = (ID3D12Resource *)data.resource; - if(initContents.tag == D3D12InitialContents::MapDirect) - { - buf = (ID3D12Resource *)res; - } + // readback heaps have already been copied to a buffer, so use that length + if(data.tag == D3D12InitialContents::MapDirect) + return WriteSerialiser::GetChunkAlignment() + 16 + uint64_t(data.dataSize); return WriteSerialiser::GetChunkAlignment() + 16 + uint64_t(buf ? buf->GetDesc().Width : 0); } else { - RDCERR("Unexpected type needing an initial state serialised: %d", record->type); + RDCERR("Unexpected type needing an initial state serialised: %d", data.resourceType); } return 16; } template -bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId resid, - ID3D12DeviceChild *liveRes) +bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId id, + D3D12ResourceRecord *record, + const D3D12InitialContents *initial) { m_State = m_Device->GetState(); - D3D12ResourceRecord *record = NULL; - D3D12InitialContents initContents; - if(ser.IsWriting()) - { - record = GetResourceRecord(resid); - initContents = GetInitialContents(resid); - } - bool ret = true; - SERIALISE_ELEMENT_LOCAL(id, resid).TypedAs("ID3D12DeviceChild *"); + SERIALISE_ELEMENT(id).TypedAs("ID3D12DeviceChild *"); SERIALISE_ELEMENT_LOCAL(type, record->type); if(IsReplayingAndReading()) { - liveRes = GetLiveResource(id); - RDCASSERT(liveRes); - m_Device->AddResourceCurChunk(id); } if(type == Resource_DescriptorHeap) { - D3D12Descriptor *Descriptors = initContents.descriptors; - uint32_t numElems = initContents.numDescriptors; + D3D12Descriptor *Descriptors = initial ? initial->descriptors : NULL; + uint32_t numElems = initial ? initial->numDescriptors : 0; SERIALISE_ELEMENT_ARRAY(Descriptors, numElems); SERIALISE_ELEMENT(numElems); @@ -413,7 +415,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI if(IsReplayingAndReading()) { - WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)liveRes; + WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)GetLiveResource(id); D3D12_DESCRIPTOR_HEAP_DESC desc = heap->GetDesc(); @@ -460,19 +462,30 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI byte *dummy = NULL; ID3D12Resource *mappedBuffer = NULL; + ID3D12Resource *liveRes = NULL; + + if(IsReplayingAndReading()) + { + liveRes = (ID3D12Resource *)GetLiveResource(id); + } + if(ser.IsWriting()) { m_Device->ExecuteLists(NULL, true); m_Device->FlushLists(); - mappedBuffer = (ID3D12Resource *)initContents.resource; + RDCASSERT(initial); - if(initContents.tag == D3D12InitialContents::MapDirect) + mappedBuffer = (ID3D12Resource *)initial->resource; + + if(initial->tag == D3D12InitialContents::MapDirect) { - mappedBuffer = (ID3D12Resource *)liveRes; + // this was a readback heap, so we did the readback in Prepare already to a buffer + ResourceContents = initial->srcData; + ContentsLength = uint64_t(initial->dataSize); + mappedBuffer = NULL; } - - if(mappedBuffer) + else if(mappedBuffer) { HRESULT hr = mappedBuffer->Map(0, NULL, (void **)&ResourceContents); ContentsLength = mappedBuffer->GetDesc().Width; @@ -495,27 +508,25 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI // only map on replay if we haven't encountered any errors so far if(IsReplayingAndReading() && !ser.IsErrored()) { - D3D12_RESOURCE_DESC resDesc = ((ID3D12Resource *)liveRes)->GetDesc(); + D3D12_RESOURCE_DESC resDesc = liveRes->GetDesc(); D3D12_HEAP_PROPERTIES heapProps = {}; - ((ID3D12Resource *)liveRes)->GetHeapProperties(&heapProps, NULL); + liveRes->GetHeapProperties(&heapProps, NULL); if(heapProps.Type == D3D12_HEAP_TYPE_UPLOAD) { // if destination is on the upload heap, it's impossible to copy via the device, // so we have to CPU copy. To save time and make a more optimal copy, we just keep the data // CPU-side - initContents.tag = D3D12InitialContents::Copy; - mappedBuffer = NULL; + + D3D12InitialContents initContents(D3D12InitialContents::Copy); ResourceContents = initContents.srcData = AllocAlignedBuffer(RDCMAX(ContentsLength, 64ULL)); initContents.resourceType = Resource_Resource; SetInitialContents(id, initContents); } else { - initContents.tag = D3D12InitialContents::Copy; - // create an upload buffer to contain the contents heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; @@ -584,10 +595,11 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI if(IsReplayingAndReading() && mappedBuffer) { + D3D12InitialContents initContents(D3D12InitialContents::Copy); initContents.resourceType = Resource_Resource; initContents.resource = mappedBuffer; - D3D12_RESOURCE_DESC resDesc = ((ID3D12Resource *)liveRes)->GetDesc(); + D3D12_RESOURCE_DESC resDesc = liveRes->GetDesc(); // for MSAA textures we upload to an MSAA texture here so we're ready to copy the image in // Apply_InitState @@ -602,7 +614,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI else { D3D12_HEAP_PROPERTIES heapProps = {}; - ((ID3D12Resource *)liveRes)->GetHeapProperties(&heapProps, NULL); + liveRes->GetHeapProperties(&heapProps, NULL); ID3D12GraphicsCommandList *list = Unwrap(m_Device->GetInitialStateList()); @@ -740,10 +752,12 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI return ret; } -template bool D3D12ResourceManager::Serialise_InitialState(ReadSerialiser &ser, ResourceId resid, - ID3D12DeviceChild *liveRes); -template bool D3D12ResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, - ID3D12DeviceChild *liveRes); +template bool D3D12ResourceManager::Serialise_InitialState(ReadSerialiser &ser, ResourceId id, + D3D12ResourceRecord *record, + const D3D12InitialContents *initial); +template bool D3D12ResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, + D3D12ResourceRecord *record, + const D3D12InitialContents *initial); void D3D12ResourceManager::Create_InitialState(ResourceId id, ID3D12DeviceChild *live, bool hasData) { @@ -767,7 +781,8 @@ void D3D12ResourceManager::Create_InitialState(ResourceId id, ID3D12DeviceChild } } -void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12InitialContents data) +void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, + const D3D12InitialContents &data) { D3D12ResourceType type = (D3D12ResourceType)data.resourceType; diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 3c39e42ac..a15238799 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -615,7 +615,8 @@ struct D3D12InitialContents descriptors(d), numDescriptors(n), resource(NULL), - srcData(NULL) + srcData(NULL), + dataSize(0) { } D3D12InitialContents(ID3D12DescriptorHeap *r) @@ -624,7 +625,8 @@ struct D3D12InitialContents descriptors(NULL), numDescriptors(0), resource(r), - srcData(NULL) + srcData(NULL), + dataSize(0) { } D3D12InitialContents(ID3D12Resource *r) @@ -633,7 +635,18 @@ struct D3D12InitialContents descriptors(NULL), numDescriptors(0), resource(r), - srcData(NULL) + srcData(NULL), + dataSize(0) + { + } + D3D12InitialContents(byte *data, size_t size) + : tag(MapDirect), + resourceType(Resource_Resource), + descriptors(NULL), + numDescriptors(0), + resource(NULL), + srcData(data), + dataSize(size) { } D3D12InitialContents(Tag tg) @@ -642,7 +655,8 @@ struct D3D12InitialContents descriptors(NULL), numDescriptors(0), resource(NULL), - srcData(NULL) + srcData(NULL), + dataSize(0) { } D3D12InitialContents() @@ -651,7 +665,8 @@ struct D3D12InitialContents descriptors(NULL), numDescriptors(0), resource(NULL), - srcData(NULL) + srcData(NULL), + dataSize(0) { } template @@ -667,6 +682,7 @@ struct D3D12InitialContents uint32_t numDescriptors; ID3D12DeviceChild *resource; byte *srcData; + size_t dataSize; }; struct D3D12ResourceManagerConfiguration @@ -704,7 +720,8 @@ public: std::map &states); template - bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, ID3D12DeviceChild *res); + bool Serialise_InitialState(SerialiserType &ser, ResourceId id, D3D12ResourceRecord *record, + const D3D12InitialContents *initial); void SetInternalResource(ID3D12DeviceChild *res); @@ -713,15 +730,15 @@ private: bool ResourceTypeRelease(ID3D12DeviceChild *res); - bool Need_InitialStateChunk(ID3D12DeviceChild *res); bool Prepare_InitialState(ID3D12DeviceChild *res); - uint64_t GetSize_InitialState(ResourceId id, ID3D12DeviceChild *res); - bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, ID3D12DeviceChild *res) + uint64_t GetSize_InitialState(ResourceId id, const D3D12InitialContents &data); + bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, D3D12ResourceRecord *record, + const D3D12InitialContents *initial) { - return Serialise_InitialState(ser, resid, res); + return Serialise_InitialState(ser, id, record, initial); } void Create_InitialState(ResourceId id, ID3D12DeviceChild *live, bool hasData); - void Apply_InitialState(ID3D12DeviceChild *live, D3D12InitialContents data); + void Apply_InitialState(ID3D12DeviceChild *live, const D3D12InitialContents &data); CaptureState m_State; WrappedID3D12Device *m_Device; diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index f67c1983d..c7d9ad0f9 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -235,9 +235,6 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el) // also invisibly backwards compatible D3D12ResourceManager *rm = (D3D12ResourceManager *)ser.GetUserData(); - ID3D12Resource *resource = NULL; - ID3D12Resource *counterResource = NULL; - switch(type) { case D3D12DescriptorType::Sampler: @@ -253,13 +250,13 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el) } case D3D12DescriptorType::SRV: { - if(ser.IsWriting() && rm && rm->HasCurrentResource(el.data.nonsamp.resource)) - resource = rm->GetCurrentAs(el.data.nonsamp.resource); - - ser.Serialise("Resource", resource); + ser.Serialise("Resource", el.data.nonsamp.resource).TypedAs("ID3D12Resource *"); + // convert to Live ID on replay if(ser.IsReading()) - el.data.nonsamp.resource = GetResID(resource); + el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource) + ? rm->GetLiveID(el.data.nonsamp.resource) + : ResourceId(); // special case because of squeezed descriptor D3D12_SHADER_RESOURCE_VIEW_DESC desc; @@ -272,47 +269,44 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el) } case D3D12DescriptorType::RTV: { - if(ser.IsWriting() && rm && rm->HasCurrentResource(el.data.nonsamp.resource)) - resource = rm->GetCurrentAs(el.data.nonsamp.resource); - - ser.Serialise("Resource", resource); + ser.Serialise("Resource", el.data.nonsamp.resource).TypedAs("ID3D12Resource *"); + // convert to Live ID on replay if(ser.IsReading()) - el.data.nonsamp.resource = GetResID(resource); + el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource) + ? rm->GetLiveID(el.data.nonsamp.resource) + : ResourceId(); ser.Serialise("Descriptor", el.data.nonsamp.rtv); break; } case D3D12DescriptorType::DSV: { - if(ser.IsWriting() && rm && rm->HasCurrentResource(el.data.nonsamp.resource)) - resource = rm->GetCurrentAs(el.data.nonsamp.resource); - - ser.Serialise("Resource", resource); + ser.Serialise("Resource", el.data.nonsamp.resource).TypedAs("ID3D12Resource *"); + // convert to Live ID on replay if(ser.IsReading()) - el.data.nonsamp.resource = GetResID(resource); + el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource) + ? rm->GetLiveID(el.data.nonsamp.resource) + : ResourceId(); ser.Serialise("Descriptor", el.data.nonsamp.dsv); break; } case D3D12DescriptorType::UAV: { - if(ser.IsWriting()) - { - if(rm && rm->HasCurrentResource(el.data.nonsamp.resource)) - resource = rm->GetCurrentAs(el.data.nonsamp.resource); - if(rm && rm->HasCurrentResource(el.data.nonsamp.counterResource)) - counterResource = rm->GetCurrentAs(el.data.nonsamp.counterResource); - } - - ser.Serialise("Resource", resource); - ser.Serialise("CounterResource", counterResource); + ser.Serialise("Resource", el.data.nonsamp.resource).TypedAs("ID3D12Resource *"); + ser.Serialise("CounterResource", el.data.nonsamp.counterResource).TypedAs("ID3D12Resource *"); + // convert to Live ID on replay if(ser.IsReading()) { - el.data.nonsamp.resource = GetResID(resource); - el.data.nonsamp.counterResource = GetResID(counterResource); + el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource) + ? rm->GetLiveID(el.data.nonsamp.resource) + : ResourceId(); + el.data.nonsamp.counterResource = rm->HasLiveResource(el.data.nonsamp.counterResource) + ? rm->GetLiveID(el.data.nonsamp.counterResource) + : ResourceId(); } // special case because of squeezed descriptor diff --git a/renderdoc/driver/d3d8/d3d8_manager.cpp b/renderdoc/driver/d3d8/d3d8_manager.cpp index cfe552cc8..82929748f 100644 --- a/renderdoc/driver/d3d8/d3d8_manager.cpp +++ b/renderdoc/driver/d3d8/d3d8_manager.cpp @@ -45,24 +45,21 @@ bool D3D8ResourceManager::ResourceTypeRelease(IUnknown *res) return true; } -bool D3D8ResourceManager::Need_InitialStateChunk(IUnknown *res) -{ - return true; -} - bool D3D8ResourceManager::Prepare_InitialState(IUnknown *res) { // TODO return false; } -uint64_t D3D8ResourceManager::GetSize_InitialState(ResourceId id, IUnknown *res) +uint64_t D3D8ResourceManager::GetSize_InitialState(ResourceId id, const D3D8InitialContents &data) { // TODO return 128; } -bool D3D8ResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, IUnknown *res) +bool D3D8ResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, + D3D8ResourceRecord *record, + const D3D8InitialContents *data) { // TODO return false; @@ -72,7 +69,7 @@ void D3D8ResourceManager::Create_InitialState(ResourceId id, IUnknown *live, boo { } -void D3D8ResourceManager::Apply_InitialState(IUnknown *live, D3D8InitialContents data) +void D3D8ResourceManager::Apply_InitialState(IUnknown *live, const D3D8InitialContents &data) { // TODO } diff --git a/renderdoc/driver/d3d8/d3d8_manager.h b/renderdoc/driver/d3d8/d3d8_manager.h index a3932e0a4..7e1d7bebb 100644 --- a/renderdoc/driver/d3d8/d3d8_manager.h +++ b/renderdoc/driver/d3d8/d3d8_manager.h @@ -74,12 +74,12 @@ private: bool ResourceTypeRelease(IUnknown *res); - bool Need_InitialStateChunk(IUnknown *res); bool Prepare_InitialState(IUnknown *res); - uint64_t GetSize_InitialState(ResourceId id, IUnknown *res); - bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, IUnknown *res); + uint64_t GetSize_InitialState(ResourceId id, const D3D8InitialContents &data); + bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, D3D8ResourceRecord *record, + const D3D8InitialContents *data); void Create_InitialState(ResourceId id, IUnknown *live, bool hasData); - void Apply_InitialState(IUnknown *live, D3D8InitialContents data); + void Apply_InitialState(IUnknown *live, const D3D8InitialContents &data); WrappedD3DDevice8 *m_Device; }; diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 9684cc50c..86089957b 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -2888,8 +2888,7 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) } else if(system == SystemChunk::InitialContents) { - return GetResourceManager()->Serialise_InitialState(ser, ResourceId(), - GLResource(MakeNullResource)); + return GetResourceManager()->Serialise_InitialState(ser, ResourceId(), NULL, NULL); } else if(system == SystemChunk::CaptureScope) { diff --git a/renderdoc/driver/gl/gl_initstate.cpp b/renderdoc/driver/gl/gl_initstate.cpp index aa0529f00..7919dfea0 100644 --- a/renderdoc/driver/gl/gl_initstate.cpp +++ b/renderdoc/driver/gl/gl_initstate.cpp @@ -183,15 +183,12 @@ void WrappedOpenGL::TextureData::GetCompressedImageDataGLES(int mip, GLenum targ } } -bool GLResourceManager::Need_InitialStateChunk(GLResource res) -{ - return true; -} - void GLResourceManager::ContextPrepare_InitialState(GLResource res) { GLInitialContents initContents; + initContents.type = res.Namespace; + ResourceId id = GetID(res); if(res.Namespace == eResBuffer) @@ -697,6 +694,8 @@ void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, Resourc GLInitialContents initContents; + initContents.type = eResTexture; + TextureStateInitialData &state = initContents.tex; state.internalformat = details.internalFormat; @@ -1053,14 +1052,14 @@ void GLResourceManager::Force_ReferenceViews() } } -uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource res) +uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, const GLInitialContents &initial) { - if(res.Namespace == eResBuffer) + if(initial.type == eResBuffer) { // buffers just have their contents, no metadata needed - return GetInitialContents(resid).bufferLength + WriteSerialiser::GetChunkAlignment() + 16; + return initial.bufferLength + WriteSerialiser::GetChunkAlignment() + 16; } - else if(res.Namespace == eResProgram) + else if(initial.type == eResProgram) { // need to estimate based on how many bindings and uniforms there are. This is a rare path - // only happening when a program is created at runtime in the middle of a frameand we didn't @@ -1070,6 +1069,8 @@ uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource re SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContents); + GLResource res = GetCurrentResource(resid); + SERIALISE_ELEMENT(resid).TypedAs("GLResource"); SERIALISE_ELEMENT(res.Namespace); @@ -1078,13 +1079,13 @@ uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource re return ser.GetWriter()->GetOffset() + 256; } - else if(res.Namespace == eResTexture) + else if(initial.type == eResTexture) { uint64_t ret = 0; ret += sizeof(TextureStateInitialData) + 64; - TextureStateInitialData TextureState = GetInitialContents(resid).tex; + const TextureStateInitialData &TextureState = initial.tex; // in these cases, no more data is serialised if(TextureState.internalformat == eGL_NONE || TextureState.type == eGL_TEXTURE_BUFFER || @@ -1132,67 +1133,68 @@ uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource re return ret; } - else if(res.Namespace == eResFramebuffer) + else if(initial.type == eResFramebuffer) { return sizeof(FramebufferInitialData); } - else if(res.Namespace == eResSampler) + else if(initial.type == eResSampler) { // reserve some extra size to account for array count return sizeof(SamplerInitialData) + 32; } - else if(res.Namespace == eResFeedback) + else if(initial.type == eResFeedback) { return sizeof(FeedbackInitialData); } - else if(res.Namespace == eResProgramPipe) + else if(initial.type == eResProgramPipe) { return sizeof(PipelineInitialData); } - else if(res.Namespace == eResVertexArray) + else if(initial.type == eResVertexArray) { return sizeof(VAOInitialData); } - else if(res.Namespace == eResRenderbuffer) + else if(initial.type == eResRenderbuffer) { } else { - RDCERR("Unexpected type of resource requiring initial state"); + RDCERR("Unexpected type of resource requiring initial state %d", initial.type); } return 16; } template -bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId resid, GLResource res) +bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId id, + GLResourceRecord *record, + const GLInitialContents *initial) { m_State = m_Driver->GetState(); - SERIALISE_ELEMENT_LOCAL(Id, GetID(res)).TypedAs("GLResource"); - SERIALISE_ELEMENT_LOCAL(Type, res.Namespace); - GLInitialContents initContents = GetInitialContents(Id); + GLInitialContents initContents; + if(initial) + initContents = *initial; + + SERIALISE_ELEMENT(id).TypedAs("GLResource"); + SERIALISE_ELEMENT_LOCAL(Type, initial->type); if(IsReplayingAndReading()) { - if(HasLiveResource(Id)) - res = GetLiveResource(Id); - else - res = GLResource(MakeNullResource); - - m_Driver->AddResourceCurChunk(Id); + m_Driver->AddResourceCurChunk(id); } if(Type == eResBuffer) { + GLResource mappedBuffer = GLResource(MakeNullResource); uint32_t BufferContentsSize = 0; byte *BufferContents = NULL; if(ser.IsWriting()) { - res = initContents.resource; - BufferContentsSize = initContents.bufferLength; - BufferContents = (byte *)GL.glMapNamedBufferEXT(res.name, eGL_READ_ONLY); + mappedBuffer = initial->resource; + BufferContentsSize = initial->bufferLength; + BufferContents = (byte *)GL.glMapNamedBufferEXT(mappedBuffer.name, eGL_READ_ONLY); if(!BufferContents) RDCERR("Couldn't map initial contents buffer for readback!"); @@ -1205,18 +1207,14 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r { if(!ser.IsErrored()) { - GL.glGenBuffers(1, &res.name); - GL.glBindBuffer(eGL_COPY_WRITE_BUFFER, res.name); - GL.glNamedBufferDataEXT(res.name, (GLsizeiptr)RDCMAX(BufferContentsSize, 4U), NULL, + GL.glGenBuffers(1, &mappedBuffer.name); + GL.glBindBuffer(eGL_COPY_WRITE_BUFFER, mappedBuffer.name); + GL.glNamedBufferDataEXT(mappedBuffer.name, (GLsizeiptr)RDCMAX(BufferContentsSize, 4U), NULL, eGL_STATIC_DRAW); - BufferContents = (byte *)GL.glMapNamedBufferEXT(res.name, eGL_WRITE_ONLY); + BufferContents = (byte *)GL.glMapNamedBufferEXT(mappedBuffer.name, eGL_WRITE_ONLY); - SetInitialContents( - Id, GLInitialContents(BufferRes(m_Driver->GetCtx(), res.name), BufferContentsSize)); - } - else - { - res = GLResource(MakeNullResource); + SetInitialContents(id, GLInitialContents(BufferRes(m_Driver->GetCtx(), mappedBuffer.name), + BufferContentsSize)); } } @@ -1224,8 +1222,8 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r // directly into upload memory ser.Serialise("BufferContents", BufferContents, BufferContentsSize, SerialiserFlags::NoFlags); - if(res.name) - GL.glUnmapNamedBufferEXT(res.name); + if(mappedBuffer.name) + GL.glUnmapNamedBufferEXT(mappedBuffer.name); SERIALISE_CHECK_READ_ERRORS(); } @@ -1238,7 +1236,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading()) { - WrappedOpenGL::ProgramData &details = m_Driver->m_Programs[GetLiveID(Id)]; + WrappedOpenGL::ProgramData &details = m_Driver->m_Programs[GetLiveID(id)]; GLuint initProg = drv.glCreateProgram(); @@ -1361,7 +1359,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r // uniforms directly into the live program, then copy back to the initial state so that we // have a pristine copy of them for later use. bindingsProgram = initProg; - uniformsProgram = GetLiveResource(Id).name; + uniformsProgram = GetLiveResource(id).name; translationTable = &details.locationTranslate; } @@ -1371,7 +1369,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r // most of the time Prepare_InitialState sets the serialise chunk directly on write, but if a // program is newly created within a frame we won't have prepared its initial contents, so we // need to be ready to write it out here. - bindingsProgram = uniformsProgram = res.name; + bindingsProgram = uniformsProgram = GetCurrentResource(id).name; } SerialiseProgramBindings(ser, m_State, bindingsProgram); @@ -1389,7 +1387,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r // see above for why we're copying this back CopyProgramUniforms(uniformsProgram, bindingsProgram); - SetInitialContents(Id, GLInitialContents(ProgramRes(m_Driver->GetCtx(), bindingsProgram), 0)); + SetInitialContents(id, GLInitialContents(ProgramRes(m_Driver->GetCtx(), bindingsProgram), 0)); } } else if(Type == eResTexture) @@ -1414,16 +1412,20 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r ResetPixelUnpackState(false, 1); } - // serialise the texture metadata which was fetched during state preparation TextureStateInitialData &TextureState = initContents.tex; + if(initial) + TextureState = initial->tex; + + // serialise the texture metadata which was fetched during state preparation SERIALISE_ELEMENT(TextureState); // only continue with serialising the contents if the format is valid (storage allocated). // Otherwise this texture has no initial state to apply if(TextureState.internalformat != eGL_NONE && !ser.IsErrored()) { - WrappedOpenGL::TextureData &details = m_Driver->m_Textures[GetID(res)]; + WrappedOpenGL::TextureData &details = + ser.IsWriting() ? m_Driver->m_Textures[id] : m_Driver->m_Textures[GetLiveID(id)]; if(TextureState.type == eGL_TEXTURE_BUFFER || TextureState.isView) { @@ -1458,14 +1460,16 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r // after we stop tracking it glGenerateMipmap is called. if(IsReplayingAndReading() && !ser.IsErrored()) { + GLResource liveRes = GetLiveResource(id); + // this is only relevant for non-immutable textures GLint immut = 0; - GL.glGetTextureParameterivEXT(res.name, TextureState.type, eGL_TEXTURE_IMMUTABLE_FORMAT, - &immut); + GL.glGetTextureParameterivEXT(liveRes.name, TextureState.type, + eGL_TEXTURE_IMMUTABLE_FORMAT, &immut); GLenum dummy = eGL_RGBA; - EmulateLuminanceFormat(res.name, TextureState.type, TextureState.internalformat, dummy); + EmulateLuminanceFormat(liveRes.name, TextureState.type, TextureState.internalformat, dummy); if(immut == 0) { @@ -1474,7 +1478,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r GLsizei d = (GLsizei)TextureState.depth; // see how many mips we actually have available - int liveMips = GetNumMips(TextureState.type, res.name, w, h, d); + int liveMips = GetNumMips(TextureState.type, liveRes.name, w, h, d); std::vector scratchBuf; @@ -1503,35 +1507,35 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r scratchBuf.resize(compSize); if(TextureState.dim == 1) - GL.glCompressedTextureImage1DEXT(res.name, targets[t], m, + GL.glCompressedTextureImage1DEXT(liveRes.name, targets[t], m, TextureState.internalformat, w, 0, compSize, &scratchBuf[0]); else if(TextureState.dim == 2) - GL.glCompressedTextureImage2DEXT(res.name, targets[t], m, + GL.glCompressedTextureImage2DEXT(liveRes.name, targets[t], m, TextureState.internalformat, w, h, 0, compSize, &scratchBuf[0]); else if(TextureState.dim == 3) - GL.glCompressedTextureImage3DEXT(res.name, targets[t], m, + GL.glCompressedTextureImage3DEXT(liveRes.name, targets[t], m, TextureState.internalformat, w, h, d, 0, compSize, &scratchBuf[0]); } else { if(TextureState.dim == 1) - GL.glTextureImage1DEXT(res.name, targets[t], m, TextureState.internalformat, - (GLsizei)w, 0, + GL.glTextureImage1DEXT(liveRes.name, targets[t], m, + TextureState.internalformat, (GLsizei)w, 0, GetBaseFormat(TextureState.internalformat), GetDataType(TextureState.internalformat), NULL); else if(TextureState.dim == 2) - GL.glTextureImage2DEXT(res.name, targets[t], m, TextureState.internalformat, - (GLsizei)w, (GLsizei)h, 0, + GL.glTextureImage2DEXT(liveRes.name, targets[t], m, + TextureState.internalformat, (GLsizei)w, (GLsizei)h, 0, GetBaseFormat(TextureState.internalformat), GetDataType(TextureState.internalformat), NULL); else if(TextureState.dim == 3) - GL.glTextureImage3DEXT(res.name, targets[t], m, TextureState.internalformat, - (GLsizei)w, (GLsizei)h, (GLsizei)d, 0, - GetBaseFormat(TextureState.internalformat), - GetDataType(TextureState.internalformat), NULL); + GL.glTextureImage3DEXT( + liveRes.name, targets[t], m, TextureState.internalformat, (GLsizei)w, + (GLsizei)h, (GLsizei)d, 0, GetBaseFormat(TextureState.internalformat), + GetDataType(TextureState.internalformat), NULL); } } } @@ -1561,7 +1565,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r else if(ser.IsWriting()) { // on writing, bind the prepared texture with initial contents to grab - tex = initContents.resource.name; + tex = initial->resource.name; GL.glBindTexture(TextureState.type, tex); } @@ -1695,7 +1699,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading() && !ser.IsErrored()) { - SetInitialContents(Id, initContents); + SetInitialContents(id, initContents); } } @@ -1720,7 +1724,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading()) { - SetInitialContents(Id, initContents); + SetInitialContents(id, initContents); } } else if(Type == eResSampler) @@ -1733,7 +1737,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading()) { - SetInitialContents(Id, initContents); + SetInitialContents(id, initContents); } } else if(Type == eResFeedback) @@ -1746,7 +1750,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading()) { - SetInitialContents(Id, initContents); + SetInitialContents(id, initContents); } } else if(Type == eResProgramPipe) @@ -1759,7 +1763,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading()) { - SetInitialContents(Id, initContents); + SetInitialContents(id, initContents); } } else if(Type == eResVertexArray) @@ -1772,7 +1776,7 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r if(IsReplayingAndReading()) { - SetInitialContents(Id, initContents); + SetInitialContents(id, initContents); } } else if(Type == eResRenderbuffer) @@ -1789,10 +1793,12 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r return true; } -template bool GLResourceManager::Serialise_InitialState<>(ReadSerialiser &ser, ResourceId resid, - GLResource res); -template bool GLResourceManager::Serialise_InitialState<>(WriteSerialiser &ser, ResourceId resid, - GLResource res); +template bool GLResourceManager::Serialise_InitialState<>(ReadSerialiser &ser, ResourceId id, + GLResourceRecord *record, + const GLInitialContents *initial); +template bool GLResourceManager::Serialise_InitialState<>(WriteSerialiser &ser, ResourceId id, + GLResourceRecord *record, + const GLInitialContents *initial); void GLResourceManager::Create_InitialState(ResourceId id, GLResource live, bool hasData) { @@ -1825,7 +1831,7 @@ void GLResourceManager::Create_InitialState(ResourceId id, GLResource live, bool } } -void GLResourceManager::Apply_InitialState(GLResource live, GLInitialContents initial) +void GLResourceManager::Apply_InitialState(GLResource live, const GLInitialContents &initial) { if(live.Namespace == eResBuffer) { diff --git a/renderdoc/driver/gl/gl_initstate.h b/renderdoc/driver/gl/gl_initstate.h index 8e35c3a67..66462b371 100644 --- a/renderdoc/driver/gl/gl_initstate.h +++ b/renderdoc/driver/gl/gl_initstate.h @@ -183,6 +183,8 @@ struct GLInitialContents TextureStateInitialData tex; }; + GLNamespace type; + // the GL object containing the contents of a texture, buffer, or program GLResource resource; uint32_t bufferLength; diff --git a/renderdoc/driver/gl/gl_manager.h b/renderdoc/driver/gl/gl_manager.h index 2132460d3..0b2fae1cf 100644 --- a/renderdoc/driver/gl/gl_manager.h +++ b/renderdoc/driver/gl/gl_manager.h @@ -246,21 +246,22 @@ public: void Force_ReferenceViews(); template - bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, GLResource res); + bool Serialise_InitialState(SerialiserType &ser, ResourceId id, GLResourceRecord *record, + const GLInitialContents *initial); void ContextPrepare_InitialState(GLResource res); - bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, GLResource res) + bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, GLResourceRecord *record, + const GLInitialContents *initial) { - return Serialise_InitialState(ser, resid, res); + return Serialise_InitialState(ser, id, record, initial); } void SetInternalResource(GLResource res); private: bool ResourceTypeRelease(GLResource res); - bool Need_InitialStateChunk(GLResource res); bool Prepare_InitialState(GLResource res); - uint64_t GetSize_InitialState(ResourceId resid, GLResource res); + uint64_t GetSize_InitialState(ResourceId resid, const GLInitialContents &initial); void CreateTextureImage(GLuint tex, GLenum internalFormat, GLenum internalFormatHint, GLenum textype, GLint dim, GLint width, GLint height, GLint depth, @@ -268,7 +269,7 @@ private: void PrepareTextureInitialContents(ResourceId liveid, ResourceId origid, GLResource res); void Create_InitialState(ResourceId id, GLResource live, bool hasData); - void Apply_InitialState(GLResource live, GLInitialContents initial); + void Apply_InitialState(GLResource live, const GLInitialContents &initial); map m_GLResourceRecords; diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index d9cfc3567..5525a0e0a 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -2941,7 +2941,7 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk) } else if(system == SystemChunk::InitialContents) { - return Serialise_InitialState(ser, ResourceId(), NULL); + return Serialise_InitialState(ser, ResourceId(), NULL, NULL); } else if(system == SystemChunk::CaptureScope) { diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 68e20b47f..6d0d9dea1 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -828,12 +828,12 @@ private: bool Prepare_SparseInitialState(WrappedVkImage *im); template bool Serialise_SparseBufferInitialState(SerialiserType &ser, ResourceId id, - VkInitialContents contents); + const VkInitialContents *contents); template bool Serialise_SparseImageInitialState(SerialiserType &ser, ResourceId id, - VkInitialContents contents); - bool Apply_SparseInitialState(WrappedVkBuffer *buf, VkInitialContents contents); - bool Apply_SparseInitialState(WrappedVkImage *im, VkInitialContents contents); + const VkInitialContents *contents); + bool Apply_SparseInitialState(WrappedVkBuffer *buf, const VkInitialContents &contents); + bool Apply_SparseInitialState(WrappedVkImage *im, const VkInitialContents &contents); void ApplyInitialContents(); @@ -916,12 +916,13 @@ public: VulkanReplay *GetReplay() { return &m_Replay; } // replay interface bool Prepare_InitialState(WrappedVkRes *res); - uint64_t GetSize_InitialState(ResourceId id, WrappedVkRes *res); - uint64_t GetSize_SparseInitialState(ResourceId id, WrappedVkRes *res); + uint64_t GetSize_InitialState(ResourceId id, const VkInitialContents &initial); + uint64_t GetSize_SparseInitialState(ResourceId id, const VkInitialContents &initial); template - bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, WrappedVkRes *res); + bool Serialise_InitialState(SerialiserType &ser, ResourceId id, VkResourceRecord *record, + const VkInitialContents *initial); void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); - void Apply_InitialState(WrappedVkRes *live, VkInitialContents initial); + void Apply_InitialState(WrappedVkRes *live, const VkInitialContents &initial); void RemapQueueFamilyIndices(uint32_t &srcQueueFamily, uint32_t &dstQueueFamily); uint32_t GetQueueFamilyIndex() { return m_QueueFamilyIdx; } diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 8e171070c..3a5486a2e 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -623,14 +623,12 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res) return false; } -uint64_t WrappedVulkan::GetSize_InitialState(ResourceId id, WrappedVkRes *res) +uint64_t WrappedVulkan::GetSize_InitialState(ResourceId id, const VkInitialContents &initial) { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - VkResourceType type = IdentifyTypeByPtr(record->Resource); - VkInitialContents initContents = GetResourceManager()->GetInitialContents(id); - - if(type == eResDescriptorSet) + if(initial.type == eResDescriptorSet) { + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); + RDCASSERT(record->descInfo && record->descInfo->layout); const DescSetLayout &layout = *record->descInfo->layout; @@ -641,21 +639,21 @@ uint64_t WrappedVulkan::GetSize_InitialState(ResourceId id, WrappedVkRes *res) return 32 + NumBindings * sizeof(DescriptorSetSlot); } - else if(type == eResBuffer) + else if(initial.type == eResBuffer) { // buffers only have initial states when they're sparse - return GetSize_SparseInitialState(id, res); + return GetSize_SparseInitialState(id, initial); } - else if(type == eResImage || type == eResDeviceMemory) + else if(initial.type == eResImage || initial.type == eResDeviceMemory) { - if(initContents.tag == VkInitialContents::Sparse) - return GetSize_SparseInitialState(id, res); + if(initial.tag == VkInitialContents::Sparse) + return GetSize_SparseInitialState(id, initial); // the size primarily comes from the buffer, the size of which we conveniently have stored. - return uint64_t(128 + initContents.mem.size + WriteSerialiser::GetChunkAlignment()); + return uint64_t(128 + initial.mem.size + WriteSerialiser::GetChunkAlignment()); } - RDCERR("Unhandled resource type %s", ToStr(type).c_str()); + RDCERR("Unhandled resource type %s", ToStr(initial.type).c_str()); return 128; } @@ -672,24 +670,13 @@ static const char *NameOfType(VkResourceType type) return "VkResource"; } -// second parameter isn't used, as we might be serialising init state for a deleted resource template -bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, WrappedVkRes *) +bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, + VkResourceRecord *record, const VkInitialContents *initial) { - VkResourceType type; - - VkResourceRecord *record = NULL; - if(ser.IsWriting()) - { - record = GetResourceManager()->GetResourceRecord(id); - // use the record's resource, not the one passed in, because the passed in one - // might be null if it was deleted - type = IdentifyTypeByPtr(record->Resource); - } - bool ret = true; - SERIALISE_ELEMENT(type); + SERIALISE_ELEMENT_LOCAL(type, initial->type); SERIALISE_ELEMENT(id).TypedAs(NameOfType(type)); if(IsReplayingAndReading()) @@ -705,12 +692,10 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W // while writing, fetching binding information from prepared initial contents if(ser.IsWriting()) { - VkInitialContents initContents = GetResourceManager()->GetInitialContents(id); - RDCASSERT(record->descInfo && record->descInfo->layout); const DescSetLayout &layout = *record->descInfo->layout; - Bindings = (DescriptorSetSlot *)initContents.descriptorSlots; + Bindings = (DescriptorSetSlot *)initial->descriptorSlots; for(size_t i = 0; i < layout.bindings.size(); i++) NumBindings += layout.bindings[i].descriptorCount; @@ -927,16 +912,15 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W else if(type == eResBuffer) { // buffers only have initial states when they're sparse - return Serialise_SparseBufferInitialState(ser, id, GetResourceManager()->GetInitialContents(id)); + return Serialise_SparseBufferInitialState(ser, id, initial); } else if(type == eResDeviceMemory || type == eResImage) { VkDevice d = !IsStructuredExporting(m_State) ? GetDev() : VK_NULL_HANDLE; - VkInitialContents initContents = GetResourceManager()->GetInitialContents(id); // if we have a blob of data, this contains sparse mapping so re-direct to the sparse // implementation of this function - SERIALISE_ELEMENT_LOCAL(IsSparse, initContents.tag == VkInitialContents::Sparse); + SERIALISE_ELEMENT_LOCAL(IsSparse, initial && initial->tag == VkInitialContents::Sparse); if(IsSparse) { @@ -944,7 +928,7 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W if(type == eResImage) { - ret = Serialise_SparseImageInitialState(ser, id, initContents); + ret = Serialise_SparseImageInitialState(ser, id, initial); } else { @@ -958,7 +942,7 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W VkResult vkr = VK_SUCCESS; byte *Contents = NULL; - uint64_t ContentsSize = initContents.mem.size; + uint64_t ContentsSize = initial ? initial->mem.size : 0; MemoryAllocation mappedMem; // Serialise this separately so that it can be used on reading to prepare the upload memory @@ -971,11 +955,11 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W // during writing, we already have the memory copied off - we just need to map it. if(ser.IsWriting()) { - if(initContents.mem.mem != VK_NULL_HANDLE) + if(initial && initial->mem.mem != VK_NULL_HANDLE) { - mappedMem = initContents.mem; - vkr = ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mappedMem.mem), initContents.mem.offs, - initContents.mem.size, 0, (void **)&Contents); + mappedMem = initial->mem; + vkr = ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mappedMem.mem), initial->mem.offs, + initial->mem.size, 0, (void **)&Contents); RDCASSERTEQUAL(vkr, VK_SUCCESS); // invalidate the cpu cache for this memory range to avoid reading stale data @@ -1059,7 +1043,7 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W } else { - VkInitialContents initial(type, uploadMemory); + VkInitialContents initialContents(type, uploadMemory); VulkanCreationInfo::Image &c = m_CreationInfo.m_Image[liveid]; @@ -1067,7 +1051,7 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W // offsets to copy out the subresources into the image itself. if(c.samples == VK_SAMPLE_COUNT_1_BIT) { - initial.buf = uploadBuf; + initialContents.buf = uploadBuf; } else { @@ -1227,12 +1211,12 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W vkDestroyBuffer(d, uploadBuf, NULL); FreeMemoryAllocation(uploadMemory); - initial.buf = VK_NULL_HANDLE; - initial.img = arrayIm; - initial.mem = arrayMem; + initialContents.buf = VK_NULL_HANDLE; + initialContents.img = arrayIm; + initialContents.mem = arrayMem; } - GetResourceManager()->SetInitialContents(id, initial); + GetResourceManager()->SetInitialContents(id, initialContents); } } } @@ -1245,10 +1229,12 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W return ret; } -template bool WrappedVulkan::Serialise_InitialState(ReadSerialiser &ser, ResourceId resid, - WrappedVkRes *); -template bool WrappedVulkan::Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, - WrappedVkRes *); +template bool WrappedVulkan::Serialise_InitialState(ReadSerialiser &ser, ResourceId id, + VkResourceRecord *record, + const VkInitialContents *initial); +template bool WrappedVulkan::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, + VkResourceRecord *record, + const VkInitialContents *initial); void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData) { @@ -1302,7 +1288,7 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool } } -void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VkInitialContents initial) +void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialContents &initial) { VkResourceType type = initial.type; diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index 3107d4579..2b7d32cc5 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -723,25 +723,21 @@ MemRefs *VulkanResourceManager::FindMemRefs(ResourceId mem) return NULL; } -bool VulkanResourceManager::Need_InitialStateChunk(WrappedVkRes *res) -{ - return true; -} - bool VulkanResourceManager::Prepare_InitialState(WrappedVkRes *res) { return m_Core->Prepare_InitialState(res); } -uint64_t VulkanResourceManager::GetSize_InitialState(ResourceId id, WrappedVkRes *res) +uint64_t VulkanResourceManager::GetSize_InitialState(ResourceId id, const VkInitialContents &initial) { - return m_Core->GetSize_InitialState(id, res); + return m_Core->GetSize_InitialState(id, initial); } -bool VulkanResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, - WrappedVkRes *res) +bool VulkanResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id, + VkResourceRecord *record, + const VkInitialContents *initial) { - return m_Core->Serialise_InitialState(ser, resid, res); + return m_Core->Serialise_InitialState(ser, id, record, initial); } void VulkanResourceManager::Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData) @@ -749,7 +745,7 @@ void VulkanResourceManager::Create_InitialState(ResourceId id, WrappedVkRes *liv return m_Core->Create_InitialState(id, live, hasData); } -void VulkanResourceManager::Apply_InitialState(WrappedVkRes *live, VkInitialContents initial) +void VulkanResourceManager::Apply_InitialState(WrappedVkRes *live, const VkInitialContents &initial) { return m_Core->Apply_InitialState(live, initial); } diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 4c60f53c2..7e19b2c6a 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -435,13 +435,12 @@ public: private: bool ResourceTypeRelease(WrappedVkRes *res); - bool AllowDeletedResource_InitialState() { return true; } - bool Need_InitialStateChunk(WrappedVkRes *res); bool Prepare_InitialState(WrappedVkRes *res); - uint64_t GetSize_InitialState(ResourceId id, WrappedVkRes *res); - bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, WrappedVkRes *res); + uint64_t GetSize_InitialState(ResourceId id, const VkInitialContents &initial); + bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, VkResourceRecord *record, + const VkInitialContents *initial); void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); - void Apply_InitialState(WrappedVkRes *live, VkInitialContents initial); + void Apply_InitialState(WrappedVkRes *live, const VkInitialContents &initial); std::vector InitialContentResources(); CaptureState m_State; diff --git a/renderdoc/driver/vulkan/vk_sparse_initstate.cpp b/renderdoc/driver/vulkan/vk_sparse_initstate.cpp index b606bdc9b..5f982356b 100644 --- a/renderdoc/driver/vulkan/vk_sparse_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_sparse_initstate.cpp @@ -359,15 +359,11 @@ bool WrappedVulkan::Prepare_SparseInitialState(WrappedVkImage *im) return true; } -uint64_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes *res) +uint64_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, const VkInitialContents &initial) { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - VkResourceType type = IdentifyTypeByPtr(record->Resource); - VkInitialContents contents = GetResourceManager()->GetInitialContents(id); - - if(type == eResBuffer) + if(initial.type == eResBuffer) { - SparseBufferInitState &info = contents.sparseBuffer; + const SparseBufferInitState &info = initial.sparseBuffer; // some bytes just to cover overheads etc. uint64_t ret = 128; @@ -383,9 +379,9 @@ uint64_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes * return ret; } - else if(type == eResImage) + else if(initial.type == eResImage) { - SparseImageInitState &info = contents.sparseImage; + const SparseImageInitState &info = initial.sparseImage; // some bytes just to cover overheads etc. uint64_t ret = 128; @@ -409,18 +405,18 @@ uint64_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes * return ret; } - RDCERR("Unhandled resource type %s", ToStr(type).c_str()); + RDCERR("Unhandled resource type %s", ToStr(initial.type).c_str()); return 128; } template bool WrappedVulkan::Serialise_SparseBufferInitialState(SerialiserType &ser, ResourceId id, - VkInitialContents contents) + const VkInitialContents *contents) { VkDevice d = !IsStructuredExporting(m_State) ? GetDev() : VK_NULL_HANDLE; VkResult vkr = VK_SUCCESS; - SERIALISE_ELEMENT_LOCAL(SparseState, contents.sparseBuffer); + SERIALISE_ELEMENT_LOCAL(SparseState, contents->sparseBuffer); MemoryAllocation mappedMem; byte *Contents = NULL; @@ -437,7 +433,7 @@ bool WrappedVulkan::Serialise_SparseBufferInitialState(SerialiserType &ser, Reso if(ser.IsWriting()) { // the memory was created not wrapped. - mappedMem = contents.mem; + mappedMem = contents->mem; vkr = ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mappedMem.mem), mappedMem.offs, mappedMem.size, 0, (void **)&Contents); RDCASSERTEQUAL(vkr, VK_SUCCESS); @@ -531,12 +527,12 @@ bool WrappedVulkan::Serialise_SparseBufferInitialState(SerialiserType &ser, Reso template bool WrappedVulkan::Serialise_SparseImageInitialState(SerialiserType &ser, ResourceId id, - VkInitialContents contents) + const VkInitialContents *contents) { VkDevice d = !IsStructuredExporting(m_State) ? GetDev() : VK_NULL_HANDLE; VkResult vkr = VK_SUCCESS; - SERIALISE_ELEMENT_LOCAL(SparseState, contents.sparseImage); + SERIALISE_ELEMENT_LOCAL(SparseState, contents->sparseImage); MemoryAllocation mappedMem; byte *Contents = NULL; @@ -552,7 +548,7 @@ bool WrappedVulkan::Serialise_SparseImageInitialState(SerialiserType &ser, Resou // during writing, we already have the memory copied off - we just need to map it. if(ser.IsWriting()) { - mappedMem = contents.mem; + mappedMem = contents->mem; vkr = ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mappedMem.mem), mappedMem.offs, mappedMem.size, 0, (void **)&Contents); RDCASSERTEQUAL(vkr, VK_SUCCESS); @@ -658,17 +654,17 @@ bool WrappedVulkan::Serialise_SparseImageInitialState(SerialiserType &ser, Resou } template bool WrappedVulkan::Serialise_SparseBufferInitialState(ReadSerialiser &ser, ResourceId id, - VkInitialContents contents); + const VkInitialContents *contents); template bool WrappedVulkan::Serialise_SparseBufferInitialState(WriteSerialiser &ser, ResourceId id, - VkInitialContents contents); + const VkInitialContents *contents); template bool WrappedVulkan::Serialise_SparseImageInitialState(ReadSerialiser &ser, ResourceId id, - VkInitialContents contents); + const VkInitialContents *contents); template bool WrappedVulkan::Serialise_SparseImageInitialState(WriteSerialiser &ser, ResourceId id, - VkInitialContents contents); + const VkInitialContents *contents); -bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, VkInitialContents contents) +bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, const VkInitialContents &contents) { - SparseBufferInitState &info = contents.sparseBuffer; + const SparseBufferInitState &info = contents.sparseBuffer; // unbind the entire buffer so that any new areas that are bound are unbound again @@ -764,9 +760,9 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, VkInitialCont return true; } -bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, VkInitialContents contents) +bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, const VkInitialContents &contents) { - SparseImageInitState &info = contents.sparseImage; + const SparseImageInitState &info = contents.sparseImage; VkQueue q = GetQ();