From e0464fea4f9a7f149c4ee1d84e5ac57839a4a862 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 19 May 2023 09:58:49 +0100 Subject: [PATCH] Don't call ReadLargeBuffer for socket reads * In ReadLargeBuffer we read directly into an external buffer with ReadExternal, but for sockets when reading externally we want to read ahead of the current spot (non-blocking) as much as possible to batch small reads together. Rather than making ReadExternal handle or detect reads to external buffers, we instead avoid ReadLargeBuffer as it is an optimisation for direct I/O to avoid unnecessary memcpy's and is not relevant for sockets. --- renderdoc/serialise/streamio.cpp | 11 ++++++++++- renderdoc/serialise/streamio.h | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/renderdoc/serialise/streamio.cpp b/renderdoc/serialise/streamio.cpp index cb6c8b95a..21e35d18b 100644 --- a/renderdoc/serialise/streamio.cpp +++ b/renderdoc/serialise/streamio.cpp @@ -270,7 +270,7 @@ bool StreamReader::Reserve(uint64_t numBytes) bool StreamReader::ReadLargeBuffer(void *buffer, uint64_t length) { - RDCASSERT(m_Sock || m_File || m_Decompressor); + RDCASSERT(m_File || m_Decompressor); byte *dest = (byte *)buffer; @@ -398,6 +398,9 @@ bool StreamReader::ReadFromExternal(void *buffer, uint64_t length) // first get the required data blocking (this will sleep the thread until it comes in). byte *readDest = (byte *)buffer; + // we expect to be reading into our window buffer + RDCASSERT(readDest >= m_BufferBase && readDest <= m_BufferBase + m_BufferSize); + success = m_Sock->RecvDataBlocking(readDest, (uint32_t)length); if(success) @@ -407,6 +410,12 @@ bool StreamReader::ReadFromExternal(void *buffer, uint64_t length) uint32_t bufSize = uint32_t(m_BufferSize - m_InputSize); + if(m_InputSize > m_BufferSize) + { + bufSize = 0; + RDCERR("Invalid read in ReadFromExternal!"); + } + // now read more, as much as possible, to try and batch future reads success = m_Sock->RecvDataNonBlocking(readDest, bufSize); diff --git a/renderdoc/serialise/streamio.h b/renderdoc/serialise/streamio.h index ae1b0bc8a..fa232ae10 100644 --- a/renderdoc/serialise/streamio.h +++ b/renderdoc/serialise/streamio.h @@ -180,7 +180,9 @@ public: // and larger by just skating over the limit each time, but that's fine because the main // case we want to catch is a window that's only a few MB and then suddenly we read 100s of // MB. - if(numBytes >= 10 * 1024 * 1024 && Available() + 128 < numBytes) + // We don't do this on sockets since we want to opportunistically read more into the window + // to batch lots of small reads together. + if(m_Sock == NULL && numBytes >= 10 * 1024 * 1024 && Available() + 128 < numBytes) { success = ReadLargeBuffer(data, numBytes); alreadyread = true;