From d316ca1665a14b77a487c1292f6a8f5ae039d289 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Mon, 13 Dec 2021 16:27:07 -0500
Subject: [PATCH] Fix dummy vao bind upon vbo recreation

---
 indra/llrender/llrender.cpp       | 25 -------------------------
 indra/llrender/llrender.h         |  2 --
 indra/llrender/llvertexbuffer.cpp | 30 ++++++++++++++++++++++++++++++
 indra/llrender/llvertexbuffer.h   |  1 +
 indra/newview/pipeline.cpp        |  3 ++-
 5 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 12a8443d7fe..81e1eaf36ac 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1085,7 +1085,6 @@ LLRender::LLRender()
     mMode(LLRender::TRIANGLES),
     mCurrTextureUnitIndex(0),
     mLineWidth(1.f),
-    mDummyVAO(0),
 	mPrimitiveReset(false)
 {	
 	mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
@@ -1138,22 +1137,6 @@ LLRender::~LLRender()
 
 void LLRender::init()
 {
-	if (mDummyVAO != 0)
-	{ 
-#ifdef GL_ARB_vertex_array_object
-		glDeleteVertexArrays(1, &mDummyVAO);
-#endif
-		mDummyVAO = 0;
-	}
-
-	if (sGLCoreProfile && !LLVertexBuffer::sUseVAO)
-	{ //bind a dummy vertex array object so we're core profile compliant
-#ifdef GL_ARB_vertex_array_object
-		glGenVertexArrays(1, &mDummyVAO);
-		glBindVertexArray(mDummyVAO);
-#endif
-	}
-	stop_glerror();
 	restoreVertexBuffers();
 }
 
@@ -1174,14 +1157,6 @@ void LLRender::shutdown()
 	mLightState.clear();
 
 	mBuffer = nullptr;
-	
-	if (mDummyVAO != 0)
-    { //bind a dummy vertex array object so we're core profile compliant
-#ifdef GL_ARB_vertex_array_object
-        glDeleteVertexArrays(1, &mDummyVAO);
-#endif
-        mDummyVAO = 0;
-    }
 }
 
 void LLRender::refreshState(void)
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index f49dbe66e17..6f158a2cb8d 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -516,8 +516,6 @@ class LLRender
 	eBlendFactor mCurrBlendAlphaSFactor;
 	eBlendFactor mCurrBlendAlphaDFactor;
 
-    U32             mDummyVAO;
-
 	std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIOffset;
 	std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIScale;
 
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6322eb27152..913f49eb48b 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -120,6 +120,7 @@ bool LLVertexBuffer::sUseStreamDraw = true;
 bool LLVertexBuffer::sUseVAO = false;
 bool LLVertexBuffer::sPreferStreamDraw = false;
 LLVertexBuffer* LLVertexBuffer::sUtilityBuffer = nullptr;
+U32 LLVertexBuffer::sDummyVAO = 0;
 
 #if LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO || defined(RELEASE_SHOW_ASSERT)
 static absl::flat_hash_set<U32> sActiveBufferNames;
@@ -996,6 +997,24 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
 	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
 	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
+
+#ifdef GL_ARB_vertex_array_object
+	if (LLRender::sGLCoreProfile && !sUseVAO)
+	{
+		if (sDummyVAO != 0)
+		{
+			glBindVertexArray(0);
+			glDeleteVertexArrays(1, &sDummyVAO);
+			sDummyVAO = 0;
+		}
+
+		{ //bind a dummy vertex array object so we're core profile compliant
+			glGenVertexArrays(1, &sDummyVAO);
+			glBindVertexArray(sDummyVAO);
+		}
+		stop_glerror();
+	}
+#endif
 }
 
 //static 
@@ -1050,6 +1069,17 @@ void LLVertexBuffer::cleanupClass()
 
 	delete sUtilityBuffer;
 	sUtilityBuffer = nullptr;
+
+
+	if (sDummyVAO != 0)
+	{
+#ifdef GL_ARB_vertex_array_object
+		glBindVertexArray(0);
+		glDeleteVertexArrays(1, &sDummyVAO);
+#endif
+		sDummyVAO = 0;
+	}
+	stop_glerror();
 }
 
 //----------------------------------------------------------------------------
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index c2c16ca69c2..511aaaae962 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -352,6 +352,7 @@ class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLV
 
 private:
 	static LLVertexBuffer* sUtilityBuffer;
+	static U32 sDummyVAO;
 };
 
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 03f46a0342e..9e939bec214 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7590,9 +7590,10 @@ void LLPipeline::doResetVertexBuffers(bool forced)
 
 	LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
 
-	LLVOPartGroup::restoreGL();
 	gGL.restoreVertexBuffers();
 
+	LLVOPartGroup::restoreGL();
+
 	if (mCubeVB.isNull())
 	{
 		mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
-- 
GitLab