diff --git a/renderdoc/api/replay/structured_data.h b/renderdoc/api/replay/structured_data.h index 148d23889..b0e4c8234 100644 --- a/renderdoc/api/replay/structured_data.h +++ b/renderdoc/api/replay/structured_data.h @@ -238,7 +238,7 @@ struct SDChunkMetaData DOCUMENT(R"(The length in bytes of this chunk - may be longer than the actual sum of the data if a conservative size estimate was used on creation to avoid seeking to fix-up the stored length. )"); - uint32_t length = 0; + uint64_t length = 0; DOCUMENT("The ID of the thread where this chunk was recorded."); uint64_t threadID = 0; diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index bc166e30e..9f1d3e4d3 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -573,7 +573,7 @@ protected: virtual bool AllowDeletedResource_InitialState() { return false; } virtual bool Need_InitialStateChunk(WrappedResourceType res) = 0; virtual bool Prepare_InitialState(WrappedResourceType res) = 0; - virtual uint32_t GetSize_InitialState(ResourceId id, WrappedResourceType res) = 0; + virtual uint64_t GetSize_InitialState(ResourceId id, WrappedResourceType res) = 0; virtual bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, WrappedResourceType res) = 0; virtual void Create_InitialState(ResourceId id, WrappedResourceType live, bool hasData) = 0; @@ -856,7 +856,7 @@ void ResourceManager::Serialise_InitialContentsNeeded(WriteSerial } } - uint32_t chunkSize = uint32_t(WrittenRecords.size() * sizeof(WrittenRecord) + 16); + uint64_t chunkSize = uint64_t(WrittenRecords.size() * sizeof(WrittenRecord) + 16); SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContentsList, chunkSize); SERIALISE_ELEMENT(WrittenRecords); @@ -1146,7 +1146,7 @@ void ResourceManager::InsertInitialContentsChunks(WriteSerialiser } else { - uint32_t size = GetSize_InitialState(id, res); + uint64_t size = GetSize_InitialState(id, res); SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContents, size); @@ -1175,7 +1175,7 @@ void ResourceManager::InsertInitialContentsChunks(WriteSerialiser } else { - uint32_t size = GetSize_InitialState(it->first, it->second); + uint64_t size = GetSize_InitialState(it->first, it->second); SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContents, size); diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 129096a90..dbb666989 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -494,7 +494,7 @@ public: // log replaying bool Prepare_InitialState(ID3D11DeviceChild *res); - uint32_t GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res); + uint64_t GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res); template bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, ID3D11DeviceChild *res); diff --git a/renderdoc/driver/d3d11/d3d11_initstate.cpp b/renderdoc/driver/d3d11/d3d11_initstate.cpp index 3056f3a36..170a4b562 100644 --- a/renderdoc/driver/d3d11/d3d11_initstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_initstate.cpp @@ -257,13 +257,13 @@ bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) return true; } -uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res) +uint64_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res) { // This function provides an upper bound on how much data Serialise_InitialState will write, so // that the chunk can be pre-allocated and not require seeking to fix-up the length. // It can be an over-estimate as long as it's not *too* far over. - uint32_t ret = 128; // type, Id, plus breathing room + uint64_t ret = 128; // type, Id, plus breathing room ResourcePitch pitch = {}; @@ -283,7 +283,7 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh // buffer width plus alignment ret += desc.ByteWidth; - ret += (uint32_t)WriteSerialiser::GetChunkAlignment(); + ret += WriteSerialiser::GetChunkAlignment(); } else if(type == Resource_Texture1D) { @@ -304,7 +304,7 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh const UINT RowPitch = GetRowPitch(desc.Width, desc.Format, mip); ret += RowPitch; - ret += (uint32_t)WriteSerialiser::GetChunkAlignment(); + ret += WriteSerialiser::GetChunkAlignment(); } } else if(type == Resource_Texture2D) @@ -344,7 +344,7 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ret += pitch.m_RowPitch * numRows; } - ret += (uint32_t)WriteSerialiser::GetChunkAlignment(); + ret += WriteSerialiser::GetChunkAlignment(); } } } @@ -373,7 +373,7 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh ret += pitch.m_DepthPitch * RDCMAX(1U, desc.Depth >> mip); } - ret += (uint32_t)WriteSerialiser::GetChunkAlignment(); + ret += WriteSerialiser::GetChunkAlignment(); } } else diff --git a/renderdoc/driver/d3d11/d3d11_manager.cpp b/renderdoc/driver/d3d11/d3d11_manager.cpp index 3d27c65df..b3d591504 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.cpp +++ b/renderdoc/driver/d3d11/d3d11_manager.cpp @@ -87,7 +87,7 @@ bool D3D11ResourceManager::Prepare_InitialState(ID3D11DeviceChild *res) return m_Device->Prepare_InitialState(res); } -uint32_t D3D11ResourceManager::GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res) +uint64_t D3D11ResourceManager::GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res) { return m_Device->GetSize_InitialState(id, res); } diff --git a/renderdoc/driver/d3d11/d3d11_manager.h b/renderdoc/driver/d3d11/d3d11_manager.h index 7000422ed..dabe6803a 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.h +++ b/renderdoc/driver/d3d11/d3d11_manager.h @@ -262,7 +262,7 @@ private: bool Force_InitialState(ID3D11DeviceChild *res, bool prepare); bool Need_InitialStateChunk(ID3D11DeviceChild *res); bool Prepare_InitialState(ID3D11DeviceChild *res); - uint32_t GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res); + uint64_t GetSize_InitialState(ResourceId id, ID3D11DeviceChild *res); bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, ID3D11DeviceChild *res); void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); void Apply_InitialState(ID3D11DeviceChild *live, D3D11InitialContents data); diff --git a/renderdoc/driver/d3d12/d3d12_initstate.cpp b/renderdoc/driver/d3d12/d3d12_initstate.cpp index 84e369a6c..35cdc7a45 100644 --- a/renderdoc/driver/d3d12/d3d12_initstate.cpp +++ b/renderdoc/driver/d3d12/d3d12_initstate.cpp @@ -347,7 +347,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) return false; } -uint32_t D3D12ResourceManager::GetSize_InitialState(ResourceId id, ID3D12DeviceChild *res) +uint64_t D3D12ResourceManager::GetSize_InitialState(ResourceId id, ID3D12DeviceChild *res) { D3D12ResourceRecord *record = GetResourceRecord(id); D3D12InitialContents initContents = GetInitialContents(id); @@ -355,7 +355,7 @@ uint32_t D3D12ResourceManager::GetSize_InitialState(ResourceId id, ID3D12DeviceC if(record->type == Resource_DescriptorHeap) { // the initial contents are just the descriptors. Estimate the serialise size here - const uint32_t descriptorSerSize = 40 + sizeof(D3D12_SAMPLER_DESC); + const uint64_t descriptorSerSize = 40 + sizeof(D3D12_SAMPLER_DESC); // add a little extra room for fixed overhead return 64 + initContents.numDescriptors * descriptorSerSize; @@ -369,8 +369,7 @@ uint32_t D3D12ResourceManager::GetSize_InitialState(ResourceId id, ID3D12DeviceC buf = (ID3D12Resource *)res; } - return (uint32_t)WriteSerialiser::GetChunkAlignment() + 16 + - uint32_t(buf ? buf->GetDesc().Width : 0); + return WriteSerialiser::GetChunkAlignment() + 16 + uint64_t(buf ? buf->GetDesc().Width : 0); } else { diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 48c4959ff..49d9f99aa 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -716,7 +716,7 @@ private: bool Force_InitialState(ID3D12DeviceChild *res, bool prepare); bool Need_InitialStateChunk(ID3D12DeviceChild *res); bool Prepare_InitialState(ID3D12DeviceChild *res); - uint32_t GetSize_InitialState(ResourceId id, ID3D12DeviceChild *res); + uint64_t GetSize_InitialState(ResourceId id, ID3D12DeviceChild *res); bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, ID3D12DeviceChild *res) { return Serialise_InitialState(ser, resid, res); diff --git a/renderdoc/driver/d3d8/d3d8_manager.cpp b/renderdoc/driver/d3d8/d3d8_manager.cpp index 96a41ce70..66420a6d6 100644 --- a/renderdoc/driver/d3d8/d3d8_manager.cpp +++ b/renderdoc/driver/d3d8/d3d8_manager.cpp @@ -61,7 +61,7 @@ bool D3D8ResourceManager::Prepare_InitialState(IUnknown *res) return false; } -uint32_t D3D8ResourceManager::GetSize_InitialState(ResourceId id, IUnknown *res) +uint64_t D3D8ResourceManager::GetSize_InitialState(ResourceId id, IUnknown *res) { // TODO return 128; diff --git a/renderdoc/driver/d3d8/d3d8_manager.h b/renderdoc/driver/d3d8/d3d8_manager.h index b8fd29583..2aca56d46 100644 --- a/renderdoc/driver/d3d8/d3d8_manager.h +++ b/renderdoc/driver/d3d8/d3d8_manager.h @@ -77,7 +77,7 @@ private: bool Force_InitialState(IUnknown *res, bool prepare); bool Need_InitialStateChunk(IUnknown *res); bool Prepare_InitialState(IUnknown *res); - uint32_t GetSize_InitialState(ResourceId id, IUnknown *res); + uint64_t GetSize_InitialState(ResourceId id, IUnknown *res); bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, IUnknown *res); void Create_InitialState(ResourceId id, IUnknown *live, bool hasData); void Apply_InitialState(IUnknown *live, D3D8InitialContents data); diff --git a/renderdoc/driver/gl/gl_initstate.cpp b/renderdoc/driver/gl/gl_initstate.cpp index d056a319c..e2fad78f0 100644 --- a/renderdoc/driver/gl/gl_initstate.cpp +++ b/renderdoc/driver/gl/gl_initstate.cpp @@ -1037,13 +1037,12 @@ bool GLResourceManager::Force_InitialState(GLResource res, bool prepare) return false; } -uint32_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource res) +uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource res) { if(res.Namespace == eResBuffer) { // buffers just have their contents, no metadata needed - return GetInitialContents(resid).bufferLength + (uint32_t)WriteSerialiser::GetChunkAlignment() + - 16; + return GetInitialContents(resid).bufferLength + WriteSerialiser::GetChunkAlignment() + 16; } else if(res.Namespace == eResProgram) { @@ -1061,11 +1060,11 @@ uint32_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource re SerialiseProgramBindings(ser, CaptureState::ActiveCapturing, res.name); SerialiseProgramUniforms(ser, CaptureState::ActiveCapturing, res.name, NULL); - return (uint32_t)ser.GetWriter()->GetOffset() + 256; + return ser.GetWriter()->GetOffset() + 256; } else if(res.Namespace == eResTexture) { - uint32_t ret = 0; + uint64_t ret = 0; ret += sizeof(TextureStateInitialData) + 64; @@ -1112,7 +1111,7 @@ uint32_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource re targetcount = 6; for(int t = 0; t < targetcount; t++) - ret += (uint32_t)WriteSerialiser::GetChunkAlignment() + size; + ret += WriteSerialiser::GetChunkAlignment() + size; } return ret; diff --git a/renderdoc/driver/gl/gl_manager.h b/renderdoc/driver/gl/gl_manager.h index 7929cd243..68b582c50 100644 --- a/renderdoc/driver/gl/gl_manager.h +++ b/renderdoc/driver/gl/gl_manager.h @@ -259,7 +259,7 @@ private: bool Force_InitialState(GLResource res, bool prepare); bool Need_InitialStateChunk(GLResource res); bool Prepare_InitialState(GLResource res); - uint32_t GetSize_InitialState(ResourceId resid, GLResource res); + uint64_t GetSize_InitialState(ResourceId resid, GLResource res); void CreateTextureImage(GLuint tex, GLenum internalFormat, GLenum internalFormatHint, GLenum textype, GLint dim, GLint width, GLint height, GLint depth, diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 9b525300d..3245af2c8 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -32,7 +32,7 @@ #include "stb/stb_image_write.h" -uint32_t VkInitParams::GetSerialiseSize() +uint64_t VkInitParams::GetSerialiseSize() { // misc bytes and fixed integer members size_t ret = 128; @@ -45,7 +45,7 @@ uint32_t VkInitParams::GetSerialiseSize() for(const std::string &s : Extensions) ret += 8 + s.size(); - return (uint32_t)ret; + return (uint64_t)ret; } void VkInitParams::Set(const VkInstanceCreateInfo *pCreateInfo, ResourceId inst) diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 32395e274..f9b82fbf5 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -52,7 +52,7 @@ struct VkInitParams ResourceId InstanceID; // remember to update this function if you add more members - uint32_t GetSerialiseSize(); + uint64_t GetSerialiseSize(); // check if a frame capture section version is supported static const uint64_t CurrentVersion = 0xF; @@ -916,8 +916,8 @@ public: VulkanReplay *GetReplay() { return &m_Replay; } // replay interface bool Prepare_InitialState(WrappedVkRes *res); - uint32_t GetSize_InitialState(ResourceId id, WrappedVkRes *res); - uint32_t GetSize_SparseInitialState(ResourceId id, WrappedVkRes *res); + uint64_t GetSize_InitialState(ResourceId id, WrappedVkRes *res); + uint64_t GetSize_SparseInitialState(ResourceId id, WrappedVkRes *res); template bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, WrappedVkRes *res); void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 244427271..8e171070c 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -623,7 +623,7 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res) return false; } -uint32_t WrappedVulkan::GetSize_InitialState(ResourceId id, WrappedVkRes *res) +uint64_t WrappedVulkan::GetSize_InitialState(ResourceId id, WrappedVkRes *res) { VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); VkResourceType type = IdentifyTypeByPtr(record->Resource); @@ -652,7 +652,7 @@ uint32_t WrappedVulkan::GetSize_InitialState(ResourceId id, WrappedVkRes *res) return GetSize_SparseInitialState(id, res); // the size primarily comes from the buffer, the size of which we conveniently have stored. - return uint32_t(128 + initContents.mem.size + WriteSerialiser::GetChunkAlignment()); + return uint64_t(128 + initContents.mem.size + WriteSerialiser::GetChunkAlignment()); } RDCERR("Unhandled resource type %s", ToStr(type).c_str()); diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index 48fbeb16f..18b2eede8 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -738,7 +738,7 @@ bool VulkanResourceManager::Prepare_InitialState(WrappedVkRes *res) return m_Core->Prepare_InitialState(res); } -uint32_t VulkanResourceManager::GetSize_InitialState(ResourceId id, WrappedVkRes *res) +uint64_t VulkanResourceManager::GetSize_InitialState(ResourceId id, WrappedVkRes *res) { return m_Core->GetSize_InitialState(id, res); } diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 343365ba3..f25c77422 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -439,7 +439,7 @@ private: bool AllowDeletedResource_InitialState() { return true; } bool Need_InitialStateChunk(WrappedVkRes *res); bool Prepare_InitialState(WrappedVkRes *res); - uint32_t GetSize_InitialState(ResourceId id, WrappedVkRes *res); + uint64_t GetSize_InitialState(ResourceId id, WrappedVkRes *res); bool Serialise_InitialState(WriteSerialiser &ser, ResourceId resid, WrappedVkRes *res); void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); void Apply_InitialState(WrappedVkRes *live, VkInitialContents initial); diff --git a/renderdoc/driver/vulkan/vk_sparse_initstate.cpp b/renderdoc/driver/vulkan/vk_sparse_initstate.cpp index c7b6504ed..b606bdc9b 100644 --- a/renderdoc/driver/vulkan/vk_sparse_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_sparse_initstate.cpp @@ -359,7 +359,7 @@ bool WrappedVulkan::Prepare_SparseInitialState(WrappedVkImage *im) return true; } -uint32_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes *res) +uint64_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes *res) { VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); VkResourceType type = IdentifyTypeByPtr(record->Resource); @@ -370,7 +370,7 @@ uint32_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes * SparseBufferInitState &info = contents.sparseBuffer; // some bytes just to cover overheads etc. - uint32_t ret = 128; + uint64_t ret = 128; // the list of memory objects bound ret += 8 + sizeof(VkSparseMemoryBind) * info.numBinds; @@ -379,7 +379,7 @@ uint32_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes * ret += 8 + sizeof(MemIDOffset) * info.numUniqueMems; // the actual data - ret += uint32_t(info.totalSize + WriteSerialiser::GetChunkAlignment()); + ret += uint64_t(info.totalSize + WriteSerialiser::GetChunkAlignment()); return ret; } @@ -388,7 +388,7 @@ uint32_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes * SparseImageInitState &info = contents.sparseImage; // some bytes just to cover overheads etc. - uint32_t ret = 128; + uint64_t ret = 128; // the meta-data structure ret += sizeof(SparseImageInitState); @@ -404,7 +404,7 @@ uint32_t WrappedVulkan::GetSize_SparseInitialState(ResourceId id, WrappedVkRes * ret += sizeof(MemIDOffset) * info.numUniqueMems; // the actual data - ret += uint32_t(info.totalSize + WriteSerialiser::GetChunkAlignment()); + ret += uint64_t(info.totalSize + WriteSerialiser::GetChunkAlignment()); return ret; } diff --git a/renderdoc/serialise/rdcfile.cpp b/renderdoc/serialise/rdcfile.cpp index 17a22438b..d3b3c1738 100644 --- a/renderdoc/serialise/rdcfile.cpp +++ b/renderdoc/serialise/rdcfile.cpp @@ -319,7 +319,7 @@ void RDCFile::Init(StreamReader &reader) m_SerVer = header.version; - if(m_SerVer != SERIALISE_VERSION) + if(m_SerVer != SERIALISE_VERSION && m_SerVer != V1_0_VERSION) { if(header.version < V1_0_VERSION) { diff --git a/renderdoc/serialise/rdcfile.h b/renderdoc/serialise/rdcfile.h index bb2a4f206..2959d0767 100644 --- a/renderdoc/serialise/rdcfile.h +++ b/renderdoc/serialise/rdcfile.h @@ -61,11 +61,12 @@ public: // version number of overall file format or chunk organisation. If the contents/meaning/order of // chunks have changed this does not need to be bumped, there are version numbers within each // API that interprets the stream that can be bumped. - static const uint32_t SERIALISE_VERSION = 0x00000100; + static const uint32_t SERIALISE_VERSION = 0x00000101; // this must never be changed - files before this were in the v0.x series and didn't have embedded // version numbers static const uint32_t V1_0_VERSION = 0x00000100; + static const uint32_t V1_1_VERSION = 0x00000101; ~RDCFile(); diff --git a/renderdoc/serialise/serialiser.cpp b/renderdoc/serialise/serialiser.cpp index f3ac37edd..5157b0d8e 100644 --- a/renderdoc/serialise/serialiser.cpp +++ b/renderdoc/serialise/serialiser.cpp @@ -60,7 +60,7 @@ Serialiser::~Serialiser() } template <> -uint32_t Serialiser::BeginChunk(uint32_t, uint32_t) +uint32_t Serialiser::BeginChunk(uint32_t, uint64_t) { uint32_t chunkID = 0; @@ -100,7 +100,16 @@ uint32_t Serialiser::BeginChunk(uint32_t, uint32_t) if(c & ChunkTimestamp) m_Read->Read(m_ChunkMetadata.timestampMicro); - m_Read->Read(m_ChunkMetadata.length); + if(c & Chunk64BitSize) + { + m_Read->Read(m_ChunkMetadata.length); + } + else + { + uint32_t chunkSize = 0; + m_Read->Read(chunkSize); + m_ChunkMetadata.length = chunkSize; + } m_LastChunkOffset = m_Read->GetOffset(); } @@ -260,7 +269,7 @@ void Serialiser::SetChunkMetadataRecording(uint32_t fla } template <> -uint32_t Serialiser::BeginChunk(uint32_t chunkID, uint32_t byteLength) +uint32_t Serialiser::BeginChunk(uint32_t chunkID, uint64_t byteLength) { { // chunk index needs to be valid @@ -271,6 +280,8 @@ uint32_t Serialiser::BeginChunk(uint32_t chunkID, uint3 RDCASSERT(chunkID <= ChunkIndexMask); c |= m_ChunkFlags; + if(byteLength > 0xffffffff) + c |= Chunk64BitSize; m_ChunkMetadata.chunkID = chunkID; @@ -334,13 +345,23 @@ uint32_t Serialiser::BeginChunk(uint32_t chunkID, uint3 { // write length, assuming it is an upper bound m_ChunkFixup = 0; - m_Write->Write(byteLength); + RDCASSERT(byteLength < 0x100000000 || (c & Chunk64BitSize) != 0); + if(c & Chunk64BitSize) + { + m_Write->Write(byteLength); + } + else + { + m_Write->Write(uint32_t(byteLength & 0xffffffff)); + } m_LastChunkOffset = m_Write->GetOffset(); m_ChunkMetadata.length = byteLength; } else { // length will be fixed up in EndChunk + // assume that this case will not produce chunks with size larger than can fit in 32 bit + // value uint32_t chunkSize = 0xbeebfeed; m_ChunkFixup = m_Write->GetOffset(); m_Write->Write(chunkSize); @@ -371,12 +392,13 @@ void Serialiser::EndChunk() RDCASSERT(curOffset > chunkOffset); uint64_t chunkLength = (curOffset - chunkOffset) - sizeof(uint32_t); + if(chunkLength > 0xffffffff) + { + RDCERR("!!! CHUNK LENGTH %llu EXCEEDED 32 BIT VALUE. CAPTURE WILL BE CORRUPTED. !!!", + chunkLength); + } - RDCASSERT(chunkLength < 0xffffffff); - - uint32_t chunklen = (uint32_t)chunkLength; - - m_Write->WriteAt(chunkOffset, chunklen); + m_Write->WriteAt(chunkOffset, uint32_t(chunkLength & 0xffffffff)); } else { @@ -393,21 +415,21 @@ void Serialiser::EndChunk() m_Write->Write(padByte); } - RDCDEBUG("Chunk estimated at %u bytes, actual length %llu. Added %llu bytes padding.", + RDCDEBUG("Chunk estimated at %llu bytes, actual length %llu. Added %llu bytes padding.", m_ChunkMetadata.length, writtenLength, numPadBytes); } else if(writtenLength > m_ChunkMetadata.length) { RDCERR( "!!! " - "ESTIMATED UPPER BOUND CHUNK LENGTH %u EXCEEDED: %llu. " + "ESTIMATED UPPER BOUND CHUNK LENGTH %llu EXCEEDED: %llu. " "CAPTURE WILL BE CORRUPTED. " "!!!", m_ChunkMetadata.length, writtenLength); } else { - RDCDEBUG("Chunk was exactly the estimate of %u bytes.", m_ChunkMetadata.length); + RDCDEBUG("Chunk was exactly the estimate of %llu bytes.", m_ChunkMetadata.length); } } diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index fbb8f29cd..4a93461dc 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -100,6 +100,7 @@ public: ChunkThreadID = 0x00020000, ChunkDuration = 0x00040000, ChunkTimestamp = 0x00080000, + Chunk64BitSize = 0x00100000, }; ////////////////////////////////////////// @@ -156,7 +157,7 @@ public: m_ExportStructured = (lookup != NULL); } - uint32_t BeginChunk(uint32_t chunkID, uint32_t byteLength); + uint32_t BeginChunk(uint32_t chunkID, uint64_t byteLength); void EndChunk(); std::string GetCurChunkName() @@ -1632,7 +1633,7 @@ class WriteSerialiser : public Serialiser { public: WriteSerialiser(StreamWriter *writer, Ownership own) : Serialiser(writer, own) {} - void WriteChunk(uint32_t chunkID, uint32_t byteLength = 0) { BeginChunk(chunkID, byteLength); } + void WriteChunk(uint32_t chunkID, uint64_t byteLength = 0) { BeginChunk(chunkID, byteLength); } }; class ReadSerialiser : public Serialiser @@ -1833,7 +1834,7 @@ class ScopedChunk { public: template - ScopedChunk(WriteSerialiser &s, ChunkType i, uint32_t byteLength = 0) + ScopedChunk(WriteSerialiser &s, ChunkType i, uint64_t byteLength = 0) : m_Idx(uint32_t(i)), m_Ser(s), m_Ended(false) { m_Ser.WriteChunk(m_Idx, byteLength);