From ae0c745656a6483fa33349d536024a5982a33cd5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 10 Oct 2019 14:52:23 +0100 Subject: [PATCH] Don't clear important data when using StructuredSerialiser --- renderdoc/driver/d3d12/d3d12_serialise.cpp | 6 +++--- renderdoc/serialise/serialiser.h | 21 +++++++++++++++------ renderdoc/serialise/streamio.h | 6 ++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index 3b14512cb..d399e4259 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -130,7 +130,7 @@ void DoSerialise(SerialiserType &ser, D3D12_CPU_DESCRIPTOR_HANDLE &el) if(rm) el.ptr = (SIZE_T)DescriptorFromPortableHandle(rm, ph); else - el.ptr = 0; + ser.ClearObj(el.ptr); } } @@ -151,7 +151,7 @@ void DoSerialise(SerialiserType &ser, D3D12_GPU_DESCRIPTOR_HANDLE &el) if(rm) el.ptr = (SIZE_T)DescriptorFromPortableHandle(rm, ph); else - el.ptr = 0; + ser.ClearObj(el.ptr); } } @@ -207,7 +207,7 @@ void DoSerialise(SerialiserType &ser, D3D12BufferLocation &el) if(rm && buffer != ResourceId() && rm->HasLiveResource(buffer)) el.Location = rm->GetLiveAs(buffer)->GetGPUVirtualAddress() + offs; else - el.Location = 0; + ser.ClearObj(el.Location); } } diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index f94076688..db14f54a0 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -188,6 +188,13 @@ public: } } + template + void ClearObj(T &el) + { + if(IsReading()) + m_Read->Clear(&el, sizeof(T)); + } + // serialise an object (either loose, or a structure member). template Serialiser &Serialise(const rdcliteral &name, T &el, @@ -1912,9 +1919,12 @@ struct ScopedDeserialiseArray GET_SERIALISER, obj); \ GET_SERIALISER.Serialise(STRING_LITERAL(#obj), obj) +// for _TYPED serialises, we need to first clear the object to 0 since the typed alias might not +// write it all. This is mostly only when co-oercing a BOOL type to bool, where only one byte gets +// written. We go via ClearObj() so that when StructuredSerialiser is in use and the reader is a +// dummy, it can skip the write. #define SERIALISE_ELEMENT_TYPED(type, obj) \ - if(ser.IsReading()) \ - obj = decltype(obj)(); \ + ser.ClearObj(obj); \ union \ { \ type *t; \ @@ -1948,8 +1958,7 @@ struct ScopedDeserialiseArray #define SERIALISE_MEMBER(obj) ser.Serialise(STRING_LITERAL(#obj), el.obj) #define SERIALISE_MEMBER_TYPED(type, obj) \ - if(ser.IsReading()) \ - el.obj = decltype(el.obj)(); \ + ser.ClearObj(el.obj); \ union \ { \ type *t; \ @@ -1962,8 +1971,8 @@ struct ScopedDeserialiseArray ser.Serialise(STRING_LITERAL(#arrayObj), el.arrayObj, el.countObj, SerialiserFlags::AllocateMemory) #define SERIALISE_MEMBER_ARRAY_TYPED(type, arrayObj, countObj) \ - if(ser.IsReading()) \ - el.arrayObj = NULL; \ + RDCCOMPILE_ASSERT(sizeof(*el.arrayObj) == sizeof(type), \ + "Array serialised co-erced type must be identically sized"); \ union \ { \ type **t; \ diff --git a/renderdoc/serialise/streamio.h b/renderdoc/serialise/streamio.h index 321af97a4..27bae84bf 100644 --- a/renderdoc/serialise/streamio.h +++ b/renderdoc/serialise/streamio.h @@ -118,6 +118,12 @@ public: return true; } + void Clear(void *data, size_t numBytes) + { + if(!m_Dummy) + memset(data, 0, numBytes); + } + bool Read(void *data, uint64_t numBytes) { if(numBytes == 0 || m_Dummy)