mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-05 05:15:47 +00:00
Allow resource managers to serialise init state for deleted objects
* This is needed in Vulkan for the case where memory is freed during a frame, but it was USED during the frame, and the initial contents are needed for the data in the memory.
This commit is contained in:
@@ -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<WrappedResourceType, RealResourceType, RecordType>::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<WrappedResourceType, RealResourceType, RecordType>::InsertI
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isAlive)
|
||||
res = GetCurrentResource(id);
|
||||
|
||||
RecordType *record = GetResourceRecord(id);
|
||||
WrappedResourceType res = GetCurrentResource(id);
|
||||
|
||||
if(record == NULL)
|
||||
{
|
||||
@@ -993,7 +999,7 @@ void ResourceManager<WrappedResourceType, RealResourceType, RecordType>::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<WrappedResourceType, RealResourceType, RecordType>::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<WrappedResourceType, RealResourceType, RecordType>::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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -196,7 +196,7 @@ class D3D11ResourceManager : public ResourceManager<ID3D11DeviceChild*, ID3D11De
|
||||
bool Force_InitialState(ID3D11DeviceChild *res);
|
||||
bool Need_InitialStateChunk(ID3D11DeviceChild *res);
|
||||
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, InitialContentData data);
|
||||
|
||||
|
||||
@@ -3874,7 +3874,7 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
|
||||
default:
|
||||
// ignore system chunks
|
||||
if((int)context == (int)INITIAL_CONTENTS)
|
||||
GetResourceManager()->Serialise_InitialState(GLResource(MakeNullResource));
|
||||
GetResourceManager()->Serialise_InitialState(ResourceId(), GLResource(MakeNullResource));
|
||||
else if((int)context < (int)FIRST_CHUNK_ID)
|
||||
m_pSerialiser->SkipCurrentChunk();
|
||||
else
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ class GLResourceManager : public ResourceManager<GLResource, GLResource, GLResou
|
||||
void MarkFBOReferenced(GLResource res, FrameRefType ref);
|
||||
|
||||
bool Prepare_InitialState(GLResource res, byte *blob);
|
||||
bool Serialise_InitialState(GLResource res);
|
||||
bool Serialise_InitialState(ResourceId resid, GLResource res);
|
||||
|
||||
private:
|
||||
bool SerialisableResource(ResourceId id, GLResourceRecord *record);
|
||||
|
||||
@@ -1796,7 +1796,7 @@ void WrappedVulkan::ProcessChunk(uint64_t offset, VulkanChunkType context)
|
||||
default:
|
||||
// ignore system chunks
|
||||
if((int)context == (int)INITIAL_CONTENTS)
|
||||
Serialise_InitialState(NULL);
|
||||
Serialise_InitialState(ResourceId(), NULL);
|
||||
else if((int)context < (int)FIRST_CHUNK_ID)
|
||||
m_pSerialiser->SkipCurrentChunk();
|
||||
else
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -244,9 +244,10 @@ class VulkanResourceManager : public ResourceManager<WrappedVkRes*, TypedRealHan
|
||||
bool ResourceTypeRelease(WrappedVkRes *res);
|
||||
|
||||
bool Force_InitialState(WrappedVkRes *res);
|
||||
bool AllowDeletedResource_InitialState() { return true; }
|
||||
bool Need_InitialStateChunk(WrappedVkRes *res);
|
||||
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, InitialContentData initial);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user