diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 54a41c9d23c0af759d00e1d514de480dc8160216..d18512f6133e437256ffb735ec11d1ca3d0e3868 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -999,6 +999,12 @@ void LLGLManager::initExtensions()
 	mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
 #endif
 	
+#ifdef GL_EXT_texture_sRGB_decode
+    mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts);
+#else
+    mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts);
+#endif
+
 	mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
 
 	mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 362fda5fb1050ddfa57d3a7784a02dacf727baf1..a7faea7d3315396f5e875e192fa0364f7ae99b90 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -118,6 +118,7 @@ class LLGLManager
 	BOOL mHasDebugOutput;
 	BOOL mHassRGBTexture;
 	BOOL mHassRGBFramebuffer;
+    BOOL mHasTexturesRGBDecode;
 
 	// Vendor-specific extensions
 	BOOL mIsATI;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 53a30a63c4e7e873f0867d69d6546851bdddf659..5dc61d0e8f997bfed1e707b2252b23c262b9f33e 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -105,7 +105,7 @@ LLTexUnit::LLTexUnit(S32 index)
 	mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
 	mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
 	mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
-	mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
+    mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR),
 	mHasMipMaps(false),
 	mIndex(index)
 {
@@ -162,6 +162,8 @@ void LLTexUnit::refreshState(void)
 		setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false);
 		setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true);
 	}
+
+    setTextureColorSpace(mTexColorSpace);
 }
 
 void LLTexUnit::activate(void)
@@ -191,7 +193,6 @@ void LLTexUnit::enable(eTextureType type)
 			stop_glerror();
 		}
 		mCurrTexType = type;
-
 		gGL.flush();
 		if (!LLGLSLShader::sNoFixedFunction && 
 			type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
@@ -219,6 +220,8 @@ void LLTexUnit::disable(void)
 		{
 			glDisable(sGLTextureType[mCurrTexType]);
 		}
+
+        setTextureColorSpace(TCS_LINEAR);
 		
 		mCurrTexType = TT_NONE;
 	}
@@ -255,7 +258,8 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
 						gl_tex->mTexOptionsDirty = false;
 						setTextureAddressMode(gl_tex->mAddressMode);
 						setTextureFilteringOption(gl_tex->mFilterOption);
-					}
+                    }
+                    setTextureColorSpace(mTexColorSpace);
 				}
 			}
 			else
@@ -330,6 +334,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
 			setTextureFilteringOption(texture->mFilterOption);
 			stop_glerror();
 		}
+        setTextureColorSpace(mTexColorSpace);
 	}
 
 	stop_glerror();
@@ -355,7 +360,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
 		{
 			activate();
 			enable(LLTexUnit::TT_CUBE_MAP);
-			mCurrTexture = cubeMap->mImages[0]->getTexName();
+            mCurrTexture = cubeMap->mImages[0]->getTexName();
 			glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
 			mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
 			cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory);
@@ -364,7 +369,8 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
 				cubeMap->mImages[0]->mTexOptionsDirty = false;
 				setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
 				setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
-			}
+            }
+            setTextureColorSpace(mTexColorSpace);
 			return true;
 		}
 		else
@@ -415,7 +421,8 @@ bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
 		enable(type);
 		mCurrTexture = texture;
 		glBindTexture(sGLTextureType[type], texture);
-		mHasMipMaps = hasMips;
+        mHasMipMaps = hasMips;
+        setTextureColorSpace(mTexColorSpace);
 	}
 	return true;
 }
@@ -435,6 +442,9 @@ void LLTexUnit::unbind(eTextureType type)
 	if (mCurrTexType == type)
 	{
 		mCurrTexture = 0;
+
+        // Always make sure our texture color space is reset to linear.  SRGB sampling should be opt-in in the vast majority of cases.  Also prevents color space "popping".
+        mTexColorSpace = TCS_LINEAR;
 		if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
 		{
 			glBindTexture(sGLTextureType[type], sWhiteTexture);
@@ -840,15 +850,18 @@ void LLTexUnit::debugTextureUnit(void)
 
 void LLTexUnit::setTextureColorSpace(eTextureColorSpace space) {
     mTexColorSpace = space;
-    if (space == TCS_SRGB) {
-        glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
-    }
-    else {
-        glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
-    }
-
-    if (gDebugGL) {
-        assert_glerror();
+    if (gGLManager.mHasTexturesRGBDecode) {
+
+        if (space == TCS_SRGB) {
+            glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
+        }
+        else {
+            glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+        }
+
+        if (gDebugGL) {
+            assert_glerror();
+        }
     }
 }
 
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 2f15edc20e2efbd4683ebab30072caef16c3388c..41f4fe40176620087a214303dd732498ed7b0e06 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -159,7 +159,7 @@ class LLTexUnit
 	// Binds the LLImageGL to this texture unit 
 	// (automatically enables the unit for the LLImageGL's texture type)
 	bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false);
-	bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
+    bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
 
 	// Binds a cubemap to this texture unit 
 	// (automatically enables the texture unit for cubemaps)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 57916eb3e5620cf3103e58b82f935a80208e8601..6489508c00726219b296d6ab9b6ff20415d3c68a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -78,7 +78,6 @@ vec3 linear_to_srgb(vec3 cl);
 vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
 {
 	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	ret.rgb = srgb_to_linear(ret.rgb);
 	
 	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
 	
@@ -98,7 +97,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
 vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
 {
 	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	ret.rgb = srgb_to_linear(ret.rgb);
 	
 	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
 	
@@ -116,7 +114,6 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
 vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
 {
 	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	ret.rgb = srgb_to_linear(ret.rgb);
 	
 	vec2 dist = tc-vec2(0.5);
 	
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 9e14c03a962a342ce763c242a3cbc96ff8f66d12..ab380f70e82c204c4bf93e674d8e0830ba8cd20a 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -83,7 +83,6 @@ vec4 correctWithGamma(vec4 col)
 vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
 {
     vec4 ret = texture2DLod(projectionMap, tc, lod);
-    ret = correctWithGamma(ret);
     
     vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
     
@@ -103,7 +102,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
 vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
 {
     vec4 ret = texture2DLod(projectionMap, tc, lod);
-    ret = correctWithGamma(ret);
 
     vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
     
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b9a917cfb41b495a7624ddb394581f7179e2239f..df6383e88bfa46a56f268c63e3614cbf5bcfadeb 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8281,7 +8281,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
 
 	stop_glerror();
 
-	channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+	channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP, LLTexUnit::TCS_SRGB);
 	if (channel > -1)
 	{
 		LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
@@ -8808,7 +8808,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
                     mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
                 }
                 gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION, LLTexUnit::TT_TEXTURE, LLTexUnit::TCS_SRGB);
-
                 unbindDeferredShader(gDeferredSpotLightProgram);
             }
 
@@ -9192,7 +9191,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
     shader.disableTexture(LLShaderMgr::DEFERRED_NOISE);
     shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
 
-    S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+    S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP, LLTexUnit::TCS_SRGB);
     if (channel > -1)
     {
         LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;