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:
baldurk
2016-02-07 18:50:37 +01:00
parent 96aaa889dc
commit 2b8c7cae64
13 changed files with 47 additions and 34 deletions
+12 -6
View File
@@ -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));
}
+2 -2
View File
@@ -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();
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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);
+18 -12
View File
@@ -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;
+2 -2
View File
@@ -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)
+2 -1
View File
@@ -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);