diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index e508c9a19976cabea54d7055a8753dffaa6ef20a..bb19248f1f77e7f5883994ccf698071364569aca 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -537,6 +537,26 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
 	}
 }
 
+// This converts from a non-linear sRGB floating point value (0..1) to a linear value.
+// Useful for gamma correction and such.  Note: any values passed through this should not be serialized.  You should also ideally cache the output of this.
+inline float sRGBtoLinear(const float val) {
+	if (val < 0.0031308f) {
+		return val * 12.92f;
+	}
+	else {
+		return 1.055f * pow(val, 1.0f / 2.4f) - 0.055f;
+	}
+}
+
+inline float linearTosRGB(const float val) {
+	if (val < 0.04045f) {
+		return val / 12.92f;
+	}
+	else {
+		return pow((val + 0.055f) / 1.055f, 2.4f);
+	}
+}
+
 // Include simd math header
 #include "llsimdmath.h"
 
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index af4e3fdda02f57d7cff070ef4bac33a1a1544f90..fcac016ed76ffb13146d8e95b6bfbc4f3cba4f66 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -53,10 +53,11 @@ const BOOL use_cube_mipmaps = FALSE;  //current build works best without cube mi
 
 bool LLCubeMap::sUseCubeMaps = true;
 
-LLCubeMap::LLCubeMap()
+LLCubeMap::LLCubeMap(bool init_as_srgb)
 	: mTextureStage(0),
 	  mTextureCoordStage(0),
-	  mMatrixStage(0)
+	  mMatrixStage(0),
+	  mIssRGB(init_as_srgb)
 {
 	mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
 	mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
@@ -82,12 +83,15 @@ void LLCubeMap::initGL()
 			U32 texname = 0;
 			
 			LLImageGL::generateTextures(1, &texname);
-
+			
 			for (int i = 0; i < 6; i++)
 			{
-				mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE));
+				mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, FALSE);
+				if (mIssRGB) {
+					mImages[i]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
+				}
 				mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
-				mRawImages[i] = new LLImageRaw(64, 64, 4);
+				mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
 				mImages[i]->createGLTexture(0, mRawImages[i], texname);
 				
 				gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); 
@@ -154,7 +158,7 @@ void LLCubeMap::initGLData()
 {
 	for (int i = 0; i < 6; i++)
 	{
-		mImages[i]->setSubImage(mRawImages[i], 0, 0, 64, 64);
+		mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
 	}
 }
 
@@ -484,7 +488,7 @@ void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
 						td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5);
 				}
 			}
-		mImages[side]->setSubImage(mRawImages[side], 0, 0, 64, 64);
+		mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION);
 	}
 }
 
diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h
index ee2c41e02694cfc0a69196bfc0b231bfef8145f3..95b6d1209913d04b3353c10c8fd6f312e9dbeabf 100644
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
@@ -36,8 +36,9 @@ class LLVector3;
 // Environment map hack!
 class LLCubeMap : public LLRefCount
 {
+	bool mIssRGB;
 public:
-	LLCubeMap();
+	LLCubeMap(bool init_as_srgb);
 	void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
 	void initGL();
 	void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 7d8f512c934b35ffbf547fa04f424fea2129f43b..d3f8431654b955039fb0c16988f7e9656781fff0 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -187,15 +187,20 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
 	switch (dataformat)
 	{
 	  case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:	return 4;
+	  case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4;
 	  case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:	return 8;
+	  case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8;
 	  case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:	return 8;
+	  case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 8;
 	  case GL_LUMINANCE:						return 8;
 	  case GL_ALPHA:							return 8;
 	  case GL_COLOR_INDEX:						return 8;
 	  case GL_LUMINANCE_ALPHA:					return 16;
 	  case GL_RGB:								return 24;
+	  case GL_SRGB:								return 24;
 	  case GL_RGB8:								return 24;
 	  case GL_RGBA:								return 32;
+	  case GL_SRGB_ALPHA:						return 32;
 	  case GL_BGRA:								return 32;		// Used for QuickTime media textures on the Mac
 	  default:
 		LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
@@ -206,11 +211,19 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
 //static
 S32 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height)
 {
-	if (dataformat >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
-		dataformat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+	switch (dataformat)
 	{
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
 		if (width < 4) width = 4;
 		if (height < 4) height = 4;
+		break;
+	default:
+		break;
 	}
 	S32 bytes ((width*height*dataFormatBits(dataformat)+7)>>3);
 	S32 aligned = (bytes+3)&~3;
@@ -223,14 +236,19 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
 	switch (dataformat)
 	{
 	  case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:	return 3;
+	  case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3;
 	  case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:	return 4;
+	  case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4;
 	  case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:	return 4;
+	  case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4;
 	  case GL_LUMINANCE:						return 1;
 	  case GL_ALPHA:							return 1;
 	  case GL_COLOR_INDEX:						return 1;
 	  case GL_LUMINANCE_ALPHA:					return 2;
 	  case GL_RGB:								return 3;
+	  case GL_SRGB:								return 3;
 	  case GL_RGBA:								return 4;
+	  case GL_SRGB_ALPHA:						return 4;
 	  case GL_BGRA:								return 4;		// Used for QuickTime media textures on the Mac
 	  default:
 		LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
@@ -650,9 +668,19 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 {
 	LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
 	bool is_compressed = false;
-	if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+
+	switch (mFormatPrimary)
 	{
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
 		is_compressed = true;
+		break;
+	default:
+		break;
 	}
 	
 	
@@ -1227,10 +1255,18 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
 			case GL_RGB8:
 				intformat = GL_COMPRESSED_RGB; 
 				break;
+			case GL_SRGB:
+			case GL_SRGB8:
+				intformat = GL_COMPRESSED_SRGB;
+				break;
 			case GL_RGBA:
 			case GL_RGBA8:
 				intformat = GL_COMPRESSED_RGBA; 
 				break;
+			case GL_SRGB_ALPHA:
+			case GL_SRGB8_ALPHA8:
+				intformat = GL_COMPRESSED_SRGB_ALPHA;
+				break;
 			case GL_LUMINANCE:
 			case GL_LUMINANCE8:
 				intformat = GL_COMPRESSED_LUMINANCE;
@@ -1798,10 +1834,12 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
 		mAlphaStride = 2;
 		break;
 	case GL_RGB:
+	case GL_SRGB:
 		mNeedsAlphaAndPickMask = FALSE ;
 		mIsMask = FALSE;
 		return ; //no alpha channel.
 	case GL_RGBA:
+	case GL_SRGB_ALPHA:
 		mAlphaStride = 4;
 		break;
 	case GL_BGRA_EXT:
@@ -1993,7 +2031,8 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
 	freePickMask();
 
 	if (mFormatType != GL_UNSIGNED_BYTE ||
-	    mFormatPrimary != GL_RGBA)
+	    mFormatPrimary != GL_RGBA ||
+		mFormatPrimary != GL_SRGB_ALPHA)
 	{
 		//cannot generate a pick mask for this texture
 		return;
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 96363045d3cd7ca9cbb2b911831e1e02e5962e46..8bcd875d9097c500ff6a8f63cc1d8a98909f894b 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -207,6 +207,9 @@ void LLSkyTex::create(const F32 brightness)
 
 void LLSkyTex::createGLImage(S32 which)
 {	
+	if (LLPipeline::RenderDeferred) {
+		mTexture[which]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
+	}
 	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
 	mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
 }
@@ -613,7 +616,9 @@ void LLVOSky::initCubeMap()
 	}
 	else if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
 	{
-		mCubeMap = new LLCubeMap();
+		bool wantsRGB = LLPipeline::RenderDeferred;
+
+		mCubeMap = new LLCubeMap(wantsRGB);
 		mCubeMap->init(images);
 	}
 	gGL.getTexUnit(0)->disable();