From 89562b66dfe916e41378ea87d14b071ee79e8a09 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Tue, 7 Mar 2023 00:25:28 -0500 Subject: [PATCH] Small VBO opts --- indra/llrender/llrender.cpp | 9 +++++---- indra/llrender/llvertexbuffer.cpp | 16 ++++++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 931c22bbac5..9ab8d166c0c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -86,7 +86,7 @@ struct LLVBCache std::chrono::steady_clock::time_point touched; }; -static std::unordered_map<U64, LLVBCache> sVBCache; +static boost::unordered_flat_map<U64, LLVBCache> sVBCache; static const GLenum sGLTextureType[] = { @@ -1720,7 +1720,7 @@ void LLRender::flush() // To leverage this, we maintain a running hash of the vertex stream being // built up before a flush, and then check that hash against a VB // cache just before creating a vertex buffer in VRAM - std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash); + auto cache = sVBCache.find(vhash); LLPointer<LLVertexBuffer> vb; @@ -1765,11 +1765,12 @@ void LLRender::flush() using namespace std::chrono_literals; // every 1024 misses, clean the cache of any VBs that haven't been touched in the last second - for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); ) + for (auto iter = sVBCache.begin(); iter != sVBCache.end(); ) { if (now - iter->second.touched > 1s) { - iter = sVBCache.erase(iter); + auto old_iter = iter++; + sVBCache.erase(old_iter); } else { diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index b2267c7c479..c7fcce2381e 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -307,7 +307,7 @@ class LLVBOPool clear(); } - typedef std::unordered_map<U32, std::list<Entry>> Pool; + typedef boost::unordered_flat_map<U32, std::list<Entry>> Pool; Pool mVBOPool; Pool mIBOPool; @@ -447,12 +447,13 @@ class LLVBOPool LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - std::unordered_map<U32, std::list<Entry>>* pools[] = { &mVBOPool, &mIBOPool }; + boost::unordered_flat_map<U32, std::list<Entry>>* pools[] = { &mVBOPool, &mIBOPool }; using namespace std::chrono_literals; Time cutoff = std::chrono::steady_clock::now() - 5s; + std::vector<GLuint> names_to_free; for (auto* pool : pools) { for (Pool::iterator iter = pool->begin(); iter != pool->end(); ) @@ -464,7 +465,7 @@ class LLVBOPool LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vbo cache timeout"); auto& entry = entries.back(); ll_aligned_free_16(entry.mData); - glDeleteBuffers(1, &entry.mGLName); + names_to_free.push_back(entry.mGLName); #if ANALYZE_VBO_POOL llassert(mReserved >= iter->first); mReserved -= iter->first; @@ -475,7 +476,7 @@ class LLVBOPool if (entries.empty()) { - iter = pool->erase(iter); + pool->erase(iter++); } else { @@ -483,6 +484,7 @@ class LLVBOPool } } } + if(!names_to_free.empty()) glDeleteBuffers(names_to_free.size(), names_to_free.data()); #if ANALYZE_VBO_POOL LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent", @@ -497,12 +499,13 @@ class LLVBOPool void clear() { + std::vector<GLuint> names_to_free; for (auto& entries : mIBOPool) { for (auto& entry : entries.second) { ll_aligned_free_16(entry.mData); - glDeleteBuffers(1, &entry.mGLName); + names_to_free.push_back(entry.mGLName); } } @@ -511,9 +514,10 @@ class LLVBOPool for (auto& entry : entries.second) { ll_aligned_free_16(entry.mData); - glDeleteBuffers(1, &entry.mGLName); + names_to_free.push_back(entry.mGLName); } } + if(!names_to_free.empty()) glDeleteBuffers(names_to_free.size(), names_to_free.data()); #if ANALYZE_VBO_POOL mReserved = 0; -- GitLab