mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-13 21:40:41 +00:00
Add util function to align serialised buffers in chunks. Refs #133
* To align a buffer inside a chunk to a wider boundary like 32-bytes in this case, the chunk needs to be aligned and the buffer within it also needs to be aligned. * The utility function accounts for the buffer serialised having a uint32 length in front of it, so it pads out until that will be at the desired boundary. This is a bit of a messy solution, but the easiest way to ensure the padding is there while being easily backwards compatible with old logs without the padding. * D3D11 and GL serialise versions are bumped, D3D11 version is backwards compatible, GL breaks compatibility.
This commit is contained in:
@@ -171,6 +171,12 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pD
|
||||
|
||||
byte *padding = m_State >= WRITING ? new byte[ResourceBufLen] : NULL;
|
||||
|
||||
// this is a bit of a hack, but to maintain backwards compatibility we have a
|
||||
// separate function here that aligns the next serialised buffer to a 32-byte
|
||||
// boundary in memory while writing (just skips the padding on read).
|
||||
if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007)
|
||||
m_pSerialiser->AlignNextBuffer(32);
|
||||
|
||||
SERIALISE_ELEMENT_BUF(byte *, bufData, padding, ResourceBufLen);
|
||||
|
||||
if(record)
|
||||
|
||||
@@ -7024,6 +7024,12 @@ bool WrappedID3D11DeviceContext::Serialise_Unmap(ID3D11Resource *pResource, UINT
|
||||
m_pSerialiser->Serialise("DiffStart", diffStart);
|
||||
m_pSerialiser->Serialise("DiffEnd", diffEnd);
|
||||
|
||||
// this is a bit of a hack, but to maintain backwards compatibility we have a
|
||||
// separate function here that aligns the next serialised buffer to a 32-byte
|
||||
// boundary in memory while writing (just skips the padding on read).
|
||||
if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007)
|
||||
m_pSerialiser->AlignNextBuffer(32);
|
||||
|
||||
byte *buf = (byte *)intercept.app.pData;
|
||||
m_pSerialiser->SerialiseBuffer("MapData", buf, len);
|
||||
|
||||
|
||||
@@ -206,6 +206,7 @@ D3D11InitParams::D3D11InitParams()
|
||||
const uint32_t D3D11InitParams::D3D11_OLD_VERSIONS[D3D11InitParams::D3D11_NUM_SUPPORTED_OLD_VERSIONS] = {
|
||||
0x0000004, // from 0x4 to 0x5, we added the stream-out hidden counters in the context's Serialise_BeginCaptureFrame
|
||||
0x0000005, // from 0x5 to 0x6, several new calls were made 'drawcalls', like Copy & GenerateMips, with serialised debug messages
|
||||
0x0000006, // from 0x6 to 0x7, we added some more padding in some buffer & texture chunks to get larger alignment than 16-byte
|
||||
};
|
||||
|
||||
ReplayCreateStatus D3D11InitParams::Serialise()
|
||||
|
||||
@@ -66,10 +66,10 @@ struct D3D11InitParams : public RDCInitParams
|
||||
UINT NumFeatureLevels;
|
||||
D3D_FEATURE_LEVEL FeatureLevels[16];
|
||||
|
||||
static const uint32_t D3D11_SERIALISE_VERSION = 0x0000006;
|
||||
static const uint32_t D3D11_SERIALISE_VERSION = 0x0000007;
|
||||
|
||||
// backwards compatibility for old logs described at the declaration of this array
|
||||
static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 2;
|
||||
static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 3;
|
||||
static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS];
|
||||
|
||||
// version number internal to d3d11 stream
|
||||
|
||||
@@ -44,6 +44,12 @@ bool WrappedID3D11Device::Serialise_CreateBuffer(
|
||||
pInitialData = &fakeData;
|
||||
}
|
||||
|
||||
// this is a bit of a hack, but to maintain backwards compatibility we have a
|
||||
// separate function here that aligns the next serialised buffer to a 32-byte
|
||||
// boundary in memory while writing (just skips the padding on read).
|
||||
if(m_State >= WRITING || GetLogVersion() >= 0x000007)
|
||||
m_pSerialiser->AlignNextBuffer(32);
|
||||
|
||||
SERIALISE_ELEMENT_BUF(byte *, InitialData, pInitialData->pSysMem, Descriptor.ByteWidth);
|
||||
|
||||
uint64_t offs = m_pSerialiser->GetOffset()-Descriptor.ByteWidth;
|
||||
@@ -261,6 +267,12 @@ vector<D3D11_SUBRESOURCE_DATA> WrappedID3D11Device::Serialise_CreateTextureData(
|
||||
intercept.CopyFromD3D();
|
||||
}
|
||||
|
||||
// this is a bit of a hack, but to maintain backwards compatibility we have a
|
||||
// separate function here that aligns the next serialised buffer to a 32-byte
|
||||
// boundary in memory while writing (just skips the padding on read).
|
||||
if(m_State >= WRITING || GetLogVersion() >= 0x000007)
|
||||
m_pSerialiser->AlignNextBuffer(32);
|
||||
|
||||
SERIALISE_ELEMENT_BUF(byte *, buf, scratch, subresourceSize);
|
||||
|
||||
if(m_State >= WRITING)
|
||||
|
||||
@@ -55,7 +55,7 @@ struct GLInitParams : public RDCInitParams
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
static const uint32_t GL_SERIALISE_VERSION = 0x000000C;
|
||||
static const uint32_t GL_SERIALISE_VERSION = 0x000000D;
|
||||
|
||||
// version number internal to opengl stream
|
||||
uint32_t SerialiseVersion;
|
||||
|
||||
@@ -309,6 +309,9 @@ bool WrappedOpenGL::Serialise_glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr
|
||||
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)));
|
||||
SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size);
|
||||
|
||||
// for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT
|
||||
m_pSerialiser->AlignNextBuffer(64);
|
||||
|
||||
SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize);
|
||||
|
||||
uint64_t offs = m_pSerialiser->GetOffset();
|
||||
@@ -424,6 +427,9 @@ bool WrappedOpenGL::Serialise_glNamedBufferDataEXT(GLuint buffer, GLsizeiptr siz
|
||||
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)));
|
||||
SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size);
|
||||
|
||||
// for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT
|
||||
m_pSerialiser->AlignNextBuffer(64);
|
||||
|
||||
SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize);
|
||||
|
||||
if(m_State == WRITING_CAPFRAME && id.id == 22)
|
||||
|
||||
@@ -940,6 +940,36 @@ void Serialiser::SkipBuffer()
|
||||
ReadBytes(len);
|
||||
}
|
||||
|
||||
void Serialiser::AlignNextBuffer(const size_t alignment)
|
||||
{
|
||||
// this is a super hack but it's the easiest way to align a buffer to a larger pow2 alignment
|
||||
// than the default 16-bytes, while still able to be backwards compatible with old logs that
|
||||
// weren't so aligned. We know that SerialiseBuffer will align to the nearest 16-byte boundary
|
||||
// after serialising 4 bytes of length, so we pad up to exactly 4 bytes before the desired
|
||||
// alignment, then after the 4 byte length there's nothing for the other padding to do.
|
||||
//
|
||||
// Note the chunk still needs to be aligned when the memory is allocated - this just ensures
|
||||
// the offset from the start is also aligned
|
||||
|
||||
size_t len = 0;
|
||||
|
||||
if(m_Mode >= WRITING)
|
||||
{
|
||||
// add sizeof(uint32_t) since we'll be serialising out how much padding is here
|
||||
uint64_t curoffs = GetOffset() + sizeof(uint32_t);
|
||||
uint64_t alignedoffs = AlignUp(curoffs, (uint64_t)alignment);
|
||||
|
||||
len = size_t(alignedoffs - curoffs);
|
||||
}
|
||||
|
||||
// avoid dynamically allocating
|
||||
RDCASSERT(alignment <= 128);
|
||||
byte padding[128] = {0};
|
||||
byte *p = &padding[0];
|
||||
|
||||
SerialiseBuffer("", p, len);
|
||||
}
|
||||
|
||||
void Serialiser::SerialiseBuffer(const char *name, byte *&buf, size_t &len)
|
||||
{
|
||||
uint32_t bufLen = (uint32_t)len;
|
||||
|
||||
@@ -487,6 +487,7 @@ class Serialiser
|
||||
// memory will be returned, or it must be already large enough.
|
||||
void SerialiseBuffer(const char *name, byte *&buf, size_t &len);
|
||||
void SkipBuffer();
|
||||
void AlignNextBuffer(const size_t alignment);
|
||||
|
||||
// NOT recommended interface. Useful for specific situations if e.g. you have
|
||||
// a buffer of data that is not arbitrary in size and can be determined by a 'type' or
|
||||
|
||||
Reference in New Issue
Block a user