mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-11-15 10:20:07 +00:00
Make it possible to write chunks larger than 4 GB
Added a special chunk flag indicating that chunk size is a 64 bit value. This allows to handle larger chunks (which heppens quite rarely) while still maintaining backward compatibility with the majority of traces. Bumped RDC file version of 0x101 (1.1) to make sure older version cannot read the new file format.
This commit is contained in:
1 parent
cfa5dd3ea5
commit
ca2307e34c
22 files changed
+81
-59
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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<Configuration>::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<Configuration>::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<Configuration>::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);
|
||||
|
||||
|
||||
@@ -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 <typename SerialiserType>
|
||||
bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, ID3D11DeviceChild *res);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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<WriteSerialiser>(ser, resid, res);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <typename SerialiserType>
|
||||
bool Serialise_InitialState(SerialiserType &ser, ResourceId resid, WrappedVkRes *res);
|
||||
void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Serialiser<SerialiserMode::Reading>::~Serialiser()
|
||||
}
|
||||
|
||||
template <>
|
||||
uint32_t Serialiser<SerialiserMode::Reading>::BeginChunk(uint32_t, uint32_t)
|
||||
uint32_t Serialiser<SerialiserMode::Reading>::BeginChunk(uint32_t, uint64_t)
|
||||
{
|
||||
uint32_t chunkID = 0;
|
||||
|
||||
@@ -100,7 +100,16 @@ uint32_t Serialiser<SerialiserMode::Reading>::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<SerialiserMode::Writing>::SetChunkMetadataRecording(uint32_t fla
|
||||
}
|
||||
|
||||
template <>
|
||||
uint32_t Serialiser<SerialiserMode::Writing>::BeginChunk(uint32_t chunkID, uint32_t byteLength)
|
||||
uint32_t Serialiser<SerialiserMode::Writing>::BeginChunk(uint32_t chunkID, uint64_t byteLength)
|
||||
{
|
||||
{
|
||||
// chunk index needs to be valid
|
||||
@@ -271,6 +280,8 @@ uint32_t Serialiser<SerialiserMode::Writing>::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<SerialiserMode::Writing>::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<SerialiserMode::Writing>::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<SerialiserMode::Writing>::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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<SerialiserMode::Writing>
|
||||
{
|
||||
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<SerialiserMode::Reading>
|
||||
@@ -1833,7 +1834,7 @@ class ScopedChunk
|
||||
{
|
||||
public:
|
||||
template <typename ChunkType>
|
||||
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);
|
||||
|
||||
Reference in new issue
Block a user