Avoid pointless multiple file passes, now that seeking isn't cheap

This commit is contained in:
baldurk
2015-09-18 22:37:44 +02:00
parent b090092d73
commit 1b8d291874
3 changed files with 63 additions and 94 deletions
+12 -34
View File
@@ -1001,8 +1001,7 @@ void WrappedID3D11Device::Serialise_CaptureScope(uint64_t offset)
void WrappedID3D11Device::ReadLogInitialisation()
{
uint64_t lastFrame = 0;
uint64_t firstFrame = 0;
uint64_t frameOffset = 0;
LazyInit();
@@ -1010,28 +1009,6 @@ void WrappedID3D11Device::ReadLogInitialisation()
m_pSerialiser->Rewind();
uint32_t captureChunkIdx = 0;
while(!m_pSerialiser->AtEnd())
{
m_pSerialiser->SkipToChunk(CAPTURE_SCOPE, &captureChunkIdx);
// found a capture chunk
if(!m_pSerialiser->AtEnd())
{
lastFrame = m_pSerialiser->GetOffset();
if(firstFrame == 0)
firstFrame = m_pSerialiser->GetOffset();
// skip this chunk
m_pSerialiser->PushContext(NULL, CAPTURE_SCOPE, false);
m_pSerialiser->SkipCurrentChunk();
m_pSerialiser->PopContext(NULL, CAPTURE_SCOPE);
}
}
m_pSerialiser->Rewind();
int chunkIdx = 0;
struct chunkinfo
@@ -1053,6 +1030,12 @@ void WrappedID3D11Device::ReadLogInitialisation()
uint64_t offset = m_pSerialiser->GetOffset();
D3D11ChunkType context = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, 1, false);
if(context == CAPTURE_SCOPE)
{
// immediately read rest of log into memory
m_pSerialiser->SetPersistentBlock(offset);
}
chunkIdx++;
@@ -1060,10 +1043,12 @@ void WrappedID3D11Device::ReadLogInitialisation()
m_pSerialiser->PopContext(NULL, context);
RenderDoc::Inst().SetProgress(FileInitialRead, float(chunkIdx)/float(captureChunkIdx));
RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize()));
if(context == CAPTURE_SCOPE)
{
frameOffset = offset;
GetResourceManager()->ApplyInitialContents();
m_pImmediateContext->ReplayLog(READING, 0, 0, false);
@@ -1076,15 +1061,10 @@ void WrappedID3D11Device::ReadLogInitialisation()
chunkInfos[context].count++;
if(context == CAPTURE_SCOPE)
{
if(m_pSerialiser->GetOffset() > lastFrame)
break;
}
break;
if(m_pSerialiser->AtEnd())
{
break;
}
}
for(auto it=chunkInfos.begin(); it != chunkInfos.end(); ++it)
@@ -1100,11 +1080,9 @@ void WrappedID3D11Device::ReadLogInitialisation()
);
}
RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - firstFrame);
RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - frameOffset);
m_pSerialiser->SetDebugText(false);
m_pSerialiser->SetPersistentBlock(firstFrame);
}
bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res)
+12 -34
View File
@@ -2850,35 +2850,12 @@ void WrappedOpenGL::DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum sev
void WrappedOpenGL::ReadLogInitialisation()
{
uint64_t lastFrame = 0;
uint64_t firstFrame = 0;
uint64_t frameOffset = 0;
m_pSerialiser->SetDebugText(true);
m_pSerialiser->Rewind();
uint32_t captureChunkIdx = 0;
while(!m_pSerialiser->AtEnd())
{
m_pSerialiser->SkipToChunk(CAPTURE_SCOPE, &captureChunkIdx);
// found a capture chunk
if(!m_pSerialiser->AtEnd())
{
lastFrame = m_pSerialiser->GetOffset();
if(firstFrame == 0)
firstFrame = m_pSerialiser->GetOffset();
// skip this chunk
m_pSerialiser->PushContext(NULL, CAPTURE_SCOPE, false);
m_pSerialiser->SkipCurrentChunk();
m_pSerialiser->PopContext(NULL, CAPTURE_SCOPE);
}
}
m_pSerialiser->Rewind();
int chunkIdx = 0;
struct chunkinfo
@@ -2900,6 +2877,12 @@ void WrappedOpenGL::ReadLogInitialisation()
uint64_t offset = m_pSerialiser->GetOffset();
GLChunkType context = (GLChunkType)m_pSerialiser->PushContext(NULL, 1, false);
if(context == CAPTURE_SCOPE)
{
// immediately read rest of log into memory
m_pSerialiser->SetPersistentBlock(offset);
}
chunkIdx++;
@@ -2907,10 +2890,12 @@ void WrappedOpenGL::ReadLogInitialisation()
m_pSerialiser->PopContext(NULL, context);
RenderDoc::Inst().SetProgress(FileInitialRead, float(chunkIdx)/float(captureChunkIdx));
RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize()));
if(context == CAPTURE_SCOPE)
{
frameOffset = offset;
GetResourceManager()->ApplyInitialContents();
ContextReplayLog(READING, 0, 0, false);
@@ -2923,15 +2908,10 @@ void WrappedOpenGL::ReadLogInitialisation()
chunkInfos[context].count++;
if(context == CAPTURE_SCOPE)
{
if(m_pSerialiser->GetOffset() > lastFrame)
break;
}
break;
if(m_pSerialiser->AtEnd())
{
break;
}
}
for(auto it=chunkInfos.begin(); it != chunkInfos.end(); ++it)
@@ -2947,11 +2927,9 @@ void WrappedOpenGL::ReadLogInitialisation()
);
}
RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - firstFrame);
RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - frameOffset);
m_pSerialiser->SetDebugText(false);
m_pSerialiser->SetPersistentBlock(firstFrame);
}
void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
+39 -26
View File
@@ -1116,37 +1116,50 @@ void Serialiser::FreeAlignedBuffer(byte *buf)
void Serialiser::SetPersistentBlock(uint64_t offs)
{
// as long as this is called immediately after pushing the chunk context at the
// offset, we will always have the start in memory, as we keep 64 bytes of
// a backwards window even if we had to shift the currently in-memory bytes
// while reading the chunk header
RDCASSERT(m_ReadOffset <= offs);
// also can't persistent block ahead of where we are
RDCASSERT(offs < (m_BufferHead - m_Buffer) + m_ReadOffset);
// ensure sane offset
RDCASSERT(offs < m_BufferSize);
size_t persistentSize = (size_t)(m_BufferSize - offs);
// allocate our persistent buffer
byte *newBuf = AllocAlignedBuffer(persistentSize);
// save where buffer head was as file-offset
uint64_t prevOffs = uint64_t(m_BufferHead - m_Buffer) + m_ReadOffset;
// find the range of the persistent block that we have in memory
byte *persistentBase = m_Buffer + (offs - m_ReadOffset);
size_t persistentInMemory = RDCMIN(persistentSize, size_t(m_CurrentBufferSize - (offs - m_ReadOffset)));
memcpy(newBuf, persistentBase, persistentInMemory);
FreeAlignedBuffer(m_Buffer);
RDCASSERT(m_BufferSize - offs < 0xffffffff);
m_CurrentBufferSize = (size_t)(m_BufferSize - offs);
m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize);
m_CurrentBufferSize = persistentSize;
m_Buffer = newBuf;
m_ReadOffset = offs;
// set the head back to where it was
m_BufferHead = m_Buffer + (prevOffs - offs);
// if we didn't read everything, read the rest
if(persistentInMemory < persistentSize)
{
ReadFromFile(persistentInMemory, persistentSize - persistentInMemory);
}
RDCASSERT(m_ReadFileHandle);
Section *s = m_KnownSections[eSectionType_FrameCapture];
RDCASSERT(s);
FileIO::fseek64(m_ReadFileHandle, s->fileoffset, SEEK_SET);
if(s->flags & eSectionFlag_LZ4Compressed)
{
RDCASSERT(s->compressedReader);
s->compressedReader->Reset();
}
// can't seek arbitrarily in the stream, need to read through the rest
while(offs > 0)
{
// read at most buffer size at a time.
size_t chunkSize = RDCMIN(m_CurrentBufferSize, (size_t)offs);
ReadFromFile(0, chunkSize);
offs -= chunkSize;
}
// now read the rest
ReadFromFile(0, m_CurrentBufferSize);
// close the file handle
FileIO::fclose(m_ReadFileHandle);
m_ReadFileHandle = 0;
}