From 997b360747bb21564f0ef89c3b3e065ea3ec0716 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 11 Jul 2012 15:17:13 -0500
Subject: [PATCH] MAINT-794 Fix for assert on loading some types of objects
 before their parents.

---
 indra/llrender/llshadermgr.cpp                | 39 ++++++++++++-------
 indra/llrender/llvertexbuffer.cpp             |  6 +--
 .../class1/objects/indexedTextureV.glsl       |  4 +-
 indra/newview/llface.cpp                      | 11 ++----
 4 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index d3b2d9fa74..a9248d4d73 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -702,7 +702,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 
 		if (texture_index_channels > 1)
 		{
-			text[count++] = strdup("VARYING_FLAT ivec4 vary_texture_index;\n");
+			text[count++] = strdup("VARYING_FLAT int vary_texture_index;\n");
 		}
 
 		text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
@@ -716,20 +716,33 @@ 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: ret = texture2D(tex%d, texcoord); break;\n", i, i);
-				text[count++] = strdup(case_str.c_str());
+			if (gGLManager.mIsNVIDIA)
+			{ //switches are unreliable on some NVIDIA drivers
+				for (U32 i = 0; i < texture_index_channels; ++i)
+				{
+					std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture2D(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i); 
+					text[count++] = strdup(if_string.c_str());
+				}
+				text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
+				text[count++] = strdup("}\n");
 			}
+			else
+			{
+				text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
+				text[count++] = strdup("\tswitch (vary_texture_index)\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);
+					text[count++] = strdup(case_str.c_str());
+				}
 
-			text[count++] = strdup("\t}\n");
-			text[count++] = strdup("\treturn ret;\n");
-			text[count++] = strdup("}\n");
+				text[count++] = strdup("\t}\n");
+				text[count++] = strdup("\treturn ret;\n");
+				text[count++] = strdup("}\n");
+			}
 		}
 		else
 		{ //should never get here.  Indexed texture rendering requires GLSL 1.30 or later 
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 953546a36f..80752231d7 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1330,7 +1330,7 @@ void LLVertexBuffer::setupVertexArray()
 		1, //TYPE_WEIGHT,
 		4, //TYPE_WEIGHT4,
 		4, //TYPE_CLOTHWEIGHT,
-		4, //TYPE_TEXTURE_INDEX
+		1, //TYPE_TEXTURE_INDEX
 	};
 
 	U32 attrib_type[] =
@@ -1347,7 +1347,7 @@ void LLVertexBuffer::setupVertexArray()
 		GL_FLOAT, //TYPE_WEIGHT,
 		GL_FLOAT, //TYPE_WEIGHT4,
 		GL_FLOAT, //TYPE_CLOTHWEIGHT,
-		GL_UNSIGNED_BYTE, //TYPE_TEXTURE_INDEX
+		GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX
 	};
 
 	bool attrib_integer[] = 
@@ -2404,7 +2404,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 #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);
+			glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
 #endif
 		}
 		if (data_mask & MAP_VERTEX)
diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
index 7c0699d72f..ca29bf3143 100644
--- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
@@ -23,9 +23,9 @@
  * $/LicenseInfo$
  */
 
-ATTRIBUTE ivec4 texture_index;
+ATTRIBUTE int texture_index;
 
-VARYING_FLAT ivec4 vary_texture_index;
+VARYING_FLAT int vary_texture_index;
 
 void passTextureIndex()
 {
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 49a20d5ef9..2d84c5d7de 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1945,15 +1945,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 			LLVector4a texIdx;
 
-			U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+			S32 index = mTextureIndex < 255 ? mTextureIndex : 0;
 
 			F32 val = 0.f;
-			U8* vp = (U8*) &val;
-			vp[0] = index;
-			vp[1] = 0;
-			vp[2] = 0;
-			vp[3] = 0;
-
+			S32* vp = (S32*) &val;
+			*vp = index;
+			
 			llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
 
 			LLVector4Logical mask;
-- 
GitLab