From 423fa1ac297e39c9395f45490278b8751188b6db Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Thu, 7 Mar 2019 10:56:26 -0800
Subject: SL-10618, SL-10698

Fix reflection/distortion map culling planes again.

Fix broken handling of shadow disables in ALM forward shaders.
---
 indra/llrender/llglslshader.cpp                    |  5 ++
 indra/llrender/llglslshader.h                      |  1 +
 indra/llrender/llshadermgr.cpp                     |  7 +-
 .../shaders/class1/deferred/alphaF.glsl            | 23 ++---
 .../shaders/class1/deferred/fullbrightF.glsl       |  4 +-
 .../shaders/class1/deferred/fullbrightShinyF.glsl  |  4 +-
 .../shaders/class1/deferred/materialF.glsl         | 34 +++-----
 .../shaders/class1/deferred/materialV.glsl         | 22 ++---
 .../shaders/class1/deferred/softenLightF.glsl      | 15 ----
 .../shaders/class1/deferred/waterF.glsl            |  2 -
 indra/newview/llviewershadermgr.cpp                | 98 ++++++++++++++++++----
 indra/newview/pipeline.cpp                         | 98 +++++++++++++++-------
 indra/newview/pipeline.h                           |  1 +
 13 files changed, 190 insertions(+), 124 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 528f23b3ee..9a4eeb59df 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -695,6 +695,11 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
     }
 }
 
+void LLGLSLShader::clearPermutations()
+{
+    mDefines.clear();
+}
+
 void LLGLSLShader::addPermutation(std::string name, std::string value)
 {
     mDefines[name] = value;
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index c06668eb43..e5110fe1c4 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -145,6 +145,7 @@ public:
 	GLint getAttribLocation(U32 attrib);
 	GLint mapUniformTextureChannel(GLint location, GLenum type);
 	
+    void clearPermutations();
 	void addPermutation(std::string name, std::string value);
 	void removePermutation(std::string name);
 	
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 11e84d8785..ec8f05e4ca 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -791,7 +791,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		}
 		*/
 
-		extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
+		extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP\n");
 
 		//uniform declartion
 		for (S32 i = 0; i < texture_index_channels; ++i)
@@ -850,11 +850,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 			LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL;
 		}
 	}
-	else
-	{
-		extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
-	}
-
     
 	//copy file into memory
 	enum {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 9191787273..a5076ef609 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -77,17 +77,11 @@ vec2 encode_normal (vec3 n);
 vec3 scaleSoftClipFrag(vec3 l);
 vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
 
-#if defined(VERT_ATMOSPHERICS)
-vec3 getSunlitColor();
-vec3 getAmblitColor();
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-void calcAtmospherics(vec3 inPositionEye, float ambFactor);
-#else
 void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
-#endif
 
+#ifdef HAS_SHADOW
 float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
 
 vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance ,float shadow)
 {
@@ -142,7 +136,11 @@ void main()
     vec4 pos = vec4(vary_position, 1.0);
     vec3 norm = vary_norm;
 
-    float shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+    float shadow = 1.0f;
+
+#ifdef HAS_SHADOW
+    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
 
 #ifdef USE_INDEXED_TEX
     vec4 diff = diffuseLookup(vary_texcoord0.xy);
@@ -184,14 +182,7 @@ void main()
     vec3 additive;
     vec3 atten;
 
-#if defined(VERT_ATMOSPHERICS)
-    sunlit = getSunlitColor();
-    amblit = getAmblitColor();
-    additive = getAdditiveColor();
-    atten = getAtmosAttenuation();
-#else
     calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten);
-#endif
 
     vec2 abnormal   = encode_normal(norm.xyz);
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 2db737a427..08ddaeceb3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -33,7 +33,7 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
-#if !HAS_DIFFUSE_LOOKUP
+#if !defined(HAS_DIFFUSE_LOOKUP)
 uniform sampler2D diffuseMap;
 #endif
 
@@ -62,7 +62,7 @@ uniform float minimum_alpha;
 
 void main() 
 {
-#if HAS_DIFFUSE_LOOKUP
+#ifdef HAS_DIFFUSE_LOOKUP
 	vec4 color = diffuseLookup(vary_texcoord0.xy);
 #else
 	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index 30e560450b..4005d5064d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -31,7 +31,7 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
-#ifndef diffuseLookup
+#ifndef HAS_DIFFUSE_LOOKUP
 uniform sampler2D diffuseMap;
 #endif
 
@@ -46,7 +46,7 @@ vec3 fullbrightScaleSoftClip(vec3 light);
 
 void main()
 {
-#if HAS_DIFFUSE_LOOKUP
+#ifdef HAS_DIFFUSE_LOOKUP
 	vec4 color = diffuseLookup(vary_texcoord0.xy);
 #else
 	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 4db2b9ae54..dd691fb36b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -41,14 +41,7 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
 vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
 vec3 scaleSoftClipFrag(vec3 l);
 
-#if defined(VERT_ATMOSPHERICS)
-vec3 getSunlitColor();
-vec3 getAmblitColor();
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-#else
 void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
-#endif
 
 vec3 srgb_to_linear(vec3 cs);
 vec3 linear_to_srgb(vec3 cs);
@@ -61,7 +54,9 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
+#ifdef HAS_SUN_SHADOW
 float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
 
 uniform samplerCube environmentMap;
 uniform sampler2D     lightFunc;
@@ -172,11 +167,11 @@ out vec4 frag_data[3];
 
 uniform sampler2D diffuseMap;
 
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
 uniform sampler2D bumpMap;
 #endif
 
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
 uniform sampler2D specularMap;
 
 VARYING vec2 vary_texcoord2;
@@ -189,7 +184,7 @@ uniform vec4 specular_color;  // specular color RGB and specular exponent (gloss
 uniform float minimum_alpha;
 #endif
 
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
 VARYING vec3 vary_mat0;
 VARYING vec3 vary_mat1;
 VARYING vec3 vary_mat2;
@@ -221,14 +216,14 @@ void main()
     vec3 gamma_diff = diffcol.rgb;
 #endif
 
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
     vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
     spec.rgb *= specular_color.rgb;
 #else
     vec4 spec = vec4(specular_color.rgb, 1.0);
 #endif
 
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
     vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
 
     norm.xyz = norm.xyz * 2 - 1;
@@ -255,7 +250,7 @@ void main()
 #endif
 
     vec4 final_specular = spec;
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
     vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
     final_specular.a = specular_color.a * norm.a;
 #else
@@ -268,8 +263,12 @@ void main()
         //forward rendering, output just lit RGBA
     vec3 pos = vary_position;
 
-    float shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
+    float shadow = 1.0f;
 
+#ifdef HAS_SUN_SHADOW
+    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
+#endif
+    
     spec = final_specular;
     vec4 diffuse = final_color;
 
@@ -285,14 +284,7 @@ void main()
     vec3 additive;
     vec3 atten;
 
-#if defined(VERT_ATMOSPHERICS)
-    sunlit   = getSunlitColor();
-    amblit   = getAmblitColor();
-    additive = getAdditiveColor();
-    atten    = getAtmosAttenuation();
-#else
     calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten);
-#endif
 
     vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 393d1e69da..7e29ada205 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -28,7 +28,7 @@
 #define DIFFUSE_ALPHA_MODE_MASK 2
 #define DIFFUSE_ALPHA_MODE_EMISSIVE 3
 
-#if HAS_SKIN
+#ifdef HAS_SKIN
 uniform mat4 modelview_matrix;
 uniform mat4 projection_matrix;
 mat4 getObjectSkinnedTransform();
@@ -39,7 +39,7 @@ uniform mat4 modelview_projection_matrix;
 
 #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 
-#if !HAS_SKIN
+#if !defined(HAS_SKIN)
 uniform mat4 modelview_matrix;
 #endif
 
@@ -55,7 +55,7 @@ ATTRIBUTE vec3 normal;
 ATTRIBUTE vec2 texcoord0;
 
 
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
 ATTRIBUTE vec4 tangent;
 ATTRIBUTE vec2 texcoord1;
 
@@ -68,7 +68,7 @@ VARYING vec2 vary_texcoord1;
 VARYING vec3 vary_normal;
 #endif
 
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
 ATTRIBUTE vec2 texcoord2;
 VARYING vec2 vary_texcoord2;
 #endif
@@ -78,7 +78,7 @@ VARYING vec2 vary_texcoord0;
 
 void main()
 {
-#if HAS_SKIN
+#ifdef HAS_SKIN
 	mat4 mat = getObjectSkinnedTransform();
 
 	mat = modelview_matrix * mat;
@@ -99,17 +99,17 @@ void main()
 	
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
 	vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
 #endif
 
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
 	vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
 #endif
 
-#if HAS_SKIN
+#ifdef HAS_SKIN
 	vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
 	vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
 	vec3 b = cross(n, t)*tangent.w;
 	
@@ -121,7 +121,7 @@ vary_normal  = n;
 #endif //HAS_NORMAL_MAP
 #else //HAS_SKIN
 	vec3 n = normalize(normal_matrix * normal);
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
 	vec3 t = normalize(normal_matrix * tangent.xyz);
 	vec3 b = cross(n,t)*tangent.w;
 	//vec3 t = cross(b,n) * binormal.w;
@@ -137,7 +137,7 @@ vary_normal  = n;
 	vertex_color = diffuse_color;
 
 #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-#if !HAS_SKIN
+#if !defined(HAS_SKIN)
 	vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
 #endif
 #endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index bd187ed5fc..07a24698a9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -71,15 +71,7 @@ vec3 getNorm(vec2 pos_screen);
 vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
 vec3 fullbrightAtmosTransportFrag(vec3 l, vec3 additive, vec3 atten);
 
-#if defined(VERT_ATMOSPHERICS)
-vec3 getPositionEye();
-vec3 getSunlitColor();
-vec3 getAmblitColor();
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-#else
 void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
-#endif
 
 vec3 scaleSoftClip(vec3 l);
 vec3 fullbrightScaleSoftClip(vec3 l);
@@ -114,14 +106,7 @@ void main()
         vec3 additive;
         vec3 atten;
 
-#if defined(VERT_ATMOSPHERICS)
-        sunlit   = getSunlitColor();
-        amblit   = getAmblitColor();
-        additive = getAdditiveColor();
-        atten    = getAtmosAttenuation();
-#else
         calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten);
-#endif
 
         float ambient = min(abs(da), 1.0);
         ambient *= 0.5;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 628f73da59..be5e3538a7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -167,8 +167,6 @@ void main()
 
     vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
 
-color.rgb = max(fb.rgb, refcol.rgb);
-
     frag_data[0] = vec4(color.rgb, 1); // diffuse
     frag_data[1] = vec4(0);     // speccolor, spec
     frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 26254bd8a3..e30ff42b4f 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1400,10 +1400,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
         gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
         gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+        gDeferredSkinnedAlphaProgram.clearPermutations();
         gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
         gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
         gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
-        gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");
+        if (use_sun_shadow)
+        {
+            gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1");
+        }
         success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
         llassert(success);
 
@@ -1456,23 +1461,41 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
             gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
             gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-            gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
-            gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
+
+            gDeferredMaterialProgram[i].clearPermutations();
+
+            bool has_normal_map   = (i & 0x8) > 0;
+            bool has_specular_map = (i & 0x4) > 0;
+
+            if (has_normal_map)
+            {
+                gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
+            }
+
+            if (has_specular_map)
+            {
+                gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
+            }
+
             gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-            gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", use_sun_shadow ? "1" : "0");
-            bool has_skin = i & 0x10;
-            gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
 
+            if (use_sun_shadow)
+            {
+                gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
+            }
+
+            bool has_skin = i & 0x10;
             gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
             gDeferredMaterialProgram[i].mFeatures.hasTransport = true;
             gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
             gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
             gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
             gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
-            gDeferredMaterialProgram[i].mFeatures.hasShadows = true;
+            gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
             
             if (has_skin)
             {
+                gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
                 gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
             }
 
@@ -1494,12 +1517,32 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
             gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
 
-            gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
-            gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
+            gDeferredMaterialWaterProgram[i].clearPermutations();
+
+            bool has_normal_map   = (i & 0x8) > 0;
+            bool has_specular_map = (i & 0x4) > 0;
+
+            if (has_normal_map)
+            {
+                gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
+            }
+
+            if (has_specular_map)
+            {
+                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
+            }
+
             gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-            gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", use_sun_shadow ? "1" : "0");
+            if (use_sun_shadow)
+            {
+                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
+            }
+
             bool has_skin = i & 0x10;
-            gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
+            if (has_skin)
+            {
+                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1");
+            }
             gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
 
             gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
@@ -1510,7 +1553,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true;
 
             gDeferredMaterialWaterProgram[i].mFeatures.hasTransport = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = true;
+            gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = use_sun_shadow;
             
             if (has_skin)
             {
@@ -1707,7 +1750,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
         gDeferredAlphaProgram.mFeatures.hasGamma = true;
         gDeferredAlphaProgram.mFeatures.hasTransport = true;
-        gDeferredAlphaProgram.mFeatures.hasShadows = true;
+        gDeferredAlphaProgram.mFeatures.hasShadows = use_sun_shadow;
 
         if (mShaderLevel[SHADER_DEFERRED] < 1)
         {
@@ -1721,8 +1764,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAlphaProgram.mShaderFiles.clear();
         gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
         gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+        gDeferredAlphaProgram.clearPermutations();
+
         gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
-        gDeferredAlphaProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");
+        if (use_sun_shadow)
+        {
+            gDeferredAlphaProgram.addPermutation("HAS_SHADOW", "1");
+        }
         gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
         gDeferredAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
 
@@ -1743,7 +1792,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
         gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true;
         gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true;
-        gDeferredAlphaImpostorProgram.mFeatures.hasShadows = true;
+        gDeferredAlphaImpostorProgram.mFeatures.hasShadows = use_sun_shadow;
 
         gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
         if (mShaderLevel[SHADER_DEFERRED] < 1)
@@ -1758,11 +1807,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAlphaImpostorProgram.mShaderFiles.clear();
         gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
         gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+        gDeferredAlphaImpostorProgram.clearPermutations();
         gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
-        gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");
         gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
         gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
 
+        if (use_sun_shadow)
+        {
+            gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", "1");
+        }
+
         gDeferredAlphaImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
 
         success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
@@ -1787,7 +1842,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true;
         gDeferredAlphaWaterProgram.mFeatures.hasGamma = true;
         gDeferredAlphaWaterProgram.mFeatures.hasTransport = true;
-        gDeferredAlphaWaterProgram.mFeatures.hasShadows = true;
+        gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow;
 
         if (mShaderLevel[SHADER_DEFERRED] < 1)
         {
@@ -1801,10 +1856,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAlphaWaterProgram.mShaderFiles.clear();
         gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
         gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+        gDeferredAlphaWaterProgram.clearPermutations();
         gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");
         gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");
         gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
-        gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");
+        if (use_sun_shadow)
+        {
+            gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1");
+        }
         gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
 
         success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);
@@ -2230,6 +2290,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAvatarAlphaProgram.mShaderFiles.clear();
         gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
         gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+        gDeferredAvatarAlphaProgram.clearPermutations();
         gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
         gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
         if (use_sun_shadow)
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2adee2a0ae..6e7e8eef21 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -403,7 +403,8 @@ LLPipeline::LLPipeline() :
     mLightMovingMask(0),
     mLightingDetail(0),
     mScreenWidth(0),
-    mScreenHeight(0)
+    mScreenHeight(0),
+    mNeedsShadowTargetClear(true)
 {
     mNoiseMap = 0;
     mTrueNoiseMap = 0;
@@ -9336,7 +9337,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
         S32 occlusion = LLPipeline::sUseOcclusion;
 
         //disable occlusion culling for reflection map for now
-        LLPipeline::sUseOcclusion = 0;
+        //LLPipeline::sUseOcclusion = 0;
 
         glh::matrix4f current = get_current_modelview();
 
@@ -9484,7 +9485,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
                 //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,
                 // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map
-                LLPlane plane(pnorm, -water_height * LLPipeline::sDistortionWaterClipPlaneMargin);
+                LLPlane plane(-pnorm, water_height * LLPipeline::sDistortionWaterClipPlaneMargin);
+
                 LLGLUserClipPlane clip_plane(plane, current, projection);
 
                 gGL.setColorMask(true, true);
@@ -9503,7 +9505,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
                 renderGeom(camera);
 
-                /*if (LLGLSLShader::sNoFixedFunction)
+                if (LLGLSLShader::sNoFixedFunction)
                 {
                     gUIProgram.bind();
                 }
@@ -9513,7 +9515,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
                 if (LLGLSLShader::sNoFixedFunction)
                 {
                     gUIProgram.unbind();
-                }*/
+                }
 
                 mWaterDis.flush();
             }
@@ -10090,11 +10092,33 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 {
     if (!sRenderDeferred || RenderShadowDetail <= 0)
     {
+        if (mNeedsShadowTargetClear)
+        {
+            LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+            for (S32 j = 0; j < 6; j++)
+            {
+                LLRenderTarget* shadow_target = getShadowTarget(j);
+                if (shadow_target)
+                {
+                    shadow_target->bindTarget();
+                    shadow_target->clear();
+                    shadow_target->flush();
+                }
+            }
+            mNeedsShadowTargetClear = false;
+        }
+
         return;
     }
 
+    mNeedsShadowTargetClear = true;
+
     LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
 
+    LLEnvironment& environment = LLEnvironment::instance();
+    LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
     bool skip_avatar_update = false;
     if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
     {
@@ -10156,6 +10180,43 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
         gGL.setColorMask(false, false);
     }
 
+    bool sun_up         = environment.getIsSunUp();
+    bool moon_up        = environment.getIsMoonUp();
+    bool ignore_shadows = (shadow_detail == 0) 
+                       || (sun_up  && (mSunDiffuse == LLColor4::black))
+                       || (moon_up && (mMoonDiffuse == LLColor4::black))
+                       || !(sun_up || moon_up);
+
+    if (ignore_shadows)
+    { //sun diffuse is totally black, shadows don't matter
+        LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+        for (S32 j = 0; j < 4; j++)
+        {
+            LLRenderTarget* shadow_target = getShadowTarget(j);
+            if (shadow_target)
+            {
+                shadow_target->bindTarget();
+                shadow_target->clear();
+                shadow_target->flush();
+            }
+        }
+
+        if (shadow_detail == 0) 
+        {
+            for (S32 j = 4; j < 6; j++)
+            {
+                LLRenderTarget* shadow_target = getShadowTarget(j);
+                if (shadow_target)
+                {
+                    shadow_target->bindTarget();
+                    shadow_target->clear();
+                    shadow_target->flush();
+                }
+            }
+        }
+    }
+
     //get sun view matrix
     
     //store current projection/modelview matrix
@@ -10181,9 +10242,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
     //LLVector3 n = RenderShadowNearDist;
     //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
 
-    LLEnvironment& environment = LLEnvironment::instance();
-    LLSettingsSky::ptr_t psky = environment.getCurrentSky();
-
     LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
 
     //put together a universal "near clip" plane for shadow frusta
@@ -10216,7 +10274,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
     up.normVec();
     at.normVec();
     
-    
     LLCamera main_camera = camera;
     
     F32 near_clip = 0.f;
@@ -10298,28 +10355,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
     // convenience array of 4 near clip plane distances
     F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
 
-    bool sun_up         = environment.getIsSunUp();
-    bool moon_up        = environment.getIsMoonUp();
-    bool ignore_shadows = (sun_up  && (mSunDiffuse == LLColor4::black))
-                       || (moon_up && (mMoonDiffuse == LLColor4::black))
-                       || !(sun_up || moon_up);
-
-    if (ignore_shadows)
-    { //sun diffuse is totally black, shadows don't matter
-        LLGLDepthTest depth(GL_TRUE);
-
-        for (S32 j = 0; j < 4; j++)
-        {
-            LLRenderTarget* shadow_target = getShadowTarget(j);
-            if (shadow_target)
-            {
-                shadow_target->bindTarget();
-                shadow_target->clear();
-                shadow_target->flush();
-            }
-        }
-    }
-    else
+    if (!ignore_shadows)
     {
         for (S32 j = 0; j < 4; j++)
         {
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 1c39fb13b6..a31f880fbf 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -666,6 +666,7 @@ public:
     LLColor4			mMoonDiffuse;
 	LLVector4			mSunDir;
     LLVector4			mMoonDir;
+    bool                mNeedsShadowTargetClear;
 
 	LLVector4			mTransformedSunDir;
     LLVector4			mTransformedMoonDir;
-- 
cgit v1.2.3