From 0d6aa3c0fe184ae00899304cb3f71315f5c73314 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 17 Feb 2022 22:52:23 +0000 Subject: SL-16815 Remove frame stalls from occlusion queries, bumpmap updates, and querying for available video memory. --- indra/newview/llvieweroctree.cpp | 93 ++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 28 deletions(-) (limited to 'indra/newview/llvieweroctree.cpp') diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 3cdef0ebff..65e9fa533d 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -787,42 +787,73 @@ void LLViewerOctreeGroup::checkStates() //occulsion culling functions and classes //------------------------------------------------------------------------------------------- std::set LLOcclusionCullingGroup::sPendingQueries; -class LLOcclusionQueryPool : public LLGLNamePool + +static std::queue sFreeQueries; + +U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() { -public: - LLOcclusionQueryPool() - { - } + LL_PROFILE_ZONE_SCOPED; + // TODO: refactor this to a general purpose name pool + static GLuint occlusion_queries[2][1024]; + static std::atomic query_count[2]; + static S32 query_page = -1; + + //reuse any query names that have been freed + if (!sFreeQueries.empty()) + { + GLuint ret = sFreeQueries.front(); + sFreeQueries.pop(); + return ret; + } -protected: + // first call, immediately fill entire name pool + if (query_page == -1) + { + glGenQueriesARB(1024, occlusion_queries[0]); + glGenQueriesARB(1024, occlusion_queries[1]); + query_page = 0; + query_count[0] = 1024; + query_count[1] = 1024; + } - virtual GLuint allocateName() - { - GLuint ret = 0; + if (query_count[query_page] == 0) //this page is empty + { + //check the other page + query_page = (query_page + 1) % 2; - glGenQueriesARB(1, &ret); - - return ret; - } + if (query_count[query_page] == 0) + { + //the other page is also empty, generate immediately and return + GLuint ret; + glGenQueriesARB(1, &ret); + return ret; + } + } - virtual void releaseName(GLuint name) - { -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - LLOcclusionCullingGroup::sPendingQueries.erase(name); -#endif - glDeleteQueriesARB(1, &name); - } -}; + GLuint ret = occlusion_queries[query_page][--query_count[query_page]]; -static LLOcclusionQueryPool sQueryPool; -U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() -{ - return sQueryPool.allocate(); + if (query_count[query_page] == 0) + { //exhausted this page, replenish on background thread + S32 page = query_page; + LL::WorkQueue::postMaybe(LL::WorkQueue::getInstance("LLImageGL"), + [=]() + { + LL_PROFILE_ZONE_NAMED("glGenQueries bg"); + if (query_count[page] == 0) // <-- protect against redundant attempts to replenish + { + glGenQueriesARB(1024, occlusion_queries[page]); + query_count[page] = 1024; + glFlush(); + } + }); + } + + return ret; } void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name) { - sQueryPool.release(name); + sFreeQueries.push(name); } //===================================== @@ -1243,7 +1274,10 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh //store which frame this query was issued on mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; - glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + { + LL_PROFILE_ZONE_NAMED("glBeginQuery"); + glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + } LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; llassert(shader); @@ -1282,7 +1316,10 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh } } - glEndQueryARB(mode); + { + LL_PROFILE_ZONE_NAMED("glEndQuery"); + glEndQueryARB(mode); + } } } -- cgit v1.3 From 7c90b82ff772df4f8e200ef83c2ecf577b6bdec0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 18 Feb 2022 15:37:55 -0600 Subject: SL-16815 Better occlusion query name pool. Leverage pool FILO nature to avoid reusing a query while the GPU is still chewing on it. --- indra/newview/llvieweroctree.cpp | 70 ++++++++++++---------------------------- 1 file changed, 20 insertions(+), 50 deletions(-) (limited to 'indra/newview/llvieweroctree.cpp') diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 65e9fa533d..5eda75753e 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -790,70 +790,36 @@ std::set LLOcclusionCullingGroup::sPendingQueries; static std::queue sFreeQueries; +#define QUERY_POOL_SIZE 1024 + U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() { LL_PROFILE_ZONE_SCOPED; - // TODO: refactor this to a general purpose name pool - static GLuint occlusion_queries[2][1024]; - static std::atomic query_count[2]; - static S32 query_page = -1; - //reuse any query names that have been freed - if (!sFreeQueries.empty()) + if (sFreeQueries.empty()) { - GLuint ret = sFreeQueries.front(); - sFreeQueries.pop(); - return ret; - } - - // first call, immediately fill entire name pool - if (query_page == -1) - { - glGenQueriesARB(1024, occlusion_queries[0]); - glGenQueriesARB(1024, occlusion_queries[1]); - query_page = 0; - query_count[0] = 1024; - query_count[1] = 1024; - } - - if (query_count[query_page] == 0) //this page is empty - { - //check the other page - query_page = (query_page + 1) % 2; - - if (query_count[query_page] == 0) + //seed 1024 query names into the free query pool + GLuint queries[1024]; + glGenQueriesARB(1024, queries); + for (int i = 0; i < 1024; ++i) { - //the other page is also empty, generate immediately and return - GLuint ret; - glGenQueriesARB(1, &ret); - return ret; + sFreeQueries.push(queries[i]); } } - GLuint ret = occlusion_queries[query_page][--query_count[query_page]]; - - if (query_count[query_page] == 0) - { //exhausted this page, replenish on background thread - S32 page = query_page; - LL::WorkQueue::postMaybe(LL::WorkQueue::getInstance("LLImageGL"), - [=]() - { - LL_PROFILE_ZONE_NAMED("glGenQueries bg"); - if (query_count[page] == 0) // <-- protect against redundant attempts to replenish - { - glGenQueriesARB(1024, occlusion_queries[page]); - query_count[page] = 1024; - glFlush(); - } - }); - } - + // pull from pool + GLuint ret = sFreeQueries.front(); + sFreeQueries.pop(); return ret; } void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name) { - sFreeQueries.push(name); + if (name != 0) + { + LL_PROFILE_ZONE_SCOPED; + sFreeQueries.push(name); + } } //===================================== @@ -1276,6 +1242,10 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh { LL_PROFILE_ZONE_NAMED("glBeginQuery"); + + //get an occlusion query that hasn't been used in awhile + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName(); glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); } -- cgit v1.3