From 5724bbd8e96a69e5ba3afd0ef4078855f0693807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 3 May 2023 23:03:34 +0200 Subject: [PATCH] Correct size calculations in GLPushBuffer. I don't see how this failed as badly as in that crash report though... --- Common/GPU/OpenGL/GLRenderManager.cpp | 23 ++++++++++++++++++----- Common/GPU/OpenGL/GLRenderManager.h | 1 + 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index da1efe7e2624..48b2f4dd339a 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -589,6 +589,7 @@ bool GLPushBuffer::AddBuffer() { if (!info.localMemory) return false; info.buffer = render_->CreateBuffer(target_, size_, GL_DYNAMIC_DRAW); + info.size = size_; buf_ = buffers_.size(); buffers_.push_back(info); return true; @@ -605,7 +606,6 @@ void GLPushBuffer::Destroy(bool onRenderThread) { } else { render_->DeleteBuffer(info.buffer); } - FreeAlignedMemory(info.localMemory); } buffers_.clear(); @@ -652,18 +652,31 @@ void GLPushBuffer::Defragment() { } // Okay, we have more than one. Destroy them all and start over with a larger one. - size_t newSize = size_ * buffers_.size(); + + // When calling AddBuffer, we sometimes increase size_. So if we allocated multiple buffers in a frame, + // they won't all have the same size. Sum things up properly. + size_t newSize = 0; + for (int i = 0; i < (int)buffers_.size(); i++) { + newSize += buffers_[i].size; + } + Destroy(false); - size_ = newSize; + // Set some sane but very free limits. If there's another spike, we'll just allocate more anyway. + size_ = std::min(std::max(newSize, (size_t)65536), (size_t)(512 * 1024 * 1024)); bool res = AddBuffer(); _assert_msg_(res, "AddBuffer failed"); } size_t GLPushBuffer::GetTotalSize() const { size_t sum = 0; - if (buffers_.size() > 1) - sum += size_ * (buffers_.size() - 1); + // When calling AddBuffer, we sometimes increase size_. So if we allocated multiple buffers in a frame, + // they won't all have the same size. Sum things up properly. + if (buffers_.size() > 1) { + for (int i = 0; i < (int)buffers_.size() - 1; i++) { + sum += buffers_[i].size; + } + } sum += offset_; return sum; } diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index 07f54ffab40c..f06724a6cbef 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -242,6 +242,7 @@ class GLPushBuffer { uint8_t *localMemory = nullptr; uint8_t *deviceMemory = nullptr; size_t flushOffset = 0; + size_t size; }; GLPushBuffer(GLRenderManager *render, GLuint target, size_t size);