From 536799d07e4298ff8157ef51ed00040e10a5ba65 Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Mon, 29 Oct 2018 23:02:20 +0100
Subject: [PATCH] SL-9977 SL-9973

---
 indra/llinventory/llsettingssky.cpp |  33 +----
 indra/llrender/llgl.cpp             |  63 ++++++++-
 indra/llrender/llgl.h               |   9 +-
 indra/llrender/llglslshader.cpp     |  50 ++++---
 indra/llrender/llglstates.h         |  24 +++-
 indra/llrender/llrender.cpp         |   2 +-
 indra/llrender/llrender.h           |   9 ++
 indra/llrender/llshadermgr.cpp      |  63 ++++++---
 indra/llrender/llshadermgr.h        |   6 +-
 indra/newview/lldrawpoolground.cpp  |   8 +-
 indra/newview/lldrawpoolwlsky.cpp   | 196 ++++++++++++++++------------
 indra/newview/lldrawpoolwlsky.h     |  15 ++-
 indra/newview/llvieweroctree.cpp    |   2 +-
 indra/newview/llviewershadermgr.cpp |  29 ++--
 indra/newview/llvowlsky.cpp         |   5 +-
 indra/newview/llxmlrpclistener.cpp  |  43 +-----
 16 files changed, 321 insertions(+), 236 deletions(-)

diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index e2fd6810390..8a1e74d7ea8 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -156,14 +156,18 @@ LLSettingsSky::validation_list_t legacyHazeValidationList()
     static LLSettingsBase::validation_list_t legacyHazeValidation;
     if (legacyHazeValidation.empty())
     {
+        legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT,             false,  LLSD::TypeArray, 
+            boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+                LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+                LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
         legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY,        false,  LLSD::TypeArray, 
             boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
                 LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
-                LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+                LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
         legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON,        false,  LLSD::TypeArray, 
             boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
                 LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
-                LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+                LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
         legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY,        false,  LLSD::TypeReal,  
             boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4.0f)))));
         legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON,        false,  LLSD::TypeReal,  
@@ -493,28 +497,6 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
         // copy constructor for LLSDArray.  Directly binding the LLSDArray as 
         // a parameter without first wrapping it in a pure LLSD object will result 
         // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
-        validation.push_back(Validator(SETTING_BLUE_DENSITY,        false,  LLSD::TypeArray, 
-            boost::bind(&Validator::verifyVectorMinMax, _1,
-                LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
-                LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
-        validation.push_back(Validator(SETTING_BLUE_HORIZON,        false,  LLSD::TypeArray, 
-            boost::bind(&Validator::verifyVectorMinMax, _1,
-                LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
-                LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
-        validation.push_back(Validator(SETTING_HAZE_DENSITY,        false,  LLSD::TypeReal,  
-            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
-        validation.push_back(Validator(SETTING_HAZE_HORIZON,        false,  LLSD::TypeReal,  
-            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
-        validation.push_back(Validator(SETTING_AMBIENT, false, LLSD::TypeArray,
-            boost::bind(&Validator::verifyVectorMinMax, _1,
-                LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
-                LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
-        validation.push_back(Validator(SETTING_DENSITY_MULTIPLIER,  false,  LLSD::TypeReal,  
-            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(2.0f)))));
-        validation.push_back(Validator(SETTING_DISTANCE_MULTIPLIER, false,  LLSD::TypeReal,  
-            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(1000.0f)))));
-
-
         validation.push_back(Validator(SETTING_BLOOM_TEXTUREID,     true,  LLSD::TypeUUID));
         validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID,   false,  LLSD::TypeUUID));
         validation.push_back(Validator(SETTING_HALO_TEXTUREID,      false,  LLSD::TypeUUID));
@@ -921,9 +903,6 @@ void LLSettingsSky::calculateHeavenlyBodyPositions()  const
         LL_WARNS("SETTINGS") << "Zero length sun direction. Wailing and gnashing of teeth may follow... or not." << LL_ENDL;
     if (mMoonDirection.lengthSquared() < 0.01f)
         LL_WARNS("SETTINGS") << "Zero length moon direction. Wailing and gnashing of teeth may follow... or not." << LL_ENDL;
-
-    llassert(mSunDirection.lengthSquared() > 0.01f);
-    llassert(mMoonDirection.lengthSquared() > 0.01f);
 }
 
 LLVector3 LLSettingsSky::getLightDirection() const
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 2f78b6e104f..a55a72c18f7 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -36,6 +36,7 @@
 #include "llsys.h"
 
 #include "llgl.h"
+#include "llglstates.h"
 #include "llrender.h"
 
 #include "llerror.h"
@@ -2478,27 +2479,45 @@ void LLGLDepthTest::checkState()
 	}
 }
 
-LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
+LLGLSquashToFarClip::LLGLSquashToFarClip()
+{
+    glh::matrix4f proj = get_current_projection();
+    setProjectionMatrix(proj, 0);
+}
+
+LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f& P, U32 layer)
+{
+    setProjectionMatrix(P, layer);
+}
+
+
+void LLGLSquashToFarClip::setProjectionMatrix(glh::matrix4f& projection, U32 layer)
 {
 
 	F32 depth = 0.99999f - 0.0001f * layer;
 
 	for (U32 i = 0; i < 4; i++)
 	{
-		P.element(2, i) = P.element(3, i) * depth;
+		projection.element(2, i) = projection.element(3, i) * depth;
 	}
 
+    U32 last_matrix_mode = gGL.getMatrixMode();
+
 	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
-	gGL.loadMatrix(P.m);
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.loadMatrix(projection.m);
+
+	gGL.matrixMode(last_matrix_mode);
 }
 
 LLGLSquashToFarClip::~LLGLSquashToFarClip()
 {
+    U32 last_matrix_mode = gGL.getMatrixMode();
+
 	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+	gGL.matrixMode(last_matrix_mode);
 }
 
 
@@ -2561,5 +2580,39 @@ void LLGLSyncFence::wait()
 #endif
 }
 
+LLGLSPipelineSkyBox::LLGLSPipelineSkyBox()
+: mAlphaTest(GL_ALPHA_TEST)
+, mCullFace(GL_CULL_FACE)
+, mSquashClip()
+{ 
+    if (!LLGLSLShader::sNoFixedFunction)
+    {
+        glDisable(GL_LIGHTING);
+        glDisable(GL_FOG);
+        glDisable(GL_CLIP_PLANE0);
+    }
+}
 
+LLGLSPipelineSkyBox::~LLGLSPipelineSkyBox()
+{
+    if (!LLGLSLShader::sNoFixedFunction)
+    {
+        glEnable(GL_LIGHTING);
+        glEnable(GL_FOG);
+        glEnable(GL_CLIP_PLANE0);
+    }
+}
 
+LLGLSPipelineDepthTestSkyBox::LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write)
+: LLGLSPipelineSkyBox()
+, mDepth(depth_test ? GL_TRUE : GL_FALSE, depth_write ? GL_TRUE : GL_FALSE, GL_LEQUAL)
+{
+
+}
+
+LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write)
+: LLGLSPipelineDepthTestSkyBox(depth_test, depth_write)    
+, mBlend(GL_BLEND)
+{ 
+    gGL.setSceneBlendType(LLRender::BT_ALPHA);
+}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 4c4302d05ba..96cbf2e3c27 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -360,14 +360,17 @@ class LLGLUserClipPlane
   Modify and load projection matrix to push depth values to far clip plane.
 
   Restores projection matrix on destruction.
-  GL_MODELVIEW_MATRIX is active whenever program execution
-  leaves this class.
+  Saves/restores matrix mode around projection manipulation.
   Does not stack.
 */
 class LLGLSquashToFarClip
 {
 public:
-	LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0);
+    LLGLSquashToFarClip();
+	LLGLSquashToFarClip(glh::matrix4f& projection, U32 layer = 0);
+
+    void setProjectionMatrix(glh::matrix4f& projection, U32 layer);
+
 	~LLGLSquashToFarClip();
 };
 
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index c03d33080fe..f0cc9acc060 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -37,12 +37,6 @@
 #include "OpenGL/OpenGL.h"
 #endif
 
-#ifdef LL_RELEASE_FOR_DOWNLOAD
-#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-#else
-#define UNIFORM_ERRS LL_ERRS("Shader")
-#endif
-
 // Lots of STL stuff in here, using namespace std to keep things more readable
 using std::vector;
 using std::pair;
@@ -456,12 +450,12 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
     }
     if( !success )
     {
-        LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
+        LL_SHADER_LOADING_WARNS() << "Failed to link shader: " << mName << LL_ENDL;
 
         // Try again using a lower shader level;
         if (mShaderLevel > 0)
         {
-            LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
+            LL_SHADER_LOADING_WARNS() << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
             mShaderLevel--;
             return createShader(attributes,uniforms);
         }
@@ -504,7 +498,7 @@ BOOL LLGLSLShader::attachObject(std::string object)
     }
     else
     {
-        LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
+        LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
         return FALSE;
     }
 }
@@ -519,7 +513,7 @@ void LLGLSLShader::attachObject(GLhandleARB object)
     }
     else
     {
-        LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
+        LL_SHADER_LOADING_WARNS() << "Attempting to attach non existing shader object. " << LL_ENDL;
     }
 }
 
@@ -937,7 +931,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
 {
     if (uniform < 0 || uniform >= (S32)mTexture.size())
     {
-        UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+        LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
         return -1;
     }
     
@@ -963,7 +957,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
 {
     if (uniform < 0 || uniform >= (S32)mTexture.size())
     {
-        UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+        LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
         return -1;
     }
     
@@ -981,7 +975,7 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
 {
     if (uniform < 0 || uniform >= (S32)mTexture.size())
     {
-        UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+        LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
         return -1;
     }
     S32 index = mTexture[uniform];
@@ -997,7 +991,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
 {
     if (uniform < 0 || uniform >= (S32)mTexture.size())
     {
-        UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+        LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
         return -1;
     }
     S32 index = mTexture[uniform];
@@ -1026,7 +1020,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1048,7 +1042,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1070,7 +1064,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1093,7 +1087,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1116,7 +1110,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1139,7 +1133,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1162,7 +1156,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1185,7 +1179,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1208,7 +1202,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1231,7 +1225,7 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1254,7 +1248,7 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1271,7 +1265,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
@@ -1288,7 +1282,7 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose,
 	{	
 		if (mUniform.size() <= index)
 		{
-			UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+			LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
 			return;
 		}
 
@@ -1305,7 +1299,7 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
     {   
         if (mUniform.size() <= index)
         {
-            UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+            LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
             return;
         }
 
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index 0e2c3bcb44b..a4924eba14d 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -208,11 +208,27 @@ class LLGLSPipelineAvatar
 class LLGLSPipelineSkyBox
 { 
 protected:
-	LLGLDisable mAlphaTest, mCullFace, mFog;
+	LLGLDisable mAlphaTest;
+    LLGLDisable mCullFace;
+    LLGLSquashToFarClip mSquashClip;
 public:
-	LLGLSPipelineSkyBox()
-		: mAlphaTest(GL_ALPHA_TEST), mCullFace(GL_CULL_FACE), mFog(GL_FOG)
-	{ }
+	LLGLSPipelineSkyBox();
+   ~LLGLSPipelineSkyBox();
+};
+
+class LLGLSPipelineDepthTestSkyBox : public LLGLSPipelineSkyBox
+{ 
+public:
+	LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write);
+
+    LLGLDepthTest mDepth;
+};
+
+class LLGLSPipelineBlendSkyBox : public LLGLSPipelineDepthTestSkyBox 
+{ 
+public:
+	LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write);
+    LLGLEnable mBlend;    
 };
 
 class LLGLSTracker
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 251c02dd77c..5733a18f47f 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1270,7 +1270,7 @@ void LLRender::syncMatrices()
 			glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
 
             // it would be nice to have this automatically track the state of the proj matrix
-            // but certain render paths require it to be mismatched *sigh*
+            // but certain render paths (deferred lighting) require it to be mismatched *sigh*
             //if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX))
             //{
 	        //    glh::matrix4f inv_proj = mat.inverse();
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 62cd526550d..a79db80ebe3 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -517,4 +517,13 @@ void set_current_projection(glh::matrix4f& mat);
 glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar);
 glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);
 glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up);
+
+#if LL_RELEASE_FOR_DOWNLOAD
+    #define LL_SHADER_LOADING_WARNS(...) LL_WARNS_ONCE("ShaderLoading")
+    #define LL_SHADER_UNIFORM_ERRS(...)  LL_WARNS_ONCE("Shader")
+#else
+    #define LL_SHADER_LOADING_WARNS(...) LL_WARNS()
+    #define LL_SHADER_UNIFORM_ERRS(...)  LL_ERRS("Shader")    
+#endif
+
 #endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 8617b58d2e2..9da705bb2de 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -25,18 +25,14 @@
  */
 
 #include "linden_common.h"
-
 #include "llshadermgr.h"
-
-#include "llfile.h"
 #include "llrender.h"
+#include "llfile.h"
 
 #if LL_DARWIN
 #include "OpenGL/OpenGL.h"
 #endif
 
-#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-
 // Lots of STL stuff in here, using namespace std to keep things more readable
 using std::vector;
 using std::pair;
@@ -537,6 +533,16 @@ static std::string get_object_log(GLhandleARB ret)
 	return res;
 }
 
+//dump shader source for debugging
+void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text)
+{	
+	for (GLuint i = 0; i < shader_code_count; i++)
+	{
+		LL_SHADER_LOADING_WARNS() << i << ": " << shader_code_text[i] << LL_ENDL;
+	}
+    LL_SHADER_LOADING_WARNS() << LL_ENDL;
+}
+
 void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename) 
 {
 	std::string log = get_object_log(ret);
@@ -548,8 +554,8 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string&
 
 	if (log.length() > 0)
 	{
-        LL_WARNS("ShaderLoading") << "Shader loading from " << fname << ":\n" << LL_ENDL;
-        LL_WARNS("ShaderLoading") << log << LL_ENDL;
+        LL_SHADER_LOADING_WARNS() << "Shader loading from " << fname << ":\n" << LL_ENDL;
+        LL_SHADER_LOADING_WARNS() << log << LL_ENDL;
 	}
  }
 
@@ -570,11 +576,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		error = glGetError();
 		if (error != GL_NO_ERROR)
 		{
-			LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
+			LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
 		}
 	}
 	
-	LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
+	//LL_SHADER_LOADING_WARNS() << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
 
 	if (filename.empty()) 
 	{
@@ -588,6 +594,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 	S32 try_gpu_class = shader_level;
 	S32 gpu_class;
 
+    std::string open_file_name;
 	//find the most relevant file
 	for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
 	{	//search from the current gpu class down to class 1 to find the most relevant shader
@@ -595,18 +602,33 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		fname << getShaderDirPrefix();
 		fname << gpu_class << "/" << filename;
 		
- 		LL_DEBUGS("ShaderLoading") << "Looking in " << fname.str() << LL_ENDL;
-		file = LLFile::fopen(fname.str(), "r");		/* Flawfinder: ignore */
+        open_file_name = fname.str();
+
+        /*
+        Would be awesome, if we didn't have shaders that re-use files
+        with different environments to say, add skinning, etc
+        can't depend on cached version to have evaluate ifdefs identically...
+        if we can define a deterministic hash for the shader based on
+        all the inputs, maybe we can save some time here.
+        if (mShaderObjects.count(filename) > 0)
+        {
+            return mShaderObjects[filename];
+        }
+
+        */
+
+ 		LL_DEBUGS("ShaderLoading") << "Looking in " << open_file_name << LL_ENDL;
+		file = LLFile::fopen(open_file_name, "r");		/* Flawfinder: ignore */
 		if (file)
 		{
-			LL_DEBUGS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
+			LL_DEBUGS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << open_file_name << " (Want class " << gpu_class << ")" << LL_ENDL;            
 			break; // done
 		}
 	}
 	
 	if (file == NULL)
 	{
-		LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << filename << LL_ENDL;
+		LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << filename << LL_ENDL;
 		return 0;
 	}
 
@@ -685,7 +707,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		extra_code_text[extra_code_count++] = strdup("#define texture2D texture\n");
 		extra_code_text[extra_code_count++] = strdup("#define textureCube texture\n");
 		extra_code_text[extra_code_count++] = strdup("#define texture2DLod textureLod\n");
-		extra_code_text[extra_code_count++] = strdup("#define	shadow2D(a,b) vec2(texture(a,b))\n");
+		extra_code_text[extra_code_count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
 		
 		if (major_version > 1 || minor_version >= 40)
 		{ //GLSL 1.40 replaces texture2DRect et al with texture
@@ -1012,7 +1034,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
 	if (!suppress_errors && success == GL_FALSE) 
 	{
 		//an error occured, print log
-		LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
+		LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL;
 	}
 
 #if LL_DARWIN
@@ -1045,7 +1067,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
 		CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
 		if (!fragmentGPUProcessing || !vertexGPUProcessing)
 		{
-			LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
+			LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
 			success = GL_FALSE;
 			suppress_errors = FALSE;		
 		}
@@ -1056,7 +1078,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
 	LLStringUtil::toLower(log);
 	if (log.find("software") != std::string::npos)
 	{
-		LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
+		LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
 		success = GL_FALSE;
 		suppress_errors = FALSE;
 	}
@@ -1072,7 +1094,7 @@ BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
 	glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
 	if (success == GL_FALSE)
 	{
-		LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL;
+		LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL;
 		dumpObjectLog(obj);
 	}
 	else
@@ -1326,9 +1348,12 @@ void LLShaderMgr::initAttribsAndUniforms()
     mReservedUniforms.push_back("rainbow_map");
     mReservedUniforms.push_back("halo_map");
     mReservedUniforms.push_back("moon_brightness");
-    mReservedUniforms.push_back("moon_phase");
     mReservedUniforms.push_back("cloud_variance");
 
+    mReservedUniforms.push_back("sh_input_r");
+    mReservedUniforms.push_back("sh_input_g");
+    mReservedUniforms.push_back("sh_input_b");
+
 	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
 
 	std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index af34c70c544..c22fe447502 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -241,10 +241,13 @@ class LLShaderMgr
         HALO_MAP,
 
         MOON_BRIGHTNESS,
-        MOON_PHASE,
 
         CLOUD_VARIANCE,
 
+        SH_INPUT_L1R,
+        SH_INPUT_L1G,
+        SH_INPUT_L1B,
+
 		END_RESERVED_UNIFORMS
 	} eGLSLReservedUniforms;
 
@@ -255,6 +258,7 @@ class LLShaderMgr
 
 	BOOL attachShaderFeatures(LLGLSLShader * shader);
 	void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE, const std::string& filename = "");
+    void dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text);
 	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
 	BOOL	validateProgramObject(GLhandleARB obj);
 	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index e5ce0413b17..bae07a171b9 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -63,13 +63,9 @@ void LLDrawPoolGround::render(S32 pass)
 		return;
 	}	
 	
-	LLGLSPipelineSkyBox gls_skybox;
+	LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
-	LLGLSquashToFarClip far_clip(get_current_projection());
-
 	F32 water_height = gAgent.getRegion()->getWaterHeight();
 	gGL.pushMatrix();
 	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
@@ -77,8 +73,6 @@ void LLDrawPoolGround::render(S32 pass)
 
 	LLFace *facep = mDrawFace[0];
 
-	gPipeline.disableLights();
-
 	LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor());
 	facep->renderIndexed();
 	
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index c4560e89f44..d4674cec677 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -163,10 +163,12 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca
 	gGL.popMatrix();
 }
 
-void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal) const
 {
     if (gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders() && gAtmosphere)
     {
+        LLGLSPipelineDepthTestSkyBox sky(true, false);
+
 		sky_shader->bind();
 
         // bind precomputed textures necessary for calculating sun and sky luminance
@@ -208,20 +210,20 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
 
         sky_shader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
 
-        LLGLDisable cull(GL_CULL_FACE);
         renderFsSky(camPosLocal, camHeightLocal, sky_shader);
 
 		sky_shader->unbind();
 	}
 }
 
-void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
 {
     LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
 
 	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
 	{
-        LLGLDisable blend(GL_BLEND);
+        LLGLSPipelineDepthTestSkyBox sky(true, false);
+
         sky_shader->bind();
 
         LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
@@ -247,19 +249,28 @@ void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightL
     }
 }
 
+void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const
+{
+    LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
+	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+	{
+        LLGLSPipelineDepthTestSkyBox sky(true, false);
+        sky_shader->bind();
+        renderDome(origin, camHeightLocal, sky_shader);	
+		sky_shader->unbind();
+    }
+}
+
 void LLDrawPoolWLSky::renderStars(void) const
 {
-	LLGLSPipelineSkyBox gls_sky;
-	LLGLEnable blend(GL_BLEND);
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+    LLGLSPipelineBlendSkyBox gls_skybox(true, false);
 	
 	// *NOTE: have to have bound the cloud noise texture already since register
 	// combiners blending below requires something to be bound
 	// and we might as well only bind once.
 	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	
-	gPipeline.disableLights();
-	
 	// *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid
 	// clamping and allow the star_alpha param to brighten the stars.
 	LLColor4 star_alpha(LLColor4::black);
@@ -323,9 +334,7 @@ void LLDrawPoolWLSky::renderStars(void) const
 
 void LLDrawPoolWLSky::renderStarsDeferred(void) const
 {
-	LLGLSPipelineSkyBox gls_sky;
-	LLGLEnable blend(GL_BLEND);
-    LLGLDepthTest depth_test(GL_TRUE, GL_FALSE, GL_LESS);
+	LLGLSPipelineBlendSkyBox gls_sky(true, false);
 
 	gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 
@@ -384,39 +393,103 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const
     gDeferredStarProgram.unbind();
 }
 
-void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
+{    
+	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
+	{		
+        LLGLSPipelineBlendSkyBox pipeline(true, true);
+
+		cloudshader->bind();
+
+        S32 cloud_channel      = cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
+        S32 cloud_next_channel = cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
+        (void)cloud_channel, (void)cloud_next_channel;
+
+        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+        cloudshader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance());
+        cloudshader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering());
+        cloudshader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering());
+        cloudshader->bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance());
+
+        F32 blend_factor   = psky ? psky->getBlendFactor()   : 0.0f;
+        F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+
+        LLVector3 sun_dir  = LLEnvironment::instance().getSunDirection();
+        LLVector3 moon_dir = LLEnvironment::instance().getMoonDirection();
+
+        F32 sunSize = (float)cosf(psky->getSunArcRadians());
+        cloudshader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize);
+        cloudshader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, sun_dir.mV);
+        cloudshader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, moon_dir.mV);
+
+        cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+        cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+
+        cloudshader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+
+		/// Render the skydome
+        renderDome(camPosLocal, camHeightLocal, cloudshader);
+
+		cloudshader->unbind();
+	}
+}
+
+void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
 {
 	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
 	{
-        LLGLDepthTest depth(GL_TRUE, GL_TRUE);
-		LLGLEnable blend(GL_BLEND);
-		gGL.setSceneBlendType(LLRender::BT_ALPHA);
+		LLGLSPipelineBlendSkyBox pipeline(true, true);
 		
-		cloud_shader->bind();
+		cloudshader->bind();
 
-        cloud_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
-        cloud_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
+        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
+        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
+        
+        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+        F32 blend_factor   = psky ? psky->getBlendFactor()   : 0.0f;
+        F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+
+        cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+        cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+
+		/// Render the skydome
+        renderDome(camPosLocal, camHeightLocal, cloudshader);
+
+		cloudshader->unbind();
+	}
+}
+
+void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
+{
+	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
+	{
+        LLGLSPipelineBlendSkyBox pipeline(true, true);
+		
+		cloudshader->bind();
+
+        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
+        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
 
         LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
 
         F32 blend_factor   = psky ? psky->getBlendFactor()   : 0.0f;
         F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
 
-        cloud_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
-        cloud_shader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+        cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+        cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
 
 		/// Render the skydome
-        renderDome(camPosLocal, camHeightLocal, cloud_shader);
+        renderDome(camPosLocal, camHeightLocal, cloudshader);
 
-		cloud_shader->unbind();
+		cloudshader->unbind();
 	}
 }
 
 void LLDrawPoolWLSky::renderHeavenlyBodies()
 {
-	LLGLSPipelineSkyBox gls_skybox;
-	LLGLEnable blend_on(GL_BLEND);
-	gPipeline.disableLights();
+	LLGLSPipelineBlendSkyBox gls_skybox(true, false);
 
     LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
 	gGL.pushMatrix();
@@ -540,35 +613,26 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
 
     const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
 
-	LLGLSNoFog disableFog;	
-	LLGLDisable clip(GL_CLIP_PLANE0);
-
 	gGL.setColorMask(true, false);
 
-	LLGLSquashToFarClip far_clip(get_current_projection());
-
     LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
 
     if (gPipeline.canUseWindLightShaders())
     {
+        if (gPipeline.useAdvancedAtmospherics())
         {
-            // Disable depth-writes for sky, but re-enable depth writes for the cloud
-            // rendering below so the cloud shader can write out depth for the stars to test against         
-            LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
-            if (gPipeline.useAdvancedAtmospherics())
-            {
-	            renderSkyHazeDeferred(origin, camHeightLocal);
-            }
-            else
-            {
-                renderSkyHaze(origin, camHeightLocal);
-            }
+	        renderSkyHazeAdvanced(origin, camHeightLocal);
+            renderHeavenlyBodies(); 
+            renderSkyCloudsAdvanced(origin, camHeightLocal, cloud_shader);     
+        }
+        else
+        {
+            renderSkyHazeDeferred(origin, camHeightLocal);
             renderHeavenlyBodies();
+            renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
         }
+    }
 
-        renderSkyClouds(origin, camHeightLocal);
-    }    
     gGL.setColorMask(true, true);
 }
 
@@ -576,21 +640,12 @@ void LLDrawPoolWLSky::renderPostDeferred(S32 pass)
 {
     LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
 
-    LLGLSNoFog disableFog;	
-	LLGLDisable clip(GL_CLIP_PLANE0);
-    LLGLSquashToFarClip far_clip(get_current_projection());
+    LLGLSPipelineBlendSkyBox sky(true, false);
 
 	gGL.pushMatrix();
 	gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-    gGL.setColorMask(true, false);
-
-    // would be nice to do this here, but would need said bodies
-    // to render at a realistic distance for depth-testing against the clouds...
-    //renderHeavenlyBodies();
     renderStarsDeferred();
-
     gGL.popMatrix();
-    gGL.setColorMask(true, true);
 }
 
 void LLDrawPoolWLSky::render(S32 pass)
@@ -602,35 +657,14 @@ void LLDrawPoolWLSky::render(S32 pass)
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
 
     const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
-
-	LLGLSNoFog disableFog;
-	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-	LLGLDisable clip(GL_CLIP_PLANE0);
-
-	LLGLSquashToFarClip far_clip(get_current_projection());
-
     LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
 
-	renderSkyHaze(origin, camHeightLocal);
-    
-	gGL.pushMatrix();
-
-    // MAINT-9006 keep sun position consistent between ALM and non-ALM rendering
-	//gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-
-	// *NOTE: have to bind a texture here since register combiners blending in
-	// renderStars() requires something to be bound and we might as well only
-	// bind the moon's texture once.		
-	gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
-    gGL.getTexUnit(1)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP));
-
-    renderHeavenlyBodies();
-
-	renderStars();
-
-	gGL.popMatrix();
+    LLGLSPipelineBlendSkyBox sky(true, false);
 
-	renderSkyClouds(origin, camHeightLocal);
+	renderSkyHaze(origin, camHeightLocal);    
+    renderStars();
+    renderHeavenlyBodies();	
+	renderSkyClouds(origin, camHeightLocal, cloud_shader);
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 }
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index 309efdbc5ba..4338de32dc4 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -81,14 +81,19 @@ class LLDrawPoolWLSky : public LLDrawPool {
 private:
     void renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
 	void renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
-	void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const;
 
-    void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
-    void renderStarsDeferred(void) const;
+    void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+    void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
+
+	void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+    void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
 
+    void renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+    void renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
+
+    void renderStarsDeferred(void) const;
 	void renderStars(void) const;
-	void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const;
-	void renderHeavenlyBodies();
+	void renderHeavenlyBodies();    
 };
 
 #endif // LL_DRAWPOOLWLSKY_H
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 7d4d737db48..9371711ca14 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1272,7 +1272,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
 						{
 							LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW_WATER);
 
-							LLGLSquashToFarClip squash(get_current_projection(), 1);
+							LLGLSquashToFarClip squash;
 							if (camera->getOrigin().isExactlyZero())
 							{ //origin is invalid, draw entire box
 								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index d98fd347141..8a949c6b4e2 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -31,25 +31,26 @@
 
 #include "llfeaturemanager.h"
 #include "llviewershadermgr.h"
-
-#include "llfile.h"
-#include "llviewerwindow.h"
-#include "llwindow.h"
 #include "llviewercontrol.h"
-#include "pipeline.h"
+
+#include "llrender.h"
+#include "llenvironment.h"
+#include "llatmosphere.h"
 #include "llworld.h"
 #include "llsky.h"
 #include "llvosky.h"
-#include "llrender.h"
+
+#include "pipeline.h"
+
+#include "llfile.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
+
 #include "lljoint.h"
 #include "llskinningutil.h"
-#include "llenvironment.h"
-#include "llatmosphere.h"
 
-#ifdef LL_RELEASE_FOR_DOWNLOAD
-#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-#else
-#define UNIFORM_ERRS LL_ERRS("Shader")
+#if LL_WINDOWS
+#pragma optimize("", off)
 #endif
 
 static LLStaticHashedString sTexture0("texture0");
@@ -486,7 +487,7 @@ void LLViewerShaderMgr::setShaders()
 		S32 effect_class = 2;
 		S32 wl_class = 3;
 		S32 water_class = 2;
-		S32 deferred_class = 0;
+		S32 deferred_class = 2;
 		S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
 
 		static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
@@ -935,6 +936,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 		// Note usage of GL_VERTEX_SHADER_ARB
 		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
 		{
+            LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
 			return FALSE;
 		}
 	}
@@ -991,6 +993,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 		// Note usage of GL_FRAGMENT_SHADER_ARB
 		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
 		{
+            LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
 			return FALSE;
 		}
 	}
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index b4b6bb252fd..570273e62c4 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -104,9 +104,10 @@ inline F32 LLVOWLSky::calcPhi(U32 i)
     // i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f]
 	F32 t = float(i) / float(getNumStacks());
 
-	// ^2 the parameter of the tesselation to bias things toward 0 (the dome's apex)
+	// ^4 the parameter of the tesselation to bias things toward 0 (the dome's apex)
 	t *= t;
-	
+	t *= t;
+
 	// invert and square the parameter of the tesselation to bias things toward 1 (the horizon)
 	t = 1.f - t;
 	t = t*t;
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 7bc8af4a0b3..0693d08dfbb 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -105,29 +105,12 @@ class CURLcodeMapper: public StatusMapperBase<CURLcode>
         def(CURLE_UNSUPPORTED_PROTOCOL);    /* 1 */
         def(CURLE_FAILED_INIT);             /* 2 */
         def(CURLE_URL_MALFORMAT);           /* 3 */
-        def(CURLE_URL_MALFORMAT_USER);      /* 4 - NOT USED */
         def(CURLE_COULDNT_RESOLVE_PROXY);   /* 5 */
         def(CURLE_COULDNT_RESOLVE_HOST);    /* 6 */
         def(CURLE_COULDNT_CONNECT);         /* 7 */
-        def(CURLE_FTP_WEIRD_SERVER_REPLY);  /* 8 */
-        def(CURLE_FTP_ACCESS_DENIED);       /* 9 a service was denied by the FTP server
-                                          due to lack of access - when login fails
-                                          this is not returned. */
-        def(CURLE_FTP_USER_PASSWORD_INCORRECT); /* 10 - NOT USED */
-        def(CURLE_FTP_WEIRD_PASS_REPLY);    /* 11 */
-        def(CURLE_FTP_WEIRD_USER_REPLY);    /* 12 */
-        def(CURLE_FTP_WEIRD_PASV_REPLY);    /* 13 */
-        def(CURLE_FTP_WEIRD_227_FORMAT);    /* 14 */
-        def(CURLE_FTP_CANT_GET_HOST);       /* 15 */
-        def(CURLE_FTP_CANT_RECONNECT);      /* 16 */
-        def(CURLE_FTP_COULDNT_SET_BINARY);  /* 17 */
         def(CURLE_PARTIAL_FILE);            /* 18 */
-        def(CURLE_FTP_COULDNT_RETR_FILE);   /* 19 */
-        def(CURLE_FTP_WRITE_ERROR);         /* 20 */
-        def(CURLE_FTP_QUOTE_ERROR);         /* 21 */
         def(CURLE_HTTP_RETURNED_ERROR);     /* 22 */
         def(CURLE_WRITE_ERROR);             /* 23 */
-        def(CURLE_MALFORMAT_USER);          /* 24 - NOT USED */
         def(CURLE_UPLOAD_FAILED);           /* 25 - failed upload "command" */
         def(CURLE_READ_ERROR);              /* 26 - could open/read from file */
         def(CURLE_OUT_OF_MEMORY);           /* 27 */
@@ -135,29 +118,18 @@ class CURLcodeMapper: public StatusMapperBase<CURLcode>
                  instead of a memory allocation error if CURL_DOES_CONVERSIONS
                  is defined
         */
-        def(CURLE_OPERATION_TIMEOUTED);     /* 28 - the timeout time was reached */
-        def(CURLE_FTP_COULDNT_SET_ASCII);   /* 29 - TYPE A failed */
-        def(CURLE_FTP_PORT_FAILED);         /* 30 - FTP PORT operation failed */
-        def(CURLE_FTP_COULDNT_USE_REST);    /* 31 - the REST command failed */
-        def(CURLE_FTP_COULDNT_GET_SIZE);    /* 32 - the SIZE command failed */
+        def(CURLE_OPERATION_TIMEDOUT);     /* 28 - the timeout time was reached */
         def(CURLE_HTTP_RANGE_ERROR);        /* 33 - RANGE "command" didn't work */
         def(CURLE_HTTP_POST_ERROR);         /* 34 */
         def(CURLE_SSL_CONNECT_ERROR);       /* 35 - wrong when connecting with SSL */
         def(CURLE_BAD_DOWNLOAD_RESUME);     /* 36 - couldn't resume download */
         def(CURLE_FILE_COULDNT_READ_FILE);  /* 37 */
-        def(CURLE_LDAP_CANNOT_BIND);        /* 38 */
-        def(CURLE_LDAP_SEARCH_FAILED);      /* 39 */
         def(CURLE_LIBRARY_NOT_FOUND);       /* 40 */
         def(CURLE_FUNCTION_NOT_FOUND);      /* 41 */
         def(CURLE_ABORTED_BY_CALLBACK);     /* 42 */
         def(CURLE_BAD_FUNCTION_ARGUMENT);   /* 43 */
-        def(CURLE_BAD_CALLING_ORDER);       /* 44 - NOT USED */
         def(CURLE_INTERFACE_FAILED);        /* 45 - CURLOPT_INTERFACE failed */
-        def(CURLE_BAD_PASSWORD_ENTERED);    /* 46 - NOT USED */
         def(CURLE_TOO_MANY_REDIRECTS );     /* 47 - catch endless re-direct loops */
-        def(CURLE_UNKNOWN_TELNET_OPTION);   /* 48 - User specified an unknown option */
-        def(CURLE_TELNET_OPTION_SYNTAX );   /* 49 - Malformed telnet option */
-        def(CURLE_OBSOLETE);                /* 50 - NOT USED */
         def(CURLE_SSL_PEER_CERTIFICATE);    /* 51 - peer's certificate wasn't ok */
         def(CURLE_GOT_NOTHING);             /* 52 - when this is a specific error */
         def(CURLE_SSL_ENGINE_NOTFOUND);     /* 53 - SSL crypto engine not found */
@@ -165,26 +137,19 @@ class CURLcodeMapper: public StatusMapperBase<CURLcode>
                                           default */
         def(CURLE_SEND_ERROR);              /* 55 - failed sending network data */
         def(CURLE_RECV_ERROR);              /* 56 - failure in receiving network data */
-        def(CURLE_SHARE_IN_USE);            /* 57 - share is in use */
+
         def(CURLE_SSL_CERTPROBLEM);         /* 58 - problem with the local certificate */
         def(CURLE_SSL_CIPHER);              /* 59 - couldn't use specified cipher */
         def(CURLE_SSL_CACERT);              /* 60 - problem with the CA cert (path?) */
         def(CURLE_BAD_CONTENT_ENCODING);    /* 61 - Unrecognized transfer encoding */
-        def(CURLE_LDAP_INVALID_URL);        /* 62 - Invalid LDAP URL */
+
         def(CURLE_FILESIZE_EXCEEDED);       /* 63 - Maximum file size exceeded */
-        def(CURLE_FTP_SSL_FAILED);          /* 64 - Requested FTP SSL level failed */
+
         def(CURLE_SEND_FAIL_REWIND);        /* 65 - Sending the data requires a rewind
                                           that failed */
         def(CURLE_SSL_ENGINE_INITFAILED);   /* 66 - failed to initialise ENGINE */
         def(CURLE_LOGIN_DENIED);            /* 67 - user); password or similar was not
                                           accepted and we failed to login */
-        def(CURLE_TFTP_NOTFOUND);           /* 68 - file not found on server */
-        def(CURLE_TFTP_PERM);               /* 69 - permission problem on server */
-        def(CURLE_TFTP_DISKFULL);           /* 70 - out of disk space on server */
-        def(CURLE_TFTP_ILLEGAL);            /* 71 - Illegal TFTP operation */
-        def(CURLE_TFTP_UNKNOWNID);          /* 72 - Unknown transfer ID */
-        def(CURLE_TFTP_EXISTS);             /* 73 - File already exists */
-        def(CURLE_TFTP_NOSUCHUSER);         /* 74 - No such user */
         def(CURLE_CONV_FAILED);             /* 75 - conversion failed */
         def(CURLE_CONV_REQD);               /* 76 - caller must register conversion
                                           callbacks using curl_easy_setopt options
-- 
GitLab