From 56191701bcbc0ef1b6872cc6bfac1d18f636fd12 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Sun, 25 Sep 2011 02:43:43 -0500
Subject: [PATCH] SH-2244 Fix for crash when enabling core profile on AMD GPUs

---
 indra/llrender/llgl.cpp           | 55 ++++++++++++++++++++++---------
 indra/llrender/llrender.cpp       |  3 +-
 indra/llrender/llvertexbuffer.cpp |  4 ++-
 3 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 4d0dfbf75d3..59c63d84656 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -493,6 +493,8 @@ bool LLGLManager::initGL()
 		LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
 	}
 
+	stop_glerror();
+
 #if LL_WINDOWS
 	if (!glGetStringi)
 	{
@@ -508,7 +510,9 @@ bool LLGLManager::initGL()
 		glGetIntegerv(GL_NUM_EXTENSIONS, &count);
 		for (GLint i = 0; i < count; ++i)
 		{
-			str << (const char*) glGetStringi(GL_EXTENSIONS, i) << " ";
+			std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
+			str << ext << " ";
+			LL_DEBUGS("GLExtensions") << ext << llendl;
 		}
 		
 		{
@@ -526,6 +530,8 @@ bool LLGLManager::initGL()
 	}
 #endif
 	
+	stop_glerror();
+
 	// Extract video card strings and convert to upper case to
 	// work around driver-to-driver variation in capitalization.
 	mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
@@ -612,8 +618,10 @@ bool LLGLManager::initGL()
 		mGLVendorShort = "MISC";
 	}
 	
+	stop_glerror();
 	// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
 	initExtensions();
+	stop_glerror();
 
 	if (mHasATIMemInfo)
 	{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
@@ -629,7 +637,22 @@ bool LLGLManager::initGL()
 		mVRAM = dedicated_memory/1024;
 	}
 
-	if (mHasMultitexture)
+	stop_glerror();
+
+	stop_glerror();
+
+	if (mHasFragmentShader)
+	{
+		GLint num_tex_image_units;
+		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
+		mNumTextureImageUnits = llmin(num_tex_image_units, 32);
+	}
+
+	if (LLRender::sGLCoreProfile)
+	{
+		mNumTextureUnits = mNumTextureImageUnits;
+	}
+	else if (mHasMultitexture)
 	{
 		GLint num_tex_units;		
 		glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
@@ -648,12 +671,7 @@ bool LLGLManager::initGL()
 		return false;
 	}
 	
-	if (mHasFragmentShader)
-	{
-		GLint num_tex_image_units;
-		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
-		mNumTextureImageUnits = llmin(num_tex_image_units, 32);
-	}
+	stop_glerror();
 
 	if (mHasTextureMultisample)
 	{
@@ -663,6 +681,8 @@ bool LLGLManager::initGL()
 		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
 	}
 
+	stop_glerror();
+
 #if LL_WINDOWS
 	if (mHasDebugOutput && gDebugGL)
 	{ //setup debug output callback
@@ -672,6 +692,8 @@ bool LLGLManager::initGL()
 	}
 #endif
 
+	stop_glerror();
+
 	//HACK always disable texture multisample, use FXAA instead
 	mHasTextureMultisample = FALSE;
 #if LL_WINDOWS
@@ -685,10 +707,17 @@ bool LLGLManager::initGL()
 	{
 		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
 	}
+
+	stop_glerror();
 	
 	setToDebugGPU();
 
+	stop_glerror();
+
 	initGLStates();
+
+	stop_glerror();
+
 	return true;
 }
 
@@ -903,10 +932,10 @@ void LLGLManager::initExtensions()
 #if !LL_DARWIN
 	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
 #endif
-	mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
+	mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 	mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
-						&& ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
-	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
+		&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
+	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 #endif
 
 #if LL_LINUX || LL_SOLARIS
@@ -1338,10 +1367,6 @@ void log_glerror()
 
 void do_assert_glerror()
 {
-	if (LL_UNLIKELY(!gGLManager.mInited))
-	{
-		LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
-	}
 	//  Create or update texture to be used with this data 
 	GLenum error;
 	error = glGetError();
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 613d1599012..8ba164fcc9e 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1052,12 +1052,13 @@ LLRender::~LLRender()
 void LLRender::init()
 {
 	llassert_always(mBuffer.isNull()) ;
-
+	stop_glerror();
 	mBuffer = new LLVertexBuffer(immediate_mask, 0);
 	mBuffer->allocateBuffer(4096, 0, TRUE);
 	mBuffer->getVertexStrider(mVerticesp);
 	mBuffer->getTexCoord0Strider(mTexcoordsp);
 	mBuffer->getColorStrider(mColorsp);
+	stop_glerror();
 }
 
 void LLRender::shutdown()
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 422f2a06d65..1b7b0cdf3e5 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1024,7 +1024,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
 void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
-		
+	
+	stop_glerror();
+
 	if (nverts < 0 || nindices < 0 ||
 		nverts > 65536)
 	{
-- 
GitLab