diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index d3b2d9fa740aaa31efd37b42508bd1e43df5eea5..a9248d4d738d1f9d66452acd80c4ebc03b12f5d9 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 953546a36f351cc0b7572ed67829fa46166cb4dd..80752231d70f94bde9ec8f0e6b524e05e119230d 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 7c0699d72f7a55bd2ba01a7e969901cd924e48d5..ca29bf3143384575a9b43095221b6d84986e53b9 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 49a20d5ef99f854f76357798063a689da07f07c4..2d84c5d7deb58aa4a9e138a8b4a2ec1be0987649 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;