From 0bbe8d73cb687e34d1b10c58b67c465df076739c Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 25 Jan 2012 15:37:36 -0600
Subject: SH-2565 Move resetVertexBuffer operation to a consistent location
 (also avoid redundant resetting of vertex buffers on detail switches). 
 Change assertion to a warning with count info.  Fix bytes pooled debug
 display.  Remove unused static vertex buffer.

---
 indra/llrender/llvertexbuffer.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index eb302392bb..518f3898a4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -205,14 +205,13 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 	rec.mGLName = name;
 	rec.mClientData = buffer;
 
-	sBytesPooled += size;
-	
 	if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
 	{
 		glDeleteBuffersARB(1, &rec.mGLName);
 	}
 	else
 	{
+		sBytesPooled += size;
 		mFreeList[i].push_back(rec);
 	}
 }
-- 
cgit v1.2.3


From 71a660e0060b9aa2c5c01fd94e8070075b373d8d Mon Sep 17 00:00:00 2001
From: Leslie Linden <leslie@lindenlab.com>
Date: Thu, 26 Jan 2012 10:17:41 -0800
Subject: * Fixed up shader compilation errors to get lighting and shadows
 working again on Mac. * Cleaned up vertex buffer allocation to guarantee
 allocation and deallocation using the same allocation methods from the same
 pools. * Added new shader feature for atmospheric helpers in the absence of
 lighting.

Reviewed by davep.
---
 indra/llrender/llglslshader.cpp   |  21 +++-
 indra/llrender/llglslshader.h     |   1 +
 indra/llrender/llshadermgr.cpp    |   5 +-
 indra/llrender/llvertexbuffer.cpp | 222 ++++++++++++++++++--------------------
 indra/llrender/llvertexbuffer.h   |  31 ++++--
 5 files changed, 151 insertions(+), 129 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 6b2852670a..3773568ad8 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -64,10 +64,23 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
 }
 
 LLShaderFeatures::LLShaderFeatures()
-: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
-hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
-hasGamma(false), hasLighting(false), isAlphaLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
-hasAlphaMask(false)
+	: atmosphericHelpers(false)
+	, calculatesLighting(false)
+	, calculatesAtmospherics(false)
+	, hasLighting(false)
+	, isAlphaLighting(false)
+	, isShiny(false)
+	, isFullbright(false)
+	, isSpecular(false)
+	, hasWaterFog(false)
+	, hasTransport(false)
+	, hasSkinning(false)
+	, hasObjectSkinning(false)
+	, hasAtmospherics(false)
+	, hasGamma(false)
+	, mIndexedTextureChannels(0)
+	, disableTextureIndex(false)
+	, hasAlphaMask(false)
 {
 }
 
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 00b4b0dbd4..7873fe3c4e 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -33,6 +33,7 @@
 class LLShaderFeatures
 {
 public:
+	bool atmosphericHelpers;
 	bool calculatesLighting;
 	bool calculatesAtmospherics;
 	bool hasLighting; // implies no transport (it's possible to have neither though)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 1a03aeebb7..908443e8cf 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -94,13 +94,16 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 		}
 	}
 
-	if (features->calculatesLighting)
+	if (features->calculatesLighting || features->atmosphericHelpers)
 	{
 		if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
 		{
 			return FALSE;
 		}
+	}
 		
+	if (features->calculatesLighting)
+	{
 		if (features->isSpecular)
 		{
 			if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 518f3898a4..9069885341 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -53,19 +53,19 @@ U32 nhpo2(U32 v)
 //============================================================================
 
 //static
-LLVBOPool LLVertexBuffer::sStreamVBOPool;
-LLVBOPool LLVertexBuffer::sDynamicVBOPool;
-LLVBOPool LLVertexBuffer::sStreamIBOPool;
-LLVBOPool LLVertexBuffer::sDynamicIBOPool;
+LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
 U32 LLVBOPool::sBytesPooled = 0;
 
-LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
+LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
 U32 LLVertexBuffer::sBindCount = 0;
 U32 LLVertexBuffer::sSetCount = 0;
 S32 LLVertexBuffer::sCount = 0;
 S32 LLVertexBuffer::sGLCount = 0;
 S32 LLVertexBuffer::sMappedCount = 0;
-BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
+BOOL LLVertexBuffer::sDisableVBOMapping = FALSE;
 BOOL LLVertexBuffer::sEnableVBOs = TRUE;
 U32 LLVertexBuffer::sGLRenderBuffer = 0;
 U32 LLVertexBuffer::sGLRenderArray = 0;
@@ -204,8 +204,8 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 	Record rec;
 	rec.mGLName = name;
 	rec.mClientData = buffer;
-
-	if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
+	
+	if (buffer == NULL)
 	{
 		glDeleteBuffersARB(1, &rec.mGLName);
 	}
@@ -282,7 +282,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 {
 	if (sLastMask != data_mask)
 	{
-		BOOL error = FALSE;
+		bool error = false;
 
 		if (LLGLSLShader::sNoFixedFunction)
 		{
@@ -343,7 +343,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 						{
 							if (gDebugSession)
 							{
-								error = TRUE;
+								error = true;
 								gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
 							}
 							else
@@ -363,7 +363,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 					{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
 						if (gDebugSession)
 						{
-							error = TRUE;
+							error = true;
 							gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
 						}
 						else
@@ -547,7 +547,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
 void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
 {
 	validateRange(start, end, count, indices_offset);
-	mMappable = FALSE;
+	mMappable = false;
 	gGL.syncMatrices();
 
 	llassert(mNumVerts >= 0);
@@ -602,7 +602,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-	mMappable = FALSE;
+	mMappable = false;
 	gGL.syncMatrices();
 
 	llassert(mNumIndices >= 0);
@@ -648,7 +648,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-	mMappable = FALSE;
+	mMappable = false;
 	gGL.syncMatrices();
 	
 	llassert(mNumVerts >= 0);
@@ -688,23 +688,13 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 //static
 void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
-	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
-	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
+	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
+	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
 
-	if(!sPrivatePoolp)
+	if (!sPrivatePoolp)
 	{ 
-		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
+		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC);
 	}
-
-	sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB;
-	sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB;
-	sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
-	sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB;
-
-	sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB;
-	sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
-	sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
-	sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
 }
 
 //static 
@@ -757,65 +747,79 @@ void LLVertexBuffer::cleanupClass()
 
 //----------------------------------------------------------------------------
 
-LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
-	LLRefCount(),
-
-	mNumVerts(0),
-	mNumIndices(0),
-	mUsage(usage),
-	mGLBuffer(0),
-	mGLArray(0),
-	mGLIndices(0), 
-	mMappedData(NULL),
-	mMappedIndexData(NULL), 
-	mVertexLocked(FALSE),
-	mIndexLocked(FALSE),
-	mFinal(FALSE),
-	mEmpty(TRUE),
-	mFence(NULL)
+S32 LLVertexBuffer::determineUsage(S32 usage)
 {
-	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
-	mFence = NULL;
+	S32 ret_usage = usage;
+
 	if (!sEnableVBOs)
 	{
-		mUsage = 0 ; 
+		ret_usage = 0;
 	}
-
-	if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+	
+	if (usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
 	{
-		mUsage = 0;
+		ret_usage = 0;
 	}
 	
-	if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
+	if (usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
 	{
-		mUsage = GL_STREAM_DRAW_ARB;
+		ret_usage = GL_STREAM_DRAW_ARB;
 	}
-
-	if (mUsage == 0 && LLRender::sGLCoreProfile)
+	
+	if (usage == 0 && LLRender::sGLCoreProfile)
 	{ //MUST use VBOs for all rendering
-		mUsage = GL_STREAM_DRAW_ARB;
+		ret_usage = GL_STREAM_DRAW_ARB;
 	}
-
-	if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
+	
+	if (usage && usage != GL_STREAM_DRAW_ARB)
 	{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
 		if (sDisableVBOMapping)
 		{ //always use stream draw if VBO mapping is disabled
-			mUsage = GL_STREAM_DRAW_ARB;
+			ret_usage = GL_STREAM_DRAW_ARB;
 		}
 		else
 		{
-			mUsage = GL_DYNAMIC_DRAW_ARB;
+			ret_usage = GL_DYNAMIC_DRAW_ARB;
 		}
 	}
 	
+	return ret_usage;
+}
+
+LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
+	LLRefCount(),
+
+	mNumVerts(0),
+	mNumIndices(0),
+	mAlignedOffset(0),
+	mAlignedIndexOffset(0),
+	mSize(0),
+	mIndicesSize(0),
+	mTypeMask(typemask),
+	mUsage(LLVertexBuffer::determineUsage(usage)),
+	mGLBuffer(0),
+	mGLIndices(0),
+	mGLArray(0),
+	mMappedData(NULL),
+	mMappedIndexData(NULL),
+	mMappedDataUsingVBOs(false),
+	mMappedIndexDataUsingVBOs(false),
+	mVertexLocked(false),
+	mIndexLocked(false),
+	mFinal(false),
+	mEmpty(true),
+	mMappable(false),
+	mFence(NULL)
+{
+	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
 
 	if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
 	{
-		mMappable = TRUE;
+		mMappable = true;
 	}
 	else
 	{
-		mMappable = FALSE;
+		mMappable = false;
 	}
 
 	//zero out offsets
@@ -824,12 +828,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 		mOffsets[i] = 0;
 	}
 
-	mTypeMask = typemask;
-	mSize = 0;
-	mIndicesSize = 0;
-	mAlignedOffset = 0;
-	mAlignedIndexOffset = 0;
-
 	sCount++;
 }
 
@@ -1010,9 +1008,11 @@ void LLVertexBuffer::createGLBuffer(U32 size)
 		return;
 	}
 
-	mEmpty = TRUE;
+	mEmpty = true;
 
-	if (useVBOs())
+	mMappedDataUsingVBOs = useVBOs();
+	
+	if (mMappedDataUsingVBOs)
 	{
 		genBuffer(size);
 	}
@@ -1039,12 +1039,14 @@ void LLVertexBuffer::createGLIndices(U32 size)
 		return;
 	}
 
-	mEmpty = TRUE;
+	mEmpty = true;
 
 	//pad by 16 bytes for aligned copies
 	size += 16;
 
-	if (useVBOs())
+	mMappedIndexDataUsingVBOs = useVBOs();
+
+	if (mMappedIndexDataUsingVBOs)
 	{
 		//pad by another 16 bytes for VBO pointer adjustment
 		size += 16;
@@ -1064,15 +1066,15 @@ void LLVertexBuffer::destroyGLBuffer()
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
 	if (mGLBuffer)
 	{
-		if (useVBOs())
+		if (mMappedDataUsingVBOs)
 		{
 			releaseBuffer();
 		}
 		else
 		{
-			FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
+			FREE_MEM(sPrivatePoolp, (void*) mMappedData);
 			mMappedData = NULL;
-			mEmpty = TRUE;
+			mEmpty = true;
 		}
 	}
 	
@@ -1085,15 +1087,15 @@ void LLVertexBuffer::destroyGLIndices()
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
 	if (mGLIndices)
 	{
-		if (useVBOs())
+		if (mMappedIndexDataUsingVBOs)
 		{
 			releaseIndices();
 		}
 		else
 		{
-			FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
+			FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
 			mMappedIndexData = NULL;
-			mEmpty = TRUE;
+			mEmpty = true;
 		}
 	}
 
@@ -1278,16 +1280,10 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
 	}
 }
 
-BOOL LLVertexBuffer::useVBOs() const
+bool LLVertexBuffer::useVBOs() const
 {
 	//it's generally ineffective to use VBO for things that are streaming on apple
-		
-	if (!mUsage)
-	{
-		return FALSE;
-	}
-
-	return TRUE;
+	return (mUsage != 0);
 }
 
 //----------------------------------------------------------------------------
@@ -1367,7 +1363,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 		if (!mVertexLocked)
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
-			mVertexLocked = TRUE;
+			mVertexLocked = true;
 			sMappedCount++;
 			stop_glerror();	
 
@@ -1446,8 +1442,8 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 			{
 				log_glerror();
 
-			//check the availability of memory
-			LLMemory::logMemoryInfo(TRUE) ; 
+				//check the availability of memory
+				LLMemory::logMemoryInfo(TRUE) ; 
 			
 				if(mMappable)
 				{			
@@ -1546,7 +1542,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
 
-			mIndexLocked = TRUE;
+			mIndexLocked = true;
 			sMappedCount++;
 			stop_glerror();	
 
@@ -1741,7 +1737,7 @@ void LLVertexBuffer::unmapBuffer()
 			mMappedData = NULL;
 		}
 
-		mVertexLocked = FALSE ;
+		mVertexLocked = false;
 		sMappedCount--;
 	}
 	
@@ -1808,13 +1804,13 @@ void LLVertexBuffer::unmapBuffer()
 			mMappedIndexData = NULL ;
 		}
 
-		mIndexLocked = FALSE ;
+		mIndexLocked = false ;
 		sMappedCount--;
 	}
 
 	if(updated_all)
 	{
-		mEmpty = FALSE;
+		mEmpty = false;
 	}
 }
 
@@ -1834,12 +1830,12 @@ template <class T,S32 type> struct VertexBufferStrider
 			if (ptr == NULL)
 			{
 				llwarns << "mapIndexBuffer failed!" << llendl;
-				return FALSE;
+				return false;
 			}
 
 			strider = (T*)ptr;
 			strider.setStride(0);
-			return TRUE;
+			return true;
 		}
 		else if (vbo.hasDataType(type))
 		{
@@ -1850,18 +1846,18 @@ template <class T,S32 type> struct VertexBufferStrider
 			if (ptr == NULL)
 			{
 				llwarns << "mapVertexBuffer failed!" << llendl;
-				return FALSE;
+				return false;
 			}
 
 			strider = (T*)ptr;
 			strider.setStride(stride);
-			return TRUE;
+			return true;
 		}
 		else
 		{
 			llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
 		}
-		return FALSE;
+		return false;
 	}
 };
 
@@ -2014,7 +2010,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
 	//set up pointers if the data mask is different ...
-	BOOL setup = (sLastMask != data_mask);
+	bool setup = (sLastMask != data_mask);
 
 	if (gDebugGL && data_mask != 0)
 	{ //make sure data requirements are fulfilled
@@ -2048,21 +2044,17 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 		if (mGLArray)
 		{
 			bindGLArray();
-			setup = FALSE; //do NOT perform pointer setup if using VAO
+			setup = false; //do NOT perform pointer setup if using VAO
 		}
 		else
 		{
-			if (bindGLBuffer())
-			{
-				setup = TRUE;
-			}
-			if (bindGLIndices())
-			{
-				setup = TRUE;
-			}
+			const bool bindBuffer = bindGLBuffer();
+			const bool bindIndices = bindGLIndices();
+			
+			setup = setup || bindBuffer || bindIndices;
 		}
 
-		BOOL error = FALSE;
+		bool error = false;
 		if (gDebugGL && !mGLArray)
 		{
 			GLint buff;
@@ -2071,7 +2063,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			{
 				if (gDebugSession)
 				{
-					error = TRUE;
+					error = true;
 					gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
 				}
 				else
@@ -2087,7 +2079,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 				{
 					if (gDebugSession)
 					{
-						error = TRUE;
+						error = true;
 						gFailLog << "Invalid GL index buffer bound: " << buff <<  std::endl;
 					}
 					else
@@ -2119,12 +2111,12 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 				glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
 				sBindCount++;
 				sVBOActive = FALSE;
-				setup = TRUE; // ... or a VBO is deactivated
+				setup = true; // ... or a VBO is deactivated
 			}
 			if (sGLRenderBuffer != mGLBuffer)
 			{
 				sGLRenderBuffer = mGLBuffer;
-				setup = TRUE; // ... or a client memory pointer changed
+				setup = true; // ... or a client memory pointer changed
 			}
 		}
 		if (mGLIndices)
@@ -2221,19 +2213,19 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 		{
 			S32 loc = TYPE_WEIGHT;
 			void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
-			glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+			glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
 		}
 		if (data_mask & MAP_WEIGHT4)
 		{
 			S32 loc = TYPE_WEIGHT4;
 			void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
-			glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+			glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
 		}
 		if (data_mask & MAP_CLOTHWEIGHT)
 		{
 			S32 loc = TYPE_CLOTHWEIGHT;
 			void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
-			glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+			glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
 		}
 		if (data_mask & MAP_TEXTURE_INDEX)
 		{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index e1cbfd3b61..a0d21b4a36 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -55,9 +55,14 @@ class LLVBOPool
 {
 public:
 	static U32 sBytesPooled;
+	
+	LLVBOPool(U32 vboUsage, U32 vboType)
+		: mUsage(vboUsage)
+		, mType(vboType)
+	{}
 
-	U32 mUsage;
-	U32 mType;
+	const U32 mUsage;
+	const U32 mType;
 
 	//size MUST be a power of 2
 	volatile U8* allocate(U32& name, U32 size);
@@ -103,6 +108,7 @@ public:
 	};
 
 	LLVertexBuffer(const LLVertexBuffer& rhs)
+		: mUsage(rhs.mUsage)
 	{
 		*this = rhs;
 	}
@@ -201,7 +207,7 @@ protected:
 	void 	destroyGLIndices();
 	void	updateNumVerts(S32 nverts);
 	void	updateNumIndices(S32 nindices); 
-	virtual BOOL	useVBOs() const;
+	bool	useVBOs() const;
 	void	unmapBuffer();
 		
 public:
@@ -274,18 +280,24 @@ protected:
 	S32		mSize;
 	S32		mIndicesSize;
 	U32		mTypeMask;
-	S32		mUsage;			// GL usage
+
+	const S32		mUsage;			// GL usage
+	
 	U32		mGLBuffer;		// GL VBO handle
 	U32		mGLIndices;		// GL IBO handle
 	U32		mGLArray;		// GL VAO handle
 	
 	volatile U8* mMappedData;	// pointer to currently mapped data (NULL if unmapped)
 	volatile U8* mMappedIndexData;	// pointer to currently mapped indices (NULL if unmapped)
-	BOOL	mVertexLocked;			// if TRUE, vertex buffer is being or has been written to in client memory
-	BOOL	mIndexLocked;			// if TRUE, index buffer is being or has been written to in client memory
-	BOOL	mFinal;			// if TRUE, buffer can not be mapped again
-	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
-	mutable BOOL	mMappable;     // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
+
+	U32		mMappedDataUsingVBOs : 1;
+	U32		mMappedIndexDataUsingVBOs : 1;
+	U32		mVertexLocked : 1;			// if TRUE, vertex buffer is being or has been written to in client memory
+	U32		mIndexLocked : 1;			// if TRUE, index buffer is being or has been written to in client memory
+	U32		mFinal : 1;			// if TRUE, buffer can not be mapped again
+	U32		mEmpty : 1;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
+	
+	mutable bool	mMappable;     // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
 	S32		mOffsets[TYPE_MAX];
 
 	std::vector<MappedRegion> mMappedVertexRegions;
@@ -296,6 +308,7 @@ protected:
 	void placeFence() const;
 	void waitFence() const;
 
+	static S32 determineUsage(S32 usage);
 
 private:
 	static LLPrivateMemoryPool* sPrivatePoolp ;
-- 
cgit v1.2.3


From 17b21fc197f162a4070083c436920c0640431568 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 26 Jan 2012 12:50:24 -0600
Subject: Fix for windows build

---
 indra/llrender/llvertexbuffer.cpp | 36 ++++++++++++++++++------------------
 indra/llrender/llvertexbuffer.h   | 32 ++++++++++++++++----------------
 2 files changed, 34 insertions(+), 34 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 9069885341..a7151afeb1 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -65,19 +65,19 @@ U32 LLVertexBuffer::sSetCount = 0;
 S32 LLVertexBuffer::sCount = 0;
 S32 LLVertexBuffer::sGLCount = 0;
 S32 LLVertexBuffer::sMappedCount = 0;
-BOOL LLVertexBuffer::sDisableVBOMapping = FALSE;
-BOOL LLVertexBuffer::sEnableVBOs = TRUE;
+bool LLVertexBuffer::sDisableVBOMapping = false;
+bool LLVertexBuffer::sEnableVBOs = true;
 U32 LLVertexBuffer::sGLRenderBuffer = 0;
 U32 LLVertexBuffer::sGLRenderArray = 0;
 U32 LLVertexBuffer::sGLRenderIndices = 0;
 U32 LLVertexBuffer::sLastMask = 0;
-BOOL LLVertexBuffer::sVBOActive = FALSE;
-BOOL LLVertexBuffer::sIBOActive = FALSE;
+bool LLVertexBuffer::sVBOActive = false;
+bool LLVertexBuffer::sIBOActive = false;
 U32 LLVertexBuffer::sAllocatedBytes = 0;
-BOOL LLVertexBuffer::sMapped = FALSE;
-BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
-BOOL LLVertexBuffer::sUseVAO = FALSE;
-BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
+bool LLVertexBuffer::sMapped = false;
+bool LLVertexBuffer::sUseStreamDraw = true;
+bool LLVertexBuffer::sUseVAO = false;
+bool LLVertexBuffer::sPreferStreamDraw = false;
 
 const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms
 
@@ -707,18 +707,18 @@ void LLVertexBuffer::unbind()
 #endif
 		sGLRenderArray = 0;
 		sGLRenderIndices = 0;
-		sIBOActive = FALSE;
+		sIBOActive = false;
 	}
 
 	if (sVBOActive)
 	{
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
-		sVBOActive = FALSE;
+		sVBOActive = false;
 	}
 	if (sIBOActive)
 	{
 		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
-		sIBOActive = FALSE;
+		sIBOActive = false;
 	}
 
 	sGLRenderBuffer = 0;
@@ -1443,7 +1443,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 				log_glerror();
 
 				//check the availability of memory
-				LLMemory::logMemoryInfo(TRUE) ; 
+				LLMemory::logMemoryInfo(true) ; 
 			
 				if(mMappable)
 				{			
@@ -1621,7 +1621,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
 		if (!mMappedIndexData)
 		{
 			log_glerror();
-			LLMemory::logMemoryInfo(TRUE) ;
+			LLMemory::logMemoryInfo(true) ;
 
 			if(mMappable)
 			{
@@ -1956,7 +1956,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
 		sGLRenderBuffer = mGLBuffer;
 		sBindCount++;
-		sVBOActive = TRUE;
+		sVBOActive = true;
 
 		if (mGLArray)
 		{
@@ -1988,7 +1988,7 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
 		sGLRenderIndices = mGLIndices;
 		stop_glerror();
 		sBindCount++;
-		sIBOActive = TRUE;
+		sIBOActive = true;
 		ret = true;
 	}
 
@@ -2101,7 +2101,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 #endif
 			sGLRenderArray = 0;
 			sGLRenderIndices = 0;
-			sIBOActive = FALSE;
+			sIBOActive = false;
 		}
 
 		if (mGLBuffer)
@@ -2110,7 +2110,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			{
 				glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
 				sBindCount++;
-				sVBOActive = FALSE;
+				sVBOActive = false;
 				setup = true; // ... or a VBO is deactivated
 			}
 			if (sGLRenderBuffer != mGLBuffer)
@@ -2125,7 +2125,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			{
 				glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
 				sBindCount++;
-				sIBOActive = FALSE;
+				sIBOActive = false;
 			}
 			
 			sGLRenderIndices = mGLIndices;
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index a0d21b4a36..0bf689bfad 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -124,9 +124,9 @@ public:
 	static LLVBOPool sStreamIBOPool;
 	static LLVBOPool sDynamicIBOPool;
 
-	static BOOL	sUseStreamDraw;
-	static BOOL sUseVAO;
-	static BOOL	sPreferStreamDraw;
+	static bool	sUseStreamDraw;
+	static bool sUseVAO;
+	static bool	sPreferStreamDraw;
 
 	static void initClass(bool use_vbo, bool no_vbo_mapping);
 	static void cleanupClass();
@@ -245,8 +245,8 @@ public:
 	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	
 
-	BOOL isEmpty() const					{ return mEmpty; }
-	BOOL isLocked() const					{ return mVertexLocked || mIndexLocked; }
+	bool isEmpty() const					{ return mEmpty; }
+	bool isLocked() const					{ return mVertexLocked || mIndexLocked; }
 	S32 getNumVerts() const					{ return mNumVerts; }
 	S32 getNumIndices() const				{ return mNumIndices; }
 	
@@ -260,7 +260,7 @@ public:
 	volatile U8* getMappedIndices() const			{ return mMappedIndexData; }
 	S32 getOffset(S32 type) const			{ return mOffsets[type]; }
 	S32 getUsage() const					{ return mUsage; }
-	BOOL isWriteable() const				{ return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; }
+	bool isWriteable() const				{ return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
 
 	void draw(U32 mode, U32 count, U32 indices_offset) const;
 	void drawArrays(U32 mode, U32 offset, U32 count) const;
@@ -292,12 +292,12 @@ protected:
 
 	U32		mMappedDataUsingVBOs : 1;
 	U32		mMappedIndexDataUsingVBOs : 1;
-	U32		mVertexLocked : 1;			// if TRUE, vertex buffer is being or has been written to in client memory
-	U32		mIndexLocked : 1;			// if TRUE, index buffer is being or has been written to in client memory
-	U32		mFinal : 1;			// if TRUE, buffer can not be mapped again
-	U32		mEmpty : 1;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
+	U32		mVertexLocked : 1;			// if true, vertex buffer is being or has been written to in client memory
+	U32		mIndexLocked : 1;			// if true, index buffer is being or has been written to in client memory
+	U32		mFinal : 1;			// if true, buffer can not be mapped again
+	U32		mEmpty : 1;			// if true, client buffer is empty (or NULL). Old values have been discarded.	
 	
-	mutable bool	mMappable;     // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
+	mutable bool	mMappable;     // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
 	S32		mOffsets[TYPE_MAX];
 
 	std::vector<MappedRegion> mMappedVertexRegions;
@@ -317,18 +317,18 @@ public:
 	static S32 sCount;
 	static S32 sGLCount;
 	static S32 sMappedCount;
-	static BOOL sMapped;
+	static bool sMapped;
 	typedef std::list<LLVertexBuffer*> buffer_list_t;
 		
-	static BOOL sDisableVBOMapping; //disable glMapBufferARB
-	static BOOL sEnableVBOs;
+	static bool sDisableVBOMapping; //disable glMapBufferARB
+	static bool sEnableVBOs;
 	static S32 sTypeSize[TYPE_MAX];
 	static U32 sGLMode[LLRender::NUM_MODES];
 	static U32 sGLRenderBuffer;
 	static U32 sGLRenderArray;
 	static U32 sGLRenderIndices;
-	static BOOL sVBOActive;
-	static BOOL sIBOActive;
+	static bool sVBOActive;
+	static bool sIBOActive;
 	static U32 sLastMask;
 	static U32 sAllocatedBytes;
 	static U32 sBindCount;
-- 
cgit v1.2.3


From ae7d475aebc836203984654912df036a11c365fc Mon Sep 17 00:00:00 2001
From: Leslie Linden <leslie@lindenlab.com>
Date: Mon, 6 Feb 2012 12:43:23 -0800
Subject: SH-2794, resolved merge conflict and corrected logic in
 LLVertexBuffer::determineUsage() to work the way it used to.

---
 indra/llrender/llvertexbuffer.cpp | 121 +++++++-------------------------------
 indra/llrender/llvertexbuffer.h   |  17 +-----
 2 files changed, 24 insertions(+), 114 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 230c1faa40..e4a5cd0299 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -204,26 +204,14 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 	Record rec;
 	rec.mGLName = name;
 	rec.mClientData = buffer;
-<<<<<<< local
-=======
-
-	sBytesPooled += size;
->>>>>>> other
 	
-<<<<<<< local
 	if (buffer == NULL)
-=======
-	if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
->>>>>>> other
 	{
 		glDeleteBuffersARB(1, &rec.mGLName);
 	}
 	else
 	{
-<<<<<<< local
 		sBytesPooled += size;
-=======
->>>>>>> other
 		mFreeList[i].push_back(rec);
 	}
 }
@@ -441,7 +429,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
 
 	U32 count = pos.size();
 	llassert_always(norm.size() >= pos.size());
-	llassert_always(count > 0) ;
+	llassert_always(count > 0);
 
 	unbind();
 	
@@ -559,11 +547,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
 void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
 {
 	validateRange(start, end, count, indices_offset);
-<<<<<<< local
 	mMappable = false;
-=======
-	mMappable = FALSE;
->>>>>>> other
 	gGL.syncMatrices();
 
 	llassert(mNumVerts >= 0);
@@ -618,11 +602,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-<<<<<<< local
 	mMappable = false;
-=======
-	mMappable = FALSE;
->>>>>>> other
 	gGL.syncMatrices();
 
 	llassert(mNumIndices >= 0);
@@ -668,11 +648,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-<<<<<<< local
 	mMappable = false;
-=======
-	mMappable = FALSE;
->>>>>>> other
 	gGL.syncMatrices();
 	
 	llassert(mNumVerts >= 0);
@@ -764,8 +740,8 @@ void LLVertexBuffer::cleanupClass()
 
 	if(sPrivatePoolp)
 	{
-		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
-		sPrivatePoolp = NULL ;
+		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp);
+		sPrivatePoolp = NULL;
 	}
 }
 
@@ -780,22 +756,22 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
 		ret_usage = 0;
 	}
 	
-	if (usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+	if (ret_usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
 	{
 		ret_usage = 0;
 	}
 	
-	if (usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
+	if (ret_usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
 	{
 		ret_usage = GL_STREAM_DRAW_ARB;
 	}
 	
-	if (usage == 0 && LLRender::sGLCoreProfile)
+	if (ret_usage == 0 && LLRender::sGLCoreProfile)
 	{ //MUST use VBOs for all rendering
 		ret_usage = GL_STREAM_DRAW_ARB;
 	}
 	
-	if (usage && usage != GL_STREAM_DRAW_ARB)
+	if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
 	{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
 		if (sDisableVBOMapping)
 		{ //always use stream draw if VBO mapping is disabled
@@ -837,55 +813,8 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
 
-	if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
-	{
-		mMappable = true;
-	}
-	else
-	{
-		mMappable = false;
-	}
-
-<<<<<<< local
-=======
-	if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
-	{
-		mUsage = 0;
-	}
-	
-	if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
-	{
-		mUsage = GL_STREAM_DRAW_ARB;
-	}
-
-	if (mUsage == 0 && LLRender::sGLCoreProfile)
-	{ //MUST use VBOs for all rendering
-		mUsage = GL_STREAM_DRAW_ARB;
-	}
-
-	if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
-	{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
-		if (sDisableVBOMapping)
-		{ //always use stream draw if VBO mapping is disabled
-			mUsage = GL_STREAM_DRAW_ARB;
-		}
-		else
-		{
-			mUsage = GL_DYNAMIC_DRAW_ARB;
-		}
-	}
-	
-
-	if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
-	{
-		mMappable = TRUE;
-	}
-	else
-	{
-		mMappable = FALSE;
-	}
+	mMappable = (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping);
 
->>>>>>> other
 	//zero out offsets
 	for (U32 i = 0; i < TYPE_MAX; i++)
 	{
@@ -963,7 +892,7 @@ LLVertexBuffer::~LLVertexBuffer()
 	
 	mFence = NULL;
 
-	llassert_always(!mMappedData && !mMappedIndexData) ;
+	llassert_always(!mMappedData && !mMappedIndexData);
 };
 
 void LLVertexBuffer::placeFence() const
@@ -1136,11 +1065,7 @@ void LLVertexBuffer::destroyGLBuffer()
 		}
 		else
 		{
-<<<<<<< local
 			FREE_MEM(sPrivatePoolp, (void*) mMappedData);
-=======
-			FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
->>>>>>> other
 			mMappedData = NULL;
 			mEmpty = true;
 		}
@@ -1161,11 +1086,7 @@ void LLVertexBuffer::destroyGLIndices()
 		}
 		else
 		{
-<<<<<<< local
 			FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
-=======
-			FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
->>>>>>> other
 			mMappedIndexData = NULL;
 			mEmpty = true;
 		}
@@ -1515,16 +1436,16 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 				log_glerror();
 
 				//check the availability of memory
-				LLMemory::logMemoryInfo(true) ; 
+				LLMemory::logMemoryInfo(true);
 			
 				if(mMappable)
 				{			
 					//--------------------
 					//print out more debug info before crash
-					llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
-					GLint size ;
-					glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
-					llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
+					llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl;
+					GLint size;
+					glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+					llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl;
 					//--------------------
 
 					GLint buff;
@@ -1539,7 +1460,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 				}
 				else
 				{
-					llerrs << "memory allocation for vertex data failed." << llendl ;
+					llerrs << "memory allocation for vertex data failed." << llendl;
 				}
 			}
 		}
@@ -1693,7 +1614,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
 		if (!mMappedIndexData)
 		{
 			log_glerror();
-			LLMemory::logMemoryInfo(true) ;
+			LLMemory::logMemoryInfo(true);
 
 			if(mMappable)
 			{
@@ -1708,7 +1629,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
 			}
 			else
 			{
-				llerrs << "memory allocation for Index data failed. " << llendl ;
+				llerrs << "memory allocation for Index data failed. " << llendl;
 			}
 		}
 	}
@@ -1739,10 +1660,10 @@ void LLVertexBuffer::unmapBuffer()
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
 	if (!useVBOs())
 	{
-		return ; //nothing to unmap
+		return; //nothing to unmap
 	}
 
-	bool updated_all = false ;
+	bool updated_all = false;
 
 	if (mMappedData && mVertexLocked)
 	{
@@ -1873,10 +1794,10 @@ void LLVertexBuffer::unmapBuffer()
 			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 			stop_glerror();
 
-			mMappedIndexData = NULL ;
+			mMappedIndexData = NULL;
 		}
 
-		mIndexLocked = false ;
+		mIndexLocked = false;
 		sMappedCount--;
 	}
 
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 036f535d81..d859199663 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -93,7 +93,7 @@ public:
 
 //============================================================================
 // base class 
-class LLPrivateMemoryPool ;
+class LLPrivateMemoryPool;
 class LLVertexBuffer : public LLRefCount
 {
 public:
@@ -260,11 +260,7 @@ public:
 	volatile U8* getMappedIndices() const			{ return mMappedIndexData; }
 	S32 getOffset(S32 type) const			{ return mOffsets[type]; }
 	S32 getUsage() const					{ return mUsage; }
-<<<<<<< local
 	bool isWriteable() const				{ return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
-=======
-	BOOL isWriteable() const				{ return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; }
->>>>>>> other
 
 	void draw(U32 mode, U32 count, U32 indices_offset) const;
 	void drawArrays(U32 mode, U32 offset, U32 count) const;
@@ -293,7 +289,6 @@ protected:
 	
 	volatile U8* mMappedData;	// pointer to currently mapped data (NULL if unmapped)
 	volatile U8* mMappedIndexData;	// pointer to currently mapped indices (NULL if unmapped)
-<<<<<<< local
 
 	U32		mMappedDataUsingVBOs : 1;
 	U32		mMappedIndexDataUsingVBOs : 1;
@@ -303,13 +298,7 @@ protected:
 	U32		mEmpty : 1;			// if true, client buffer is empty (or NULL). Old values have been discarded.	
 	
 	mutable bool	mMappable;     // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
-=======
-	BOOL	mVertexLocked;			// if TRUE, vertex buffer is being or has been written to in client memory
-	BOOL	mIndexLocked;			// if TRUE, index buffer is being or has been written to in client memory
-	BOOL	mFinal;			// if TRUE, buffer can not be mapped again
-	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
-	mutable BOOL	mMappable;     // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
->>>>>>> other
+
 	S32		mOffsets[TYPE_MAX];
 
 	std::vector<MappedRegion> mMappedVertexRegions;
@@ -323,7 +312,7 @@ protected:
 	static S32 determineUsage(S32 usage);
 
 private:
-	static LLPrivateMemoryPool* sPrivatePoolp ;
+	static LLPrivateMemoryPool* sPrivatePoolp;
 
 public:
 	static S32 sCount;
-- 
cgit v1.2.3


From 38e0b7de96de02243453eeaf5710b924f68abc7a Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 6 Feb 2012 18:56:19 -0600
Subject: SH-2729 Fix for horizontal line of glitching graphics when DoF
 enabled

---
 indra/llrender/llshadermgr.cpp | 2 ++
 indra/llrender/llshadermgr.h   | 2 ++
 2 files changed, 4 insertions(+)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 908443e8cf..d03d349f0f 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1070,6 +1070,8 @@ void LLShaderMgr::initAttribsAndUniforms()
 	mReservedUniforms.push_back("magnification");
 	mReservedUniforms.push_back("max_cof");
 	mReservedUniforms.push_back("res_scale");
+	mReservedUniforms.push_back("dof_width");
+	mReservedUniforms.push_back("dof_height");
 
 	mReservedUniforms.push_back("depthMap");
 	mReservedUniforms.push_back("shadowMap0");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 950e6c9c2f..e28bda6de2 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -142,6 +142,8 @@ public:
 		DOF_MAGNIFICATION,
 		DOF_MAX_COF,
 		DOF_RES_SCALE,
+		DOF_WIDTH,
+		DOF_HEIGHT,
 
 		DEFERRED_DEPTH,
 		DEFERRED_SHADOW0,
-- 
cgit v1.2.3


From e0582d4bc71e2f367b4cf4a6f0b808451620b52f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 8 Feb 2012 19:01:08 -0600
Subject: Fix for Debug GL generating errors when changing graphics preferences
 (reloading shaders).

---
 indra/llrender/llglslshader.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 3773568ad8..7eba62e59e 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -109,7 +109,10 @@ void LLGLSLShader::unload()
 		glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
 		for (GLsizei i = 0; i < count; i++)
 		{
-			glDeleteObjectARB(obj[i]);
+			if (glIsProgramARB(obj[i]))
+			{
+				glDeleteObjectARB(obj[i]);
+			}
 		}
 
 		glDeleteObjectARB(mProgramObject);
-- 
cgit v1.2.3


From 3710c6110d65d3a604f7b419cd764cf5b9b98600 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 10 Feb 2012 20:04:19 -0600
Subject: SH-2908 Rework indexed texture rendering to use a uvec4 instead of a
 float for texture indices in the data stream.  Also rework gl_FragColor
 overrides to not collide with some odd driver implementations.

---
 indra/llrender/llgl.cpp           | 62 +++++++++++++++++++++++++-
 indra/llrender/llgl.h             |  2 +
 indra/llrender/llglheaders.h      |  3 ++
 indra/llrender/llglslshader.cpp   |  5 ++-
 indra/llrender/llshadermgr.cpp    | 92 ++++++++++++++++++---------------------
 indra/llrender/llvertexbuffer.cpp | 46 +++++++++++++++++---
 6 files changed, 153 insertions(+), 57 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 946e602fee..79d4415117 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -97,6 +97,8 @@ void APIENTRY gl_debug_callback(GLenum source,
 }
 #endif
 
+void parse_glsl_version(S32& major, S32& minor);
+
 void ll_init_fail_log(std::string filename)
 {
 	gFailLog.open(filename.c_str());
@@ -295,6 +297,7 @@ PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
 PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
 PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
 PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
 
 #if LL_WINDOWS
 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
@@ -341,6 +344,7 @@ PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;
 PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;
 PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;
 PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
 PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
 PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
@@ -443,7 +447,8 @@ LLGLManager::LLGLManager() :
 	mDriverVersionMinor(0),
 	mDriverVersionRelease(0),
 	mGLVersion(1.0f),
-		
+	mGLSLVersionMajor(0),
+	mGLSLVersionMinor(0),		
 	mVRAM(0),
 	mGLMaxVertexRange(0),
 	mGLMaxIndexRange(0)
@@ -554,6 +559,11 @@ bool LLGLManager::initGL()
 
 	mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
 
+	if (mGLVersion >= 2.f)
+	{
+		parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
+	}
+
 	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
 	// from being recognized as ATI.
 	if (mGLVendor.substr(0,4) == "ATI ")
@@ -1300,6 +1310,7 @@ void LLGLManager::initExtensions()
 		glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
 		glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
 		glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
+		glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
 		glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
 		glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
 		glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
@@ -2098,6 +2109,55 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
 	}
 }
 
+
+void parse_glsl_version(S32& major, S32& minor)
+{
+	// GL_SHADING_LANGUAGE_VERSION returns a null-terminated string with the format: 
+	// <major>.<minor>[.<release>] [<vendor specific>]
+
+	const char* version = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
+	major = 0;
+	minor = 0;
+	
+	if( !version )
+	{
+		return;
+	}
+
+	std::string ver_copy( version );
+	S32 len = (S32)strlen( version );	/* Flawfinder: ignore */
+	S32 i = 0;
+	S32 start;
+	// Find the major version
+	start = i;
+	for( ; i < len; i++ )
+	{
+		if( '.' == version[i] )
+		{
+			break;
+		}
+	}
+	std::string major_str = ver_copy.substr(start,i-start);
+	LLStringUtil::convertToS32(major_str, major);
+
+	if( '.' == version[i] )
+	{
+		i++;
+	}
+
+	// Find the minor version
+	start = i;
+	for( ; i < len; i++ )
+	{
+		if( ('.' == version[i]) || isspace(version[i]) )
+		{
+			break;
+		}
+	}
+	std::string minor_str = ver_copy.substr(start,i-start);
+	LLStringUtil::convertToS32(minor_str, minor);
+}
+
 LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
 {
 	mApply = apply;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 6a147b8e19..5a33c98708 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -138,6 +138,8 @@ public:
 	S32 mDriverVersionMinor;
 	S32 mDriverVersionRelease;
 	F32 mGLVersion; // e.g = 1.4
+	S32 mGLSLVersionMajor;
+	S32 mGLSLVersionMinor;
 	std::string mDriverVersionVendorString;
 
 	S32 mVRAM; // VRAM in MB
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 10aad202e1..d61ec707f0 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -199,6 +199,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
 extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
 extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
 extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
 extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
 extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
 extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
@@ -460,6 +461,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
 extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
 extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
 extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
 extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
 extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
 extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
@@ -693,6 +695,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
 extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
 extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
 extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
 extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
 extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
 extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7eba62e59e..a879a18895 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -164,8 +164,9 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
 		return FALSE;
 	}
 
-	if (gGLManager.mGLVersion < 3.1f)
-	{ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
+	if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3)
+	{ //indexed texture rendering requires GLSL 1.3 or later
+		//attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
 		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
 	}
 
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index d03d349f0f..321b139181 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -575,31 +575,39 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 	GLcharARB* text[4096];
 	GLuint count = 0;
 
-	F32 version = gGLManager.mGLVersion;
-
-//hack to never use GLSL > 1.20 on OSX
-#if LL_DARWIN
-	version = llmin(version, 2.9f);
-#endif
-
-	if (version < 2.1f)
-	{
-		text[count++] = strdup("#version 110\n");
-		text[count++] = strdup("#define ATTRIBUTE attribute\n");
-		text[count++] = strdup("#define VARYING varying\n");
-	}
-	else if (version < 3.3f)
+	S32 major_version = gGLManager.mGLSLVersionMajor;
+	S32 minor_version = gGLManager.mGLSLVersionMinor;
+	
+	if (major_version == 1 && minor_version < 30)
 	{
-		//set version to 1.20
-		text[count++] = strdup("#version 120\n");
-		text[count++] = strdup("#define FXAA_GLSL_120 1\n");
-		text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
-		text[count++] = strdup("#define ATTRIBUTE attribute\n");
-		text[count++] = strdup("#define VARYING varying\n");
+		if (minor_version < 10)
+		{
+			//should NEVER get here -- if major version is 1 and minor version is less than 10, 
+			// viewer should never attempt to use shaders, continuing will result in undefined behavior
+			llerrs << "Unsupported GLSL Version." << llendl;
+		}
+
+		if (minor_version <= 19)
+		{
+			text[count++] = strdup("#version 110\n");
+			text[count++] = strdup("#define ATTRIBUTE attribute\n");
+			text[count++] = strdup("#define VARYING varying\n");
+			text[count++] = strdup("#define VARYING_FLAT varying\n");
+		}
+		else if (minor_version <= 29)
+		{
+			//set version to 1.20
+			text[count++] = strdup("#version 120\n");
+			text[count++] = strdup("#define FXAA_GLSL_120 1\n");
+			text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
+			text[count++] = strdup("#define ATTRIBUTE attribute\n");
+			text[count++] = strdup("#define VARYING varying\n");
+			text[count++] = strdup("#define VARYING_FLAT varying\n");
+		}
 	}
 	else
 	{  
-		if (version < 4.f)
+		if (major_version < 4)
 		{
 			//set version to 1.30
 			text[count++] = strdup("#version 130\n");
@@ -618,13 +626,17 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		{ //"varying" state is "out" in a vertex program, "in" in a fragment program 
 			// ("varying" is deprecated after version 1.20)
 			text[count++] = strdup("#define VARYING out\n");
+			text[count++] = strdup("#define VARYING_FLAT flat out\n");
 		}
 		else
 		{
 			text[count++] = strdup("#define VARYING in\n");
+			text[count++] = strdup("#define VARYING_FLAT flat in\n");
 		}
 
 		//backwards compatibility with legacy texture lookup syntax
+		text[count++] = strdup("#define texture2D texture\n");
+		text[count++] = strdup("#define texture2DRect texture\n");
 		text[count++] = strdup("#define textureCube texture\n");
 		text[count++] = strdup("#define texture2DLod textureLod\n");
 		text[count++] = strdup("#define	shadow2D(a,b) vec2(texture(a,b))\n");
@@ -651,11 +663,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		.
 		uniform sampler2D texN;
 		
-		VARYING float vary_texture_index;
+		VARYING uvec4 vary_texture_index;
 
 		vec4 diffuseLookup(vec2 texcoord)
 		{
-			switch (int(vary_texture_index+0.25))
+			switch (vary_texture_index.r))
 			{
 				case 0: return texture2D(tex0, texcoord);
 				case 1: return texture2D(tex1, texcoord);
@@ -679,7 +691,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 
 		if (texture_index_channels > 1)
 		{
-			text[count++] = strdup("VARYING float vary_texture_index;\n");
+			text[count++] = strdup("VARYING_FLAT uvec4 vary_texture_index;\n");
 		}
 
 		text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
@@ -691,9 +703,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 			text[count++] = strdup("return texture2D(tex0, texcoord);\n");
 			text[count++] = strdup("}\n");
 		}
-		else if (gGLManager.mGLVersion >= 3.f)
-		{ 
-			text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
+		else if (major_version > 1 || minor_version >= 30)
+		{  //switches are supported in GLSL 1.30 and later
+			text[count++] = strdup("\tswitch (vary_texture_index.r)\n");
 			text[count++] = strdup("\t{\n");
 		
 			//switch body
@@ -708,28 +720,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 			text[count++] = strdup("}\n");
 		}
 		else
-		{
-			//switches aren't supported, make block that looks like:
-			/*
-				int ti = int(vary_texture_index+0.25);
-				if (ti == 0) return texture2D(tex0, texcoord);
-				if (ti == 1) return texture2D(tex1, texcoord);
-				.
-				.
-				.
-				if (ti == N) return texture2D(texN, texcoord);
-			*/
-				
-			text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
-			for (S32 i = 0; i < texture_index_channels; ++i)
-			{
-				std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
-				text[count++] = strdup(if_str.c_str());
-			}
-
-			text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
-			text[count++] = strdup("}\n");
-		}			
+		{ //should never get here.  Indexed texture rendering requires GLSL 1.30 or later 
+			// (for passing integers between vertex and fragment shaders)
+			llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
+		}
 	}
 
 	//copy file into memory
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index e4a5cd0299..b2438ef824 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -284,6 +284,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 	{
 		bool error = false;
 
+		if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
+		{
+			//make sure texture index is disabled
+			data_mask = data_mask & ~MAP_TEXTURE_INDEX;
+		}
+
 		if (LLGLSLShader::sNoFixedFunction)
 		{
 			for (U32 i = 0; i < TYPE_MAX; ++i)
@@ -1193,7 +1199,7 @@ void LLVertexBuffer::setupVertexArray()
 		1, //TYPE_WEIGHT,
 		4, //TYPE_WEIGHT4,
 		4, //TYPE_CLOTHWEIGHT,
-		1, //TYPE_TEXTURE_INDEX
+		4, //TYPE_TEXTURE_INDEX
 	};
 
 	U32 attrib_type[] =
@@ -1210,7 +1216,24 @@ void LLVertexBuffer::setupVertexArray()
 		GL_FLOAT, //TYPE_WEIGHT,
 		GL_FLOAT, //TYPE_WEIGHT4,
 		GL_FLOAT, //TYPE_CLOTHWEIGHT,
-		GL_FLOAT, //TYPE_TEXTURE_INDEX
+		GL_UNSIGNED_BYTE, //TYPE_TEXTURE_INDEX
+	};
+
+	bool attrib_integer[] = 
+	{
+		false, //TYPE_VERTEX,
+		false, //TYPE_NORMAL,
+		false, //TYPE_TEXCOORD0,
+		false, //TYPE_TEXCOORD1,
+		false, //TYPE_TEXCOORD2,
+		false, //TYPE_TEXCOORD3,
+		false, //TYPE_COLOR,
+		false, //TYPE_EMISSIVE,
+		false, //TYPE_BINORMAL,
+		false, //TYPE_WEIGHT,
+		false, //TYPE_WEIGHT4,
+		false, //TYPE_CLOTHWEIGHT,
+		true, //TYPE_TEXTURE_INDEX
 	};
 
 	U32 attrib_normalized[] =
@@ -1238,7 +1261,19 @@ void LLVertexBuffer::setupVertexArray()
 		if (mTypeMask & (1 << i))
 		{
 			glEnableVertexAttribArrayARB(i);
-			glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); 
+
+			if (attrib_integer)
+			{
+				//glVertexattribIPointer requires GLSL 1.30 or later
+				if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
+				{
+					glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]); 
+				}
+			}
+			else
+			{
+				glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); 
+			}
 		}
 		else
 		{
@@ -2220,11 +2255,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 			void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
 			glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
 		}
-		if (data_mask & MAP_TEXTURE_INDEX)
+		if (data_mask & MAP_TEXTURE_INDEX && 
+				(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
 		{
 			S32 loc = TYPE_TEXTURE_INDEX;
 			void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
-			glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+			glVertexAttribIPointer(loc, 4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
 		}
 		if (data_mask & MAP_VERTEX)
 		{
-- 
cgit v1.2.3


From 76a27f5100666739aae53c0988318a6dae647666 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 13 Feb 2012 13:55:51 -0600
Subject: SH-2964 Fix for shader compilation error on some older NVIDIA cards.

---
 indra/llrender/llshadermgr.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 321b139181..269f78c8cd 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -663,7 +663,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		.
 		uniform sampler2D texN;
 		
-		VARYING uvec4 vary_texture_index;
+		VARYING ivec4 vary_texture_index;
 
 		vec4 diffuseLookup(vec2 texcoord)
 		{
@@ -691,7 +691,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 
 		if (texture_index_channels > 1)
 		{
-			text[count++] = strdup("VARYING_FLAT uvec4 vary_texture_index;\n");
+			text[count++] = strdup("VARYING_FLAT ivec4 vary_texture_index;\n");
 		}
 
 		text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
-- 
cgit v1.2.3


From 80505ddf68c8a0a962a720a1c1d2a894df47157f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 13 Feb 2012 15:02:07 -0600
Subject: SH-2908 Fix for linux build.

---
 indra/llrender/llgl.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 79d4415117..e855dda57d 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -344,7 +344,6 @@ PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;
 PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;
 PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;
 PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
-PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
 PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
 PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
-- 
cgit v1.2.3


From 64c89ee2c51c539d38d4d55807b18172d6606514 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 13 Feb 2012 15:41:21 -0600
Subject: SH-2908 Fix for mac build

---
 indra/llrender/llgl.cpp           | 9 +++++++++
 indra/llrender/llvertexbuffer.cpp | 4 ++++
 2 files changed, 13 insertions(+)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index e855dda57d..197bc2b422 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -561,6 +561,15 @@ bool LLGLManager::initGL()
 	if (mGLVersion >= 2.f)
 	{
 		parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
+
+#if LL_DARWIN
+		//never use GLSL greater than 1.20 on OSX
+		if (mGLSLVersionMajor > 1 || mGLSLVersionMinor >= 30)
+		{
+			mGLSLVersionMajor = 1;
+			mGLSLVersionMinor = 20;
+		}
+#endif
 	}
 
 	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index b2438ef824..a7f0170658 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1264,11 +1264,13 @@ void LLVertexBuffer::setupVertexArray()
 
 			if (attrib_integer)
 			{
+#if !LL_DARWIN
 				//glVertexattribIPointer requires GLSL 1.30 or later
 				if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
 				{
 					glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]); 
 				}
+#endif
 			}
 			else
 			{
@@ -2258,9 +2260,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 		if (data_mask & MAP_TEXTURE_INDEX && 
 				(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
 		{
+#if !LL_DARWIN
 			S32 loc = TYPE_TEXTURE_INDEX;
 			void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
 			glVertexAttribIPointer(loc, 4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+#endif
 		}
 		if (data_mask & MAP_VERTEX)
 		{
-- 
cgit v1.2.3


From 3267b42ee521a7a059e0e87cba75a3d32af678e5 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 13 Feb 2012 18:26:48 -0600
Subject: SH-2908 Temporary fix for mac build

---
 indra/llrender/llglslshader.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index a879a18895..4b7e639aed 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -109,7 +109,9 @@ void LLGLSLShader::unload()
 		glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
 		for (GLsizei i = 0; i < count; i++)
 		{
+#if !LL_DARWIN
 			if (glIsProgramARB(obj[i]))
+#endif
 			{
 				glDeleteObjectARB(obj[i]);
 			}
-- 
cgit v1.2.3


From 8d12038ef674dca701f313431b1089458816f638 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 17 Feb 2012 15:06:48 -0600
Subject: SH-2908 Potential fix for precision complaints from some AMD OpenGL
 3.1 implementations.

---
 indra/llrender/llshadermgr.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 269f78c8cd..9aeb1a99f8 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -611,6 +611,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		{
 			//set version to 1.30
 			text[count++] = strdup("#version 130\n");
+
+			//some implementations of GLSL 1.30 require integer precision be explicitly declared
+			text[count++] = strdup("precision mediump int;\n");
 		}
 		else
 		{ //set version to 400
@@ -663,7 +666,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		.
 		uniform sampler2D texN;
 		
-		VARYING ivec4 vary_texture_index;
+		VARYING_FLAT ivec4 vary_texture_index;
 
 		vec4 diffuseLookup(vec2 texcoord)
 		{
-- 
cgit v1.2.3


From e1a71a97cd00d70fedeb6191b6ebb10361019ee1 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 21 Feb 2012 14:02:09 -0600
Subject: SH-2908 Potential fix for pink textures on some OpenGL 3.1
 implementations.

---
 indra/llrender/llshadermgr.cpp | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 9aeb1a99f8..e1cd8fa62d 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -614,6 +614,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 
 			//some implementations of GLSL 1.30 require integer precision be explicitly declared
 			text[count++] = strdup("precision mediump int;\n");
+			text[count++] = strdup("precision highp float;\n");
 		}
 		else
 		{ //set version to 400
@@ -668,20 +669,22 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		
 		VARYING_FLAT ivec4 vary_texture_index;
 
+		vec4 ret = vec4(1,0,1,1);
+
 		vec4 diffuseLookup(vec2 texcoord)
 		{
 			switch (vary_texture_index.r))
 			{
-				case 0: return texture2D(tex0, texcoord);
-				case 1: return texture2D(tex1, texcoord);
-				case 2: return texture2D(tex2, texcoord);
+				case 0: ret = texture2D(tex0, texcoord); break;
+				case 1: ret = texture2D(tex1, texcoord); break;
+				case 2: ret = texture2D(tex2, texcoord); break;
 				.
 				.
 				.
-				case N: return texture2D(texN, texcoord);
+				case N: return texture2D(texN, texcoord); break;
 			}
 
-			return vec4(0,0,0,0);
+			return ret;
 		}
 		*/
 
@@ -708,18 +711,19 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		}
 		else if (major_version > 1 || minor_version >= 30)
 		{  //switches are supported in GLSL 1.30 and later
+			text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
 			text[count++] = strdup("\tswitch (vary_texture_index.r)\n");
 			text[count++] = strdup("\t{\n");
 		
 			//switch body
 			for (S32 i = 0; i < texture_index_channels; ++i)
 			{
-				std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
+				std::string case_str = llformat("\t\tcase %d: ret = texture2D(tex%d, texcoord); break;\n", i, i);
 				text[count++] = strdup(case_str.c_str());
 			}
 
 			text[count++] = strdup("\t}\n");
-			text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
+			text[count++] = strdup("\treturn ret;\n");
 			text[count++] = strdup("}\n");
 		}
 		else
-- 
cgit v1.2.3


From 8f261582b80d7d4a61cf8bb42c0429fa58f0c186 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 22 Feb 2012 14:30:24 -0600
Subject: SH-2908 Fix for crash when enabling Lighting and Shadows on some AMD
 GPUs

---
 indra/llrender/llshadermgr.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index e1cd8fa62d..b28a97adaa 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -644,6 +644,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		text[count++] = strdup("#define textureCube texture\n");
 		text[count++] = strdup("#define texture2DLod textureLod\n");
 		text[count++] = strdup("#define	shadow2D(a,b) vec2(texture(a,b))\n");
+		text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
 	}
 
 	//copy preprocessor definitions into buffer
-- 
cgit v1.2.3


From a128836dedf25dc56807cced9316fbaa09a7f019 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 23 Feb 2012 13:41:19 -0600
Subject: SH-2908 Fix for linux build.

---
 indra/llrender/llvertexbuffer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index a7f0170658..8b5503229f 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1262,7 +1262,7 @@ void LLVertexBuffer::setupVertexArray()
 		{
 			glEnableVertexAttribArrayARB(i);
 
-			if (attrib_integer)
+			if (attrib_integer[i])
 			{
 #if !LL_DARWIN
 				//glVertexattribIPointer requires GLSL 1.30 or later
-- 
cgit v1.2.3


From 353907bac61e6db0aca16e7e43f13f627b414dca Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 28 Feb 2012 16:10:04 -0600
Subject: SH-2908 Fix for incompatibility issue with GLSL 1.30

---
 indra/llrender/llshadermgr.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b28a97adaa..7d384450e6 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -640,11 +640,15 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 
 		//backwards compatibility with legacy texture lookup syntax
 		text[count++] = strdup("#define texture2D texture\n");
-		text[count++] = strdup("#define texture2DRect texture\n");
 		text[count++] = strdup("#define textureCube texture\n");
 		text[count++] = strdup("#define texture2DLod textureLod\n");
 		text[count++] = strdup("#define	shadow2D(a,b) vec2(texture(a,b))\n");
-		text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
+
+		if (major_version > 1 || minor_version >= 40)
+		{ //GLSL 1.40 replaces texture2DRect et al with texture
+			text[count++] = strdup("#define texture2DRect texture\n");
+			text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
+		}
 	}
 
 	//copy preprocessor definitions into buffer
-- 
cgit v1.2.3


From f53fa08c7069f7f604f3fcab70d65af8bb616f08 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 2 Mar 2012 13:35:10 -0600
Subject: MAINT-708 Use texture compression to minimize memory bloat
 (experimental)

---
 indra/llrender/llgl.cpp           | 13 ++++++++++++
 indra/llrender/llimagegl.cpp      | 43 ++++++++++++++++++++++++++++++++++-----
 indra/llrender/llimagegl.h        |  7 +++++--
 indra/llrender/llrendertarget.cpp |  4 ++--
 4 files changed, 58 insertions(+), 9 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 197bc2b422..b99465ee47 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -94,6 +94,10 @@ void APIENTRY gl_debug_callback(GLenum source,
 	llwarns << "Severity: " << std::hex << severity << llendl;
 	llwarns << "Message: " << message << llendl;
 	llwarns << "-----------------------" << llendl;
+	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+	{
+		llerrs << "Halting on GL Error" << llendl;
+	}
 }
 #endif
 
@@ -572,6 +576,15 @@ bool LLGLManager::initGL()
 #endif
 	}
 
+	if (mGLVersion >= 3.f && LLImageGL::sCompressTextures)
+	{ //use texture compression
+		glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
+	}
+	else
+	{ //GL version is < 3.0, always disable texture compression
+		LLImageGL::sCompressTextures = false;
+	}
+	
 	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
 	// from being recognized as ATI.
 	if (mGLVendor.substr(0,4) == "ATI ")
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 78591ddd38..17131c9d8a 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -57,6 +57,7 @@ BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE;
 F32 LLImageGL::sLastFrameTime			= 0.f;
 BOOL LLImageGL::sAllowReadBackRaw       = FALSE ;
 LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
+bool LLImageGL::sCompressTextures = false;
 
 std::set<LLImageGL*> LLImageGL::sImageList;
 
@@ -477,6 +478,8 @@ void LLImageGL::init(BOOL usemipmaps)
 	mDiscardLevelInAtlas = -1 ;
 	mTexelsInAtlas = 0 ;
 	mTexelsInGLTexture = 0 ;
+
+	mAllowCompression = true;
 	
 	mTarget = GL_TEXTURE_2D;
 	mBindTarget = LLTexUnit::TT_TEXTURE;
@@ -705,7 +708,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						stop_glerror();
 					}
 						
-					LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
+					LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
 					if (gl_level == 0)
 					{
 						analyzeAlpha(data_in, w, h);
@@ -747,7 +750,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
 								 w, h, 
 								 mFormatPrimary, mFormatType,
-								 data_in);
+								 data_in, mAllowCompression);
 					analyzeAlpha(data_in, w, h);
 					stop_glerror();
 
@@ -805,7 +808,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 							stop_glerror();
 						}
 
-						LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
+						LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
 						if (m == 0)
 						{
 							analyzeAlpha(data_in, w, h);
@@ -863,7 +866,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 			}
 
 			LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
-						 mFormatPrimary, mFormatType, (GLvoid *)data_in);
+						 mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
 			analyzeAlpha(data_in, w, h);
 			
 			updatePickMask(w, h, data_in);
@@ -1110,7 +1113,7 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
 }
 
 // static
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
 {
 	bool use_scratch = false;
 	U32* scratch = NULL;
@@ -1173,6 +1176,36 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
 		}
 	}
 
+	if (LLImageGL::sCompressTextures && allow_compression)
+	{
+		switch (intformat)
+		{
+			case GL_RGB: 
+			case GL_RGB8:
+				intformat = GL_COMPRESSED_RGB; 
+				break;
+			case GL_RGBA:
+			case GL_RGBA8:
+				intformat = GL_COMPRESSED_RGBA; 
+				break;
+			case GL_LUMINANCE:
+			case GL_LUMINANCE8:
+				intformat = GL_COMPRESSED_LUMINANCE;
+				break;
+			case GL_LUMINANCE_ALPHA:
+			case GL_LUMINANCE8_ALPHA8:
+				intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+				break;
+			case GL_ALPHA:
+			case GL_ALPHA8:
+				intformat = GL_COMPRESSED_ALPHA;
+				break;
+			default:
+				llwarns << "Could not compress format: " << std::hex << intformat << llendl;
+				break;
+		}
+	}
+
 	stop_glerror();
 	glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
 	stop_glerror();
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2cfb15b0d9..e23005fe29 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -94,12 +94,13 @@ public:
 	
 	void setSize(S32 width, S32 height, S32 ncomponents);
 	void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
+	void setAllowCompression(bool allow) { mAllowCompression = allow; }
 
 	// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() 
 	// for tracking purposes and will be deprecated in the future
 	static void generateTextures(S32 numTextures, U32 *textures);
 	static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
-	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
+	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
 
 	BOOL createGLTexture() ;
 	BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, 
@@ -209,6 +210,8 @@ private:
 	U32      mTexelsInAtlas ;
 	U32      mTexelsInGLTexture;
 
+	bool mAllowCompression;
+
 protected:
 	LLGLenum mTarget;		// Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
 	LLTexUnit::eTextureType mBindTarget;	// Normally TT_TEXTURE, sometimes something else (ex. cube maps)
@@ -246,7 +249,7 @@ public:
 	static BOOL sGlobalUseAnisotropic;
 	static LLImageGL* sDefaultGLTexture ;	
 	static BOOL sAutomatedTest;
-
+	static bool sCompressTextures;			//use GL texture compression
 #if DEBUG_MISS
 	BOOL mMissed; // Missed on last bind?
 	BOOL getMissed() const { return mMissed; };
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index ef2a7395da..780f1dc484 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -143,7 +143,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
 
 	{
 		clear_glerror();
-		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
 		if (glGetError() != GL_NO_ERROR)
 		{
 			llwarns << "Could not allocate color buffer for render target." << llendl;
@@ -223,7 +223,7 @@ bool LLRenderTarget::allocateDepth()
 		U32 internal_type = LLTexUnit::getInternalType(mUsage);
 		stop_glerror();
 		clear_glerror();
-		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
 		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
-- 
cgit v1.2.3


From cd468364a77ca184133f8c49c9042cefae5c6ce1 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 7 Mar 2012 17:26:43 -0600
Subject: MAINT-708 Don't compress UI textures.  Use GL_NICEST as compression
 hint to avoid artifacts.

---
 indra/llrender/llgl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index b99465ee47..fdb674c433 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -578,7 +578,7 @@ bool LLGLManager::initGL()
 
 	if (mGLVersion >= 3.f && LLImageGL::sCompressTextures)
 	{ //use texture compression
-		glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
+		glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
 	}
 	else
 	{ //GL version is < 3.0, always disable texture compression
-- 
cgit v1.2.3


From 83e69659e2c950bec02df8c8e1b15fbc34ca1dc6 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 8 Mar 2012 15:22:56 -0600
Subject: MAINT-708 Add checkbox to hardware settings for controlling texture
 compression.  Default texture compression to on for cards with 512MB of VRAM
 or less, off otherwise.

---
 indra/llrender/llgl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index fdb674c433..3f78ab20d0 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -576,7 +576,7 @@ bool LLGLManager::initGL()
 #endif
 	}
 
-	if (mGLVersion >= 3.f && LLImageGL::sCompressTextures)
+	if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
 	{ //use texture compression
 		glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
 	}
-- 
cgit v1.2.3


From 3953477ee5a9f60346a1d448b74bb5829bf18c56 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 13 Mar 2012 17:34:11 -0500
Subject: MAINT-708 Reduce amount of video memory consumed by vertex buffer
 objects.

---
 indra/llrender/llvertexbuffer.cpp | 159 +++++++++++++++++++++++++++++++-------
 indra/llrender/llvertexbuffer.h   |   6 +-
 2 files changed, 136 insertions(+), 29 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 8b5503229f..a5e2342367 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -38,6 +38,8 @@
 #include "llglslshader.h"
 #include "llmemory.h"
 
+#define LL_VBO_POOLING 0
+
 //Next Highest Power Of Two
 //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
 U32 nhpo2(U32 v)
@@ -49,6 +51,35 @@ U32 nhpo2(U32 v)
 	return r;
 }
 
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+	llassert(i > 0);
+	llassert(nhpo2(i) == i);
+
+	U32 r = 0;
+
+	while (i >>= 1) ++r;
+
+	return r;
+}
+
+
+const U32 LL_VBO_BLOCK_SIZE = 2048;
+
+U32 vbo_block_size(U32 size)
+{ //what block size will fit size?
+	U32 mod = size % LL_VBO_BLOCK_SIZE;
+	return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+}
+
+U32 vbo_block_index(U32 size)
+{
+	return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+}
+
+
 
 //============================================================================
 
@@ -57,7 +88,11 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB
 LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
 LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
 LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+
 U32 LLVBOPool::sBytesPooled = 0;
+U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
 
 LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
 U32 LLVertexBuffer::sBindCount = 0;
@@ -74,6 +109,7 @@ U32 LLVertexBuffer::sLastMask = 0;
 bool LLVertexBuffer::sVBOActive = false;
 bool LLVertexBuffer::sIBOActive = false;
 U32 LLVertexBuffer::sAllocatedBytes = 0;
+U32 LLVertexBuffer::sVertexCount = 0;
 bool LLVertexBuffer::sMapped = false;
 bool LLVertexBuffer::sUseStreamDraw = true;
 bool LLVertexBuffer::sUseVAO = false;
@@ -134,39 +170,35 @@ public:
 };
 
 
-//which power of 2 is i?
-//assumes i is a power of 2 > 0
-U32 wpo2(U32 i)
-{
-	llassert(i > 0);
-	llassert(nhpo2(i) == i);
-
-	U32 r = 0;
-
-	while (i >>= 1) ++r;
-
-	return r;
-}
-
 volatile U8* LLVBOPool::allocate(U32& name, U32 size)
 {
-	llassert(nhpo2(size) == size);
+	llassert(vbo_block_size(size) == size);
+	
+	volatile U8* ret = NULL;
+
+#if LL_VBO_POOLING
 
-	U32 i = wpo2(size);
+	U32 i = vbo_block_index(size);
 
 	if (mFreeList.size() <= i)
 	{
 		mFreeList.resize(i+1);
 	}
 
-	volatile U8* ret = NULL;
-
 	if (mFreeList[i].empty())
 	{
 		//make a new buffer
 		glGenBuffersARB(1, &name);
 		glBindBufferARB(mType, name);
-		LLVertexBuffer::sAllocatedBytes += size;
+
+		if (mType == GL_ARRAY_BUFFER_ARB)
+		{
+			LLVertexBuffer::sAllocatedBytes += size;
+		}
+		else
+		{
+			LLVertexBuffer::sAllocatedIndexBytes += size;
+		}
 
 		if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
 		{
@@ -185,19 +217,55 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
 		name = mFreeList[i].front().mGLName;
 		ret = mFreeList[i].front().mClientData;
 
-		sBytesPooled -= size;
+		if (mType == GL_ARRAY_BUFFER_ARB)
+		{
+			sBytesPooled -= size;
+		}
+		else
+		{
+			sIndexBytesPooled -= size;
+		}
 
 		mFreeList[i].pop_front();
 	}
+#else //no pooling
+
+	glGenBuffersARB(1, &name);
+	glBindBufferARB(mType, name);
+
+	if (mType == GL_ARRAY_BUFFER_ARB)
+	{
+		LLVertexBuffer::sAllocatedBytes += size;
+	}
+	else
+	{
+		LLVertexBuffer::sAllocatedIndexBytes += size;
+	}
+
+	if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
+	{
+		glBufferDataARB(mType, size, 0, mUsage);
+		ret = (U8*) ll_aligned_malloc_16(size);
+	}
+	else
+	{ //always use a true hint of static draw when allocating non-client-backed buffers
+		glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+	}
+
+	glBindBufferARB(mType, 0);
+
+#endif
 
 	return ret;
 }
 
 void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 {
-	llassert(nhpo2(size) == size);
+	llassert(vbo_block_size(size) == size);
 
-	U32 i = wpo2(size);
+#if LL_VBO_POOLING
+
+	U32 i = vbo_block_index(size);
 
 	llassert(mFreeList.size() > i);
 
@@ -211,9 +279,29 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 	}
 	else
 	{
-		sBytesPooled += size;
+		if (mType == GL_ARRAY_BUFFER_ARB)
+		{
+			sBytesPooled += size;
+		}
+		else
+		{
+			sIndexBytesPooled += size;
+		}
 		mFreeList[i].push_back(rec);
 	}
+#else //no pooling
+	glDeleteBuffersARB(1, &name);
+	ll_aligned_free_16((U8*) buffer);
+
+	if (mType == GL_ARRAY_BUFFER_ARB)
+	{
+		LLVertexBuffer::sAllocatedBytes -= size;
+	}
+	else
+	{
+		LLVertexBuffer::sAllocatedIndexBytes -= size;
+	}
+#endif
 }
 
 void LLVBOPool::cleanup()
@@ -237,8 +325,16 @@ void LLVBOPool::cleanup()
 
 			l.pop_front();
 
-			LLVertexBuffer::sAllocatedBytes -= size;
-			sBytesPooled -= size;
+			if (mType == GL_ARRAY_BUFFER_ARB)
+			{
+				sBytesPooled -= size;
+				LLVertexBuffer::sAllocatedBytes -= size;
+			}
+			else
+			{
+				sIndexBytesPooled -= size;
+				LLVertexBuffer::sAllocatedIndexBytes -= size;
+			}
 		}
 
 		size *= 2;
@@ -261,7 +357,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
 	sizeof(F32),	   // TYPE_WEIGHT,
 	sizeof(LLVector4), // TYPE_WEIGHT4,
 	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
-	sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
+	sizeof(U32),	   // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
 };
 
 U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = 
@@ -898,6 +994,9 @@ LLVertexBuffer::~LLVertexBuffer()
 	
 	mFence = NULL;
 
+	sVertexCount -= mNumVerts;
+	sIndexCount -= mNumIndices;
+
 	llassert_always(!mMappedData && !mMappedIndexData);
 };
 
@@ -929,7 +1028,7 @@ void LLVertexBuffer::waitFence() const
 
 void LLVertexBuffer::genBuffer(U32 size)
 {
-	mSize = nhpo2(size);
+	mSize = vbo_block_size(size);
 
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
@@ -945,7 +1044,7 @@ void LLVertexBuffer::genBuffer(U32 size)
 
 void LLVertexBuffer::genIndices(U32 size)
 {
-	mIndicesSize = nhpo2(size);
+	mIndicesSize = vbo_block_size(size);
 
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
@@ -1121,7 +1220,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
 		createGLBuffer(needed_size);
 	}
 
+	sVertexCount -= mNumVerts;
 	mNumVerts = nverts;
+	sVertexCount += mNumVerts;
 }
 
 void LLVertexBuffer::updateNumIndices(S32 nindices)
@@ -1137,7 +1238,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
 		createGLIndices(needed_size);
 	}
 
+	sIndexCount -= mNumIndices;
 	mNumIndices = nindices;
+	sIndexCount += mNumIndices;
 }
 
 void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index d859199663..ceaa70c3b6 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -55,7 +55,8 @@ class LLVBOPool
 {
 public:
 	static U32 sBytesPooled;
-	
+	static U32 sIndexBytesPooled;
+
 	LLVBOPool(U32 vboUsage, U32 vboType)
 		: mUsage(vboUsage)
 		, mType(vboType)
@@ -332,6 +333,9 @@ public:
 	static bool sIBOActive;
 	static U32 sLastMask;
 	static U32 sAllocatedBytes;
+	static U32 sAllocatedIndexBytes;
+	static U32 sVertexCount;
+	static U32 sIndexCount;
 	static U32 sBindCount;
 	static U32 sSetCount;
 };
-- 
cgit v1.2.3


From 3894701180e436f313afdb94ed9b5d95f15474ce Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 14 Mar 2012 16:13:23 -0500
Subject: MAINT-708 Fix for pink when enabling RenderUseVAO

---
 indra/llrender/llvertexbuffer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index a5e2342367..b4899209c4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -357,7 +357,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
 	sizeof(F32),	   // TYPE_WEIGHT,
 	sizeof(LLVector4), // TYPE_WEIGHT4,
 	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
-	sizeof(U32),	   // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
+	sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
 };
 
 U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = 
-- 
cgit v1.2.3


From 0af7b7038f9e063cf71808e7d7ceaedcb17b83a9 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 21 Mar 2012 16:05:57 -0500
Subject: MAINT-804, MAINT-810 Disable framebuffer object usage on intel chips
 (implicitly disables lighting and shadows)

---
 indra/llrender/llgl.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 3f78ab20d0..c629ac33cc 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -748,6 +748,11 @@ bool LLGLManager::initGL()
 	}
 #endif
 
+	if (mIsIntel)
+	{ //never try to use framebuffer objects on intel (crashy)
+		mHasFramebufferObject = FALSE;
+	}
+
 	if (mHasFramebufferObject)
 	{
 		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
-- 
cgit v1.2.3


From ce0f455b7cb5a5d45e7682e4a4180b577eda3c5a Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 26 Mar 2012 13:09:09 -0500
Subject: MAINT-806 Fix for some shaders failing to link on ATI x800.

---
 indra/llrender/llgl.cpp | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c629ac33cc..a819ab0b79 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -605,11 +605,8 @@ bool LLGLManager::initGL()
 #endif // LL_WINDOWS
 
 #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
-		// release 7277 is a point at which we verify that ATI OpenGL
-		// drivers get pretty stable with SL, ~Catalyst 8.2,
-		// for both Win32 and Linux.
-		if (mDriverVersionRelease < 7277 &&
-		    mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
+		// count any pre OpenGL 3.0 implementation as an old driver
+		if (mGLVersion < 3.f) 
 		{
 			mATIOldDriver = TRUE;
 		}
-- 
cgit v1.2.3