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:
Alex Vakulenko authored and Baldur Karlsson committed 2019-05-10 10:25:26 -07:00
1 parent cfa5dd3ea5
commit ca2307e34c
22 files changed
+81 -59

No files matched your search

+1 -1
View File
@@ -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;
+4 -4
View File
@@ -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);
+1 -1
View File
@@ -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);
+6 -6
View File
@@ -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
+1 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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);
+3 -4
View File
@@ -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
{
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+5 -6
View File
@@ -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;
+1 -1
View File
@@ -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,
+2 -2
View File
@@ -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)
+3 -3
View File
@@ -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);
+2 -2
View File
@@ -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());
+1 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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)
{
+2 -1
View File
@@ -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();
+34 -12
View File
@@ -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);
}
}
+4 -3
View File
@@ -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);