diff --git a/renderdoc/driver/d3d11/d3d11_postvs.cpp b/renderdoc/driver/d3d11/d3d11_postvs.cpp index bd618ccb6..f523db932 100644 --- a/renderdoc/driver/d3d11/d3d11_postvs.cpp +++ b/renderdoc/driver/d3d11/d3d11_postvs.cpp @@ -324,8 +324,7 @@ void D3D11Replay::InitPostVSBuffers(uint32_t eventId) if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize < outputSize) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu", oldSize, m_SOBufferSize); CreateSOBuffers(); @@ -439,8 +438,7 @@ void D3D11Replay::InitPostVSBuffers(uint32_t eventId) if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize < outputSize) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu", oldSize, m_SOBufferSize); CreateSOBuffers(); if(!m_SOStagingBuffer) @@ -777,11 +775,12 @@ void D3D11Replay::InitPostVSBuffers(uint32_t eventId) sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); } while(hr == S_FALSE); - if(m_SOBufferSize < stride * numPrims.PrimitivesStorageNeeded * 3) + uint64_t outputSize = stride * numPrims.PrimitivesStorageNeeded * 3; + + if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize < stride * numPrims.PrimitivesStorageNeeded * 3) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu", oldSize, m_SOBufferSize); CreateSOBuffers(); if(!m_SOStagingBuffer) @@ -900,7 +899,7 @@ void D3D11Replay::InitPostVSBuffers(uint32_t eventId) (uint32_t)bytesWritten, D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0, 0, 0, }; - if(bytesWritten >= m_SOBufferSize) + if(bytesWritten > m_SOBufferSize) { RDCERR("Generated output data too large: %08x", bufferDesc.ByteWidth); diff --git a/renderdoc/driver/d3d12/d3d12_postvs.cpp b/renderdoc/driver/d3d12/d3d12_postvs.cpp index afd60cd5f..092114eb4 100644 --- a/renderdoc/driver/d3d12/d3d12_postvs.cpp +++ b/renderdoc/driver/d3d12/d3d12_postvs.cpp @@ -329,8 +329,7 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId) if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize < outputSize) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu for output data", oldSize, m_SOBufferSize); recreate = true; @@ -434,11 +433,12 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId) indexRemap[indices[i]] = i; } - if(m_SOBufferSize / sizeof(Vec4f) < indices.size() * sizeof(uint32_t)) + outputSize = uint64_t(indices.size() * sizeof(uint32_t) * sizeof(Vec4f)); + + if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize / sizeof(Vec4f) < indices.size() * sizeof(uint32_t)) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu for indices", oldSize, m_SOBufferSize); recreate = true; } @@ -886,11 +886,12 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId) range.End = 0; m_SOStagingBuffer->Unmap(0, &range); - if(m_SOBufferSize < data->PrimitivesStorageNeeded * 3 * stride) + uint64_t outputSize = data->PrimitivesStorageNeeded * 3 * stride; + + if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize < data->PrimitivesStorageNeeded * 3 * stride) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu for output", oldSize, m_SOBufferSize); CreateSOBuffers(); } @@ -1025,11 +1026,12 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId) D3D12_QUERY_DATA_SO_STATISTICS *data; hr = m_SOStagingBuffer->Map(0, &range, (void **)&data); - if(m_SOBufferSize < data->PrimitivesStorageNeeded * 3 * stride) + uint64_t outputSize = data->PrimitivesStorageNeeded * 3 * stride; + + if(m_SOBufferSize < outputSize) { uint64_t oldSize = m_SOBufferSize; - while(m_SOBufferSize < data->PrimitivesStorageNeeded * 3 * stride) - m_SOBufferSize *= 2; + m_SOBufferSize = CalcMeshOutputSize(m_SOBufferSize, outputSize); RDCWARN("Resizing stream-out buffer from %llu to %llu for output", oldSize, m_SOBufferSize); CreateSOBuffers(); diff --git a/renderdoc/driver/gl/gl_postvs.cpp b/renderdoc/driver/gl/gl_postvs.cpp index f5eb8435f..5783b2002 100644 --- a/renderdoc/driver/gl/gl_postvs.cpp +++ b/renderdoc/driver/gl/gl_postvs.cpp @@ -375,8 +375,7 @@ void GLReplay::InitPostVSBuffers(uint32_t eventId) if(DebugData.feedbackBufferSize < outputSize) { uint64_t oldSize = DebugData.feedbackBufferSize; - while(DebugData.feedbackBufferSize < outputSize) - DebugData.feedbackBufferSize *= 2; + DebugData.feedbackBufferSize = CalcMeshOutputSize(DebugData.feedbackBufferSize, outputSize); RDCWARN("Resizing xfb buffer from %llu to %llu for output", oldSize, DebugData.feedbackBufferSize); if(DebugData.feedbackBufferSize > INTPTR_MAX) @@ -495,8 +494,7 @@ void GLReplay::InitPostVSBuffers(uint32_t eventId) if(DebugData.feedbackBufferSize < outputSize) { uint64_t oldSize = DebugData.feedbackBufferSize; - while(DebugData.feedbackBufferSize < outputSize) - DebugData.feedbackBufferSize *= 2; + DebugData.feedbackBufferSize = CalcMeshOutputSize(DebugData.feedbackBufferSize, outputSize); RDCWARN("Resizing xfb buffer from %llu to %llu for output", oldSize, DebugData.feedbackBufferSize); if(DebugData.feedbackBufferSize > INTPTR_MAX) @@ -1051,8 +1049,8 @@ void GLReplay::InitPostVSBuffers(uint32_t eventId) if(DebugData.feedbackBufferSize < maxOutputSize) { uint64_t oldSize = DebugData.feedbackBufferSize; - while(DebugData.feedbackBufferSize < maxOutputSize) - DebugData.feedbackBufferSize *= 2; + DebugData.feedbackBufferSize = + CalcMeshOutputSize(DebugData.feedbackBufferSize, maxOutputSize); RDCWARN("Conservatively resizing xfb buffer from %llu to %llu for output", oldSize, DebugData.feedbackBufferSize); if(DebugData.feedbackBufferSize > INTPTR_MAX) diff --git a/renderdoc/replay/replay_driver.cpp b/renderdoc/replay/replay_driver.cpp index 986020782..cb31df4a3 100644 --- a/renderdoc/replay/replay_driver.cpp +++ b/renderdoc/replay/replay_driver.cpp @@ -207,6 +207,20 @@ void PatchLineStripIndexBuffer(const DrawcallDescription *draw, uint8_t *idx8, u #undef IDX_VALUE } +uint64_t CalcMeshOutputSize(uint64_t curSize, uint64_t requiredOutput) +{ + // resize exponentially up to 256MB to avoid repeated resizes + while(curSize < requiredOutput && curSize < 0x10000000ULL) + curSize *= 2; + + // after that, just align the required size up to 16MB and allocate that. Otherwise we can + // vastly-overallocate at large sizes. + if(curSize < requiredOutput) + curSize = AlignUp(requiredOutput, 0x1000000ULL); + + return curSize; +} + FloatVector HighlightCache::InterpretVertex(const byte *data, uint32_t vert, const MeshDisplay &cfg, const byte *end, bool useidx, bool &valid) { diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 08e1f883d..f596f21c5 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -236,6 +236,8 @@ DrawcallDescription *SetupDrawcallPointers(std::vector &d void PatchLineStripIndexBuffer(const DrawcallDescription *draw, uint8_t *idx8, uint16_t *idx16, uint32_t *idx32, std::vector &patchedIndices); +uint64_t CalcMeshOutputSize(uint64_t curSize, uint64_t requiredOutput); + // simple cache for when we need buffer data for highlighting // vertices, typical use will be lots of vertices in the same // mesh, not jumping back and forth much between meshes.