Fix structured serialisation of specially handled structs

* Anything which has an explicit "If writing, set up element" rather than merely
  serialising directly.
* Also e.g. for ResourceIds, when structurising grabbing the ID of an object
  will get the live ID, so we need to get the original ID.
This commit is contained in:
baldurk
2020-10-28 15:25:01 +00:00
parent d397b7fdce
commit 2c248935f6
3 changed files with 74 additions and 39 deletions
+55 -22
View File
@@ -81,6 +81,8 @@ void DoSerialiseViaResourceId(SerialiserType &ser, Interface *&el)
if(ser.IsWriting())
id = GetResID(el);
if(ser.IsStructurising() && rm)
id = rm->GetOriginalID(GetResID(el));
DoSerialise(ser, id);
@@ -161,7 +163,7 @@ void DoSerialise(SerialiserType &ser, D3D12RootSignatureParameter &el)
{
RDCASSERTMSG(
"root signature parameter serialisation is only supported for structured serialisers",
ser.IsDummy());
ser.IsStructurising());
SERIALISE_MEMBER(ParameterType);
switch(el.ParameterType)
@@ -211,8 +213,10 @@ void DoSerialise(SerialiserType &ser, D3D12_CPU_DESCRIPTOR_HANDLE &el)
PortableHandle ph;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
ph = ToPortableHandle(el);
if(ser.IsStructurising() && rm)
ph.heap = rm->GetOriginalID(ph.heap);
DoSerialise(ser, ph);
@@ -232,8 +236,10 @@ void DoSerialise(SerialiserType &ser, D3D12_GPU_DESCRIPTOR_HANDLE &el)
PortableHandle ph;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
ph = ToPortableHandle(el);
if(ser.IsStructurising() && rm)
ph.heap = rm->GetOriginalID(ph.heap);
DoSerialise(ser, ph);
@@ -255,11 +261,16 @@ void DoSerialise(SerialiserType &ser, DynamicDescriptorCopy &el)
PortableHandle dst, src;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
{
dst = ToPortableHandle(el.dst);
src = ToPortableHandle(el.src);
}
if(ser.IsStructurising() && rm)
{
dst.heap = rm->GetOriginalID(dst.heap);
src.heap = rm->GetOriginalID(src.heap);
}
ser.Serialise("dst"_lit, dst);
ser.Serialise("src"_lit, src);
@@ -287,8 +298,10 @@ void DoSerialise(SerialiserType &ser, D3D12BufferLocation &el)
ResourceId buffer;
UINT64 offs = 0;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
WrappedID3D12Resource1::GetResIDFromAddr(el.Location, buffer, offs);
if(ser.IsStructurising() && rm)
buffer = rm->GetOriginalID(buffer);
ser.Serialise("Buffer"_lit, buffer);
ser.Serialise("Offset"_lit, offs);
@@ -341,17 +354,21 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el)
}
case D3D12DescriptorType::SRV:
{
ser.Serialise("Resource"_lit, el.data.nonsamp.resource).TypedAs("ID3D12Resource *"_lit);
ResourceId Resource = el.data.nonsamp.resource;
if(ser.IsStructurising())
Resource = rm->GetOriginalID(Resource);
ser.Serialise("Resource"_lit, Resource).TypedAs("ID3D12Resource *"_lit);
// convert to Live ID on replay
if(ser.IsReading())
el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource)
? rm->GetLiveID(el.data.nonsamp.resource)
: ResourceId();
el.data.nonsamp.resource =
rm->HasLiveResource(Resource) ? rm->GetLiveID(Resource) : ResourceId();
// special case because of squeezed descriptor
D3D12_SHADER_RESOURCE_VIEW_DESC desc;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
desc = el.data.nonsamp.srv.AsDesc();
ser.Serialise("Descriptor"_lit, desc);
if(ser.IsReading())
@@ -360,35 +377,51 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el)
}
case D3D12DescriptorType::RTV:
{
ser.Serialise("Resource"_lit, el.data.nonsamp.resource).TypedAs("ID3D12Resource *"_lit);
ResourceId Resource = el.data.nonsamp.resource;
if(ser.IsStructurising())
Resource = rm->GetOriginalID(Resource);
ser.Serialise("Resource"_lit, Resource).TypedAs("ID3D12Resource *"_lit);
// convert to Live ID on replay
if(ser.IsReading())
el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource)
? rm->GetLiveID(el.data.nonsamp.resource)
: ResourceId();
el.data.nonsamp.resource =
rm->HasLiveResource(Resource) ? rm->GetLiveID(Resource) : ResourceId();
ser.Serialise("Descriptor"_lit, el.data.nonsamp.rtv);
break;
}
case D3D12DescriptorType::DSV:
{
ser.Serialise("Resource"_lit, el.data.nonsamp.resource).TypedAs("ID3D12Resource *"_lit);
ResourceId Resource = el.data.nonsamp.resource;
if(ser.IsStructurising())
Resource = rm->GetOriginalID(Resource);
ser.Serialise("Resource"_lit, Resource).TypedAs("ID3D12Resource *"_lit);
// convert to Live ID on replay
if(ser.IsReading())
el.data.nonsamp.resource = rm->HasLiveResource(el.data.nonsamp.resource)
? rm->GetLiveID(el.data.nonsamp.resource)
: ResourceId();
el.data.nonsamp.resource =
rm->HasLiveResource(Resource) ? rm->GetLiveID(Resource) : ResourceId();
ser.Serialise("Descriptor"_lit, el.data.nonsamp.dsv);
break;
}
case D3D12DescriptorType::UAV:
{
ser.Serialise("Resource"_lit, el.data.nonsamp.resource).TypedAs("ID3D12Resource *"_lit);
ser.Serialise("CounterResource"_lit, el.data.nonsamp.counterResource)
.TypedAs("ID3D12Resource *"_lit);
ResourceId Resource = el.data.nonsamp.resource;
ResourceId CounterResource = el.data.nonsamp.counterResource;
if(ser.IsStructurising())
{
Resource = rm->GetOriginalID(Resource);
CounterResource = rm->GetOriginalID(CounterResource);
}
ser.Serialise("Resource"_lit, Resource).TypedAs("ID3D12Resource *"_lit);
ser.Serialise("CounterResource"_lit, CounterResource).TypedAs("ID3D12Resource *"_lit);
// convert to Live ID on replay
if(ser.IsReading())
@@ -403,7 +436,7 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el)
// special case because of squeezed descriptor
D3D12_UNORDERED_ACCESS_VIEW_DESC desc;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
desc = el.data.nonsamp.uav.AsDesc();
ser.Serialise("Descriptor"_lit, desc);
if(ser.IsReading())
+11 -9
View File
@@ -237,6 +237,8 @@ void DoSerialiseViaResourceId(SerialiserType &ser, type &el)
if(ser.IsWriting() && rm)
id = GetResID(el);
if(ser.IsStructurising() && rm)
id = rm->GetOriginalID(GetResID(el));
DoSerialise(ser, id);
@@ -1297,7 +1299,7 @@ static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const voi
// this is the parent sType, serialised here for convenience
ser.Serialise("sType"_lit, sType);
if(ser.IsReading())
if(ser.IsReading() && !ser.IsStructurising())
{
// default to a NULL pNext
pNext = NULL;
@@ -4191,7 +4193,7 @@ void DoSerialise(SerialiserType &ser, ImageState &el)
SERIALISE_ELEMENT_LOCAL(imageInfo, el.GetImageInfo());
rdcarray<ImageSubresourceStateForRange> subresourceStates;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
{
el.subresourceStates.ToArray(subresourceStates);
}
@@ -4254,7 +4256,7 @@ void DoSerialise(SerialiserType &ser, VkDescriptorUpdateTemplateEntry &el)
{
uint64_t offset = 0;
uint64_t stride = 0;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
{
offset = el.offset;
stride = el.stride;
@@ -9279,7 +9281,7 @@ void DoSerialise(SerialiserType &ser, VkImportMemoryWin32HandleInfoKHR &el)
{
rdcstr name;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
name = el.name ? StringFormat::Wide2UTF8(el.name) : "";
ser.Serialise("name"_lit, name);
@@ -9317,7 +9319,7 @@ void DoSerialise(SerialiserType &ser, VkExportMemoryWin32HandleInfoKHR &el)
{
rdcstr name;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
name = el.name ? StringFormat::Wide2UTF8(el.name) : "";
ser.Serialise("name"_lit, name);
@@ -9386,7 +9388,7 @@ void DoSerialise(SerialiserType &ser, VkExportFenceWin32HandleInfoKHR &el)
{
rdcstr name;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
name = el.name ? StringFormat::Wide2UTF8(el.name) : "";
ser.Serialise("name"_lit, name);
@@ -9425,7 +9427,7 @@ void DoSerialise(SerialiserType &ser, VkImportFenceWin32HandleInfoKHR &el)
{
rdcstr name;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
name = el.name ? StringFormat::Wide2UTF8(el.name) : "";
ser.Serialise("name"_lit, name);
@@ -9479,7 +9481,7 @@ void DoSerialise(SerialiserType &ser, VkExportSemaphoreWin32HandleInfoKHR &el)
{
rdcstr name;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
name = el.name ? StringFormat::Wide2UTF8(el.name) : "";
ser.Serialise("name"_lit, name);
@@ -9518,7 +9520,7 @@ void DoSerialise(SerialiserType &ser, VkImportSemaphoreWin32HandleInfoKHR &el)
{
rdcstr name;
if(ser.IsWriting())
if(ser.IsWriting() || ser.IsStructurising())
name = el.name ? StringFormat::Wide2UTF8(el.name) : "";
ser.Serialise("name"_lit, name);
+8 -8
View File
@@ -86,6 +86,7 @@ class Serialiser
public:
static constexpr bool IsReading() { return sertype != SerialiserMode::Writing; }
static constexpr bool IsWriting() { return sertype == SerialiserMode::Writing; }
bool IsStructurising() const { return m_Structuriser; }
bool ExportStructure() const
{
// in debug builds, allow structured export during write for debugging. In release, only allow
@@ -116,7 +117,6 @@ public:
bool IsErrored() { return IsReading() ? m_Read->IsErrored() : m_Write->IsErrored(); }
void SetErrored() { IsReading() ? m_Read->SetErrored() : m_Write->SetErrored(); }
bool IsDummy() { return m_Dummy; }
StreamWriter *GetWriter() { return m_Write; }
StreamReader *GetReader() { return m_Read; }
uint32_t GetChunkMetadataRecording() { return m_ChunkFlags; }
@@ -300,7 +300,7 @@ public:
// ScopedDeseralise* classes. We can verify with e.g. valgrind that there are no leaks, so to keep
// the analysis non-spammy we just don't allocate for coverity builds
#if !defined(__COVERITY__)
if(!m_Dummy && (flags & SerialiserFlags::AllocateMemory))
if(!m_Structuriser && (flags & SerialiserFlags::AllocateMemory))
{
if(byteSize > 0)
el = AllocAlignedBuffer(byteSize);
@@ -621,7 +621,7 @@ public:
// ScopedDeseralise* classes. We can verify with e.g. valgrind that there are no leaks, so to keep
// the analysis non-spammy we just don't allocate for coverity builds
#if !defined(__COVERITY__)
if(IsReading() && !m_Dummy && (flags & SerialiserFlags::AllocateMemory))
if(IsReading() && !m_Structuriser && (flags & SerialiserFlags::AllocateMemory))
{
if(arrayCount > 0)
el = new T[(size_t)arrayCount];
@@ -668,7 +668,7 @@ public:
// ScopedDeseralise* classes. We can verify with e.g. valgrind that there are no leaks, so to keep
// the analysis non-spammy we just don't allocate for coverity builds
#if !defined(__COVERITY__)
if(IsReading() && !m_Dummy && (flags & SerialiserFlags::AllocateMemory))
if(IsReading() && !m_Structuriser && (flags & SerialiserFlags::AllocateMemory))
{
if(arrayCount > 0)
el = new T[(size_t)arrayCount];
@@ -1273,7 +1273,7 @@ protected:
template <SerialiserMode othertype>
friend class Serialiser;
void SetDummy(bool dummy) { m_Dummy = dummy; }
void SetStructuriser(bool s) { m_Structuriser = s; }
private:
static const uint64_t ChunkAlignment = 64;
template <class SerialiserMode, typename T, bool isEnum = std::is_enum<T>::value>
@@ -1345,7 +1345,7 @@ private:
ser.ConfigureStructuredExport(lookup, buffers, 0, 1.0);
ser.SetStreamingMode(true);
ser.SetDummy(true);
ser.SetStructuriser(true);
ser.SetUserData(userData);
ser.SetStringDatabase(stringDB);
@@ -1368,7 +1368,7 @@ private:
// See SetStreamingMode
bool m_DataStreaming = false;
bool m_DrawChunk = false;
bool m_Dummy = false;
bool m_Structuriser = false;
uint64_t m_LastChunkOffset = 0;
uint64_t m_ChunkFixup = 0;
@@ -1437,7 +1437,7 @@ public:
{
ConfigureStructuredExport(lookup, false, 0, 1.0);
SetStreamingMode(true);
SetDummy(true);
SetStructuriser(true);
}
};
#endif