summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-04-02 00:33:03 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-04-03 02:12:38 +0300
commit210a6a8eb4499b86f548f7afdc90f1660c117f9c (patch)
tree5d6c830652802ceb8a44a0718701aa24bc73d6d4
parentde5ff4f6548e377043b534957b34f2b3298e339e (diff)
#5602 deleteProbe optimization pass
glGenQueries synchronizes cpu with gpu, which is expensive
-rw-r--r--indra/newview/llreflectionmap.cpp5
-rw-r--r--indra/newview/llreflectionmapmanager.cpp34
-rw-r--r--indra/newview/llreflectionmapmanager.h7
3 files changed, 44 insertions, 2 deletions
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index 7f5076bd56..f4f3e39f17 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -45,7 +45,8 @@ LLReflectionMap::~LLReflectionMap()
{
if (mOcclusionQuery)
{
- glDeleteQueries(1, &mOcclusionQuery);
+ gPipeline.mReflectionMapManager.recycleQuery(mOcclusionQuery);
+ mOcclusionQuery = 0;
}
}
@@ -341,7 +342,7 @@ void LLReflectionMap::doOcclusion(const LLVector4a& eye)
if (mOcclusionQuery == 0)
{ // no query was previously issued, allocate one and issue
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - glGenQueries");
- glGenQueries(1, &mOcclusionQuery);
+ mOcclusionQuery = gPipeline.mReflectionMapManager.allocateQuery();
do_query = true;
}
else
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index c6fa64753c..d2e37fb40a 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -523,6 +523,7 @@ void LLReflectionMapManager::refreshSettings()
mRenderReflectionProbeLevel = gSavedSettings.getS32("RenderReflectionProbeLevel");
mRenderReflectionProbeCount = gSavedSettings.getU32("RenderReflectionProbeCount");
mRenderReflectionProbeDynamicAllocation = gSavedSettings.getS32("RenderReflectionProbeDynamicAllocation");
+ cleanupQueryPool();
}
LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
@@ -570,6 +571,25 @@ U32 LLReflectionMapManager::probeMemory()
return (mDynamicProbeCount * 6 * (mProbeResolution * mProbeResolution) * 4) / 1024 / 1024 + (mDynamicProbeCount * 6 * (LL_IRRADIANCE_MAP_RESOLUTION * LL_IRRADIANCE_MAP_RESOLUTION) * 4) / 1024 / 1024;
}
+GLuint LLReflectionMapManager::allocateQuery()
+{
+ if (mQueryPool.empty())
+ {
+ GLuint query;
+ glGenQueries(1, &query);
+ return query;
+ }
+
+ GLuint query = mQueryPool.front();
+ mQueryPool.pop_front();
+ return query;
+}
+
+void LLReflectionMapManager::recycleQuery(GLuint query)
+{
+ mQueryPool.push_back(query);
+}
+
struct CompareProbeDepth
{
bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs)
@@ -713,6 +733,7 @@ void LLReflectionMapManager::deleteProbe(U32 i)
other->mNeighbors.erase(iter);
}
+ // Probes are distance sorted, order matters.
mProbes.erase(mProbes.begin() + i);
}
@@ -1549,10 +1570,23 @@ void LLReflectionMapManager::cleanup()
glDeleteBuffers(1, &mUBO);
mUBO = 0;
+ cleanupQueryPool();
+
// note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state
initCubeFree();
}
+void LLReflectionMapManager::cleanupQueryPool()
+{
+ if (!mQueryPool.empty())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("cleanup query pool");
+ std::vector<GLuint> queries(mQueryPool.begin(), mQueryPool.end());
+ glDeleteQueries(static_cast<GLsizei>(queries.size()), queries.data());
+ mQueryPool.clear();
+ }
+}
+
void LLReflectionMapManager::doOcclusion()
{
LLVector4a eye;
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
index 5daed7d1cf..1e1f9ad1a2 100644
--- a/indra/newview/llreflectionmapmanager.h
+++ b/indra/newview/llreflectionmapmanager.h
@@ -106,6 +106,7 @@ public:
// release any GL state
void cleanup();
+ void cleanupQueryPool();
// maintain reflection probes
void update();
@@ -164,6 +165,10 @@ public:
U32 probeCount();
U32 probeMemory();
+ // glDeleteQueries is expensive, so we maintain a pool of queries
+ GLuint allocateQuery();
+ void recycleQuery(GLuint query);
+
private:
friend class LLPipeline;
friend class LLHeroProbeManager;
@@ -190,6 +195,8 @@ private:
// bind UBO used for rendering
void setUniforms();
+ std::deque<GLuint> mQueryPool;
+
// render target for cube snapshots
// used to generate mipmaps without doing a copy-to-texture
LLRenderTarget mRenderTarget;