diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index c61bd1e50..0a0528267 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -428,9 +428,10 @@ class ResourceManager : public ResourceRecordHandler virtual bool ResourceTypeRelease(WrappedResourceType res) = 0; virtual bool Force_InitialState(WrappedResourceType res) = 0; + virtual bool AllowDeletedResource_InitialState() { return false; } virtual bool Need_InitialStateChunk(WrappedResourceType res) = 0; virtual bool Prepare_InitialState(WrappedResourceType res) = 0; - virtual bool Serialise_InitialState(WrappedResourceType res) = 0; + virtual bool Serialise_InitialState(ResourceId id, WrappedResourceType res) = 0; virtual void Create_InitialState(ResourceId id, WrappedResourceType live, bool hasData) = 0; virtual void Apply_InitialState(WrappedResourceType live, InitialContentData initial) = 0; @@ -956,8 +957,11 @@ void ResourceManager::InsertI skipped++; continue; } + + WrappedResourceType res = (WrappedResourceType)RecordType::NullResource; + bool isAlive = HasCurrentResource(id); - if(!HasCurrentResource(id)) + if(!AllowDeletedResource_InitialState() && !isAlive) { #if VERBOSE_DIRTY_RESOURCES RDCDEBUG("Resource %llu no longer exists - skipping", id); @@ -965,8 +969,10 @@ void ResourceManager::InsertI continue; } + if(isAlive) + res = GetCurrentResource(id); + RecordType *record = GetResourceRecord(id); - WrappedResourceType res = GetCurrentResource(id); if(record == NULL) { @@ -993,7 +999,7 @@ void ResourceManager::InsertI if(!Need_InitialStateChunk(res)) { // just need to grab data, don't create chunk - Serialise_InitialState(res); + Serialise_InitialState(id, res); continue; } @@ -1007,7 +1013,7 @@ void ResourceManager::InsertI { ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, false); - Serialise_InitialState(res); + Serialise_InitialState(id, res); fileSerialiser->Insert(scope.Get(true)); } @@ -1035,7 +1041,7 @@ void ResourceManager::InsertI { ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, false); - Serialise_InitialState(it->second); + Serialise_InitialState(it->first, it->second); fileSerialiser->Insert(scope.Get(true)); } diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index 9ccc9abea..9da688da6 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -970,7 +970,7 @@ void WrappedID3D11Device::ProcessChunk(uint64_t offset, D3D11ChunkType context) default: // ignore system chunks if(context == INITIAL_CONTENTS) - Serialise_InitialState(NULL); + Serialise_InitialState(ResourceId(), NULL); else if(context < FIRST_CHUNK_ID) m_pSerialiser->SkipCurrentChunk(); else @@ -1321,7 +1321,7 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) return true; } -bool WrappedID3D11Device::Serialise_InitialState(ID3D11DeviceChild *res) +bool WrappedID3D11Device::Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res) { ResourceType type = Resource_Unknown; ResourceId Id = ResourceId(); diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 471ec28f6..2b5711728 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -322,7 +322,7 @@ public: // log replaying bool Prepare_InitialState(ID3D11DeviceChild *res); - bool Serialise_InitialState(ID3D11DeviceChild *res); + bool Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res); void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); void Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial); diff --git a/renderdoc/driver/d3d11/d3d11_manager.cpp b/renderdoc/driver/d3d11/d3d11_manager.cpp index abe0d8b9b..a09d9351c 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.cpp +++ b/renderdoc/driver/d3d11/d3d11_manager.cpp @@ -106,9 +106,9 @@ bool D3D11ResourceManager::Prepare_InitialState(ID3D11DeviceChild *res) return m_Device->Prepare_InitialState(res); } -bool D3D11ResourceManager::Serialise_InitialState(ID3D11DeviceChild *res) +bool D3D11ResourceManager::Serialise_InitialState(ResourceId id, ID3D11DeviceChild *res) { - return m_Device->Serialise_InitialState(res); + return m_Device->Serialise_InitialState(id, res); } void D3D11ResourceManager::Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData) diff --git a/renderdoc/driver/d3d11/d3d11_manager.h b/renderdoc/driver/d3d11/d3d11_manager.h index 6b9087fd6..c1d911061 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.h +++ b/renderdoc/driver/d3d11/d3d11_manager.h @@ -196,7 +196,7 @@ class D3D11ResourceManager : public ResourceManagerSerialise_InitialState(GLResource(MakeNullResource)); + GetResourceManager()->Serialise_InitialState(ResourceId(), GLResource(MakeNullResource)); else if((int)context < (int)FIRST_CHUNK_ID) m_pSerialiser->SkipCurrentChunk(); else diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 3710c72e3..69f838ee7 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -804,7 +804,7 @@ bool GLResourceManager::Force_InitialState(GLResource res) return false; } -bool GLResourceManager::Serialise_InitialState(GLResource res) +bool GLResourceManager::Serialise_InitialState(ResourceId resid, GLResource res) { ResourceId Id = ResourceId(); diff --git a/renderdoc/driver/gl/gl_manager.h b/renderdoc/driver/gl/gl_manager.h index ad83fa6ea..732fa354e 100644 --- a/renderdoc/driver/gl/gl_manager.h +++ b/renderdoc/driver/gl/gl_manager.h @@ -221,7 +221,7 @@ class GLResourceManager : public ResourceManagerSkipCurrentChunk(); else diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 1212d46a8..1a8bbe97f 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -462,8 +462,8 @@ private: bool Prepare_SparseInitialState(WrappedVkBuffer *buf); bool Prepare_SparseInitialState(WrappedVkImage *im); - bool Serialise_SparseInitialState(ResourceId id, WrappedVkBuffer *buf, VulkanResourceManager::InitialContentData contents); - bool Serialise_SparseInitialState(ResourceId id, WrappedVkImage *im, VulkanResourceManager::InitialContentData contents); + bool Serialise_SparseBufferInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents); + bool Serialise_SparseImageInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents); bool Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourceManager::InitialContentData contents); bool Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceManager::InitialContentData contents); @@ -539,7 +539,7 @@ public: // replay interface bool Prepare_InitialState(WrappedVkRes *res); - bool Serialise_InitialState(WrappedVkRes *res); + bool Serialise_InitialState(ResourceId resid, WrappedVkRes *res); void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); void Apply_InitialState(WrappedVkRes *live, VulkanResourceManager::InitialContentData initial); diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 905199312..2bc30306e 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -377,7 +377,7 @@ bool WrappedVulkan::Prepare_SparseInitialState(WrappedVkImage *im) return true; } -bool WrappedVulkan::Serialise_SparseInitialState(ResourceId id, WrappedVkBuffer *buf, VulkanResourceManager::InitialContentData contents) +bool WrappedVulkan::Serialise_SparseBufferInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents) { if(m_State >= WRITING) { @@ -502,7 +502,7 @@ bool WrappedVulkan::Serialise_SparseInitialState(ResourceId id, WrappedVkBuffer return true; } -bool WrappedVulkan::Serialise_SparseInitialState(ResourceId id, WrappedVkImage *im, VulkanResourceManager::InitialContentData contents) +bool WrappedVulkan::Serialise_SparseImageInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents) { if(m_State >= WRITING) { @@ -1201,15 +1201,20 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res) return false; } -bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) +// second parameter isn't used, as we might be serialising init state for a deleted resource +bool WrappedVulkan::Serialise_InitialState(ResourceId resid, WrappedVkRes *) { // use same serialiser as resource manager Serialiser *localSerialiser = GetMainSerialiser(); + + VkResourceRecord *record = NULL; + if(m_State >= WRITING) + record = GetResourceManager()->GetResourceRecord(resid); - SERIALISE_ELEMENT(VkResourceType, type, IdentifyTypeByPtr(res)); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(res)); - - if(m_State < WRITING) res = GetResourceManager()->GetLiveResource(id); + // use the record's resource, not the one passed in, because the passed in one + // might be null if it was deleted + SERIALISE_ELEMENT(VkResourceType, type, IdentifyTypeByPtr(record->Resource)); + SERIALISE_ELEMENT(ResourceId, id, resid); if(m_State >= WRITING) { @@ -1217,7 +1222,6 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) if(type == eResDescriptorSet) { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); RDCASSERT(record->descInfo && record->descInfo->layout); const DescSetLayout &layout = *record->descInfo->layout; @@ -1231,7 +1235,7 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) } else if(type == eResBuffer) { - return Serialise_SparseInitialState(id, (WrappedVkBuffer *)res, initContents); + return Serialise_SparseBufferInitialState(id, initContents); } else if(type == eResDeviceMemory || type == eResImage) { @@ -1245,7 +1249,7 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) { // contains page mapping RDCASSERT(type == eResImage); - return Serialise_SparseInitialState(id, (WrappedVkImage *)res, initContents); + return Serialise_SparseImageInitialState(id, initContents); } byte *ptr = NULL; @@ -1265,6 +1269,8 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) } else { + WrappedVkRes *res = GetResourceManager()->GetLiveResource(id); + RDCASSERT(res != NULL); ResourceId liveid = GetResourceManager()->GetLiveID(id); @@ -1417,7 +1423,7 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) } else if(type == eResBuffer) { - return Serialise_SparseInitialState(id, (WrappedVkBuffer *)NULL, VulkanResourceManager::InitialContentData()); + return Serialise_SparseBufferInitialState(id, VulkanResourceManager::InitialContentData()); } else if(type == eResImage) { @@ -1426,7 +1432,7 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) if(isSparse) { - return Serialise_SparseInitialState(id, (WrappedVkImage *)NULL, VulkanResourceManager::InitialContentData()); + return Serialise_SparseImageInitialState(id, VulkanResourceManager::InitialContentData()); } uint32_t dataSize = 0; diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index b3a8edda5..d11865609 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -489,9 +489,9 @@ bool VulkanResourceManager::Prepare_InitialState(WrappedVkRes *res) return m_Core->Prepare_InitialState(res); } -bool VulkanResourceManager::Serialise_InitialState(WrappedVkRes *res) +bool VulkanResourceManager::Serialise_InitialState(ResourceId resid, WrappedVkRes *res) { - return m_Core->Serialise_InitialState(res); + return m_Core->Serialise_InitialState(resid, res); } void VulkanResourceManager::Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData) diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 7ab1374e1..1c459dc6c 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -244,9 +244,10 @@ class VulkanResourceManager : public ResourceManager