From 42ec639c860e172803753b9cb41ae9483305f2f8 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 12 Oct 2022 14:46:51 -0500
Subject: [PATCH] SL-18190 Remove water reflection detail combo box and
 reimplement "Transparent Water" checkbox.

---
 indra/llrender/llshadermgr.cpp                |   1 +
 indra/llrender/llshadermgr.h                  |   1 +
 indra/newview/CMakeLists.txt                  |   4 -
 indra/newview/app_settings/high_graphics.xml  |  41 --
 indra/newview/app_settings/low_graphics.xml   |  41 --
 indra/newview/app_settings/mid_graphics.xml   |  41 --
 indra/newview/app_settings/settings.xml       |   2 +-
 .../class3/environment/underWaterF.glsl       |  19 +-
 .../shaders/class3/environment/waterF.glsl    |   7 +
 indra/newview/app_settings/ultra_graphics.xml |  42 --
 indra/newview/featuretable.txt                |  22 +-
 indra/newview/featuretable_mac.txt            |   9 -
 indra/newview/lldrawpoolalpha.cpp             |   5 +
 indra/newview/lldrawpoolwater.cpp             |  32 +-
 indra/newview/llfloaterpreference.cpp         |  32 +-
 indra/newview/llsettingsvo.cpp                |   4 +-
 indra/newview/llviewerdisplay.cpp             |   1 -
 indra/newview/llviewershadermgr.cpp           |  16 +-
 indra/newview/pipeline.cpp                    | 362 +-----------------
 indra/newview/pipeline.h                      |   3 -
 .../floater_preferences_graphics_advanced.xml |  51 ---
 21 files changed, 82 insertions(+), 654 deletions(-)
 delete mode 100644 indra/newview/app_settings/high_graphics.xml
 delete mode 100644 indra/newview/app_settings/low_graphics.xml
 delete mode 100644 indra/newview/app_settings/mid_graphics.xml
 delete mode 100644 indra/newview/app_settings/ultra_graphics.xml

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index a363eac59e7..7f7829c18e4 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1357,6 +1357,7 @@ void LLShaderMgr::initAttribsAndUniforms()
 	mReservedUniforms.push_back("specular");
 	mReservedUniforms.push_back("lightExp");
 	mReservedUniforms.push_back("waterFogColor");
+    mReservedUniforms.push_back("waterFogColorLinear");
 	mReservedUniforms.push_back("waterFogDensity");
 	mReservedUniforms.push_back("waterFogKS");
 	mReservedUniforms.push_back("refScale");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index b803a8b129b..6d2138f4051 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -205,6 +205,7 @@ class LLShaderMgr
         WATER_SPECULAR,                     //  "specular"
         WATER_SPECULAR_EXP,                 //  "lightExp"
         WATER_FOGCOLOR,                     //  "waterFogColor"
+        WATER_FOGCOLOR_LINEAR,              //  "waterFogColorLinear"
         WATER_FOGDENSITY,                   //  "waterFogDensity"
         WATER_FOGKS,                        //  "waterFogKS"
         WATER_REFSCALE,                     //  "refScale"
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index bfc41e31530..1882f75de9e 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1701,13 +1701,10 @@ set(viewer_APPSETTINGS_FILES
     app_settings/cmd_line.xml
     app_settings/commands.xml
     app_settings/grass.xml
-    app_settings/high_graphics.xml
     app_settings/ignorable_dialogs.xml
     app_settings/key_bindings.xml
     app_settings/keywords_lsl_default.xml
     app_settings/logcontrol.xml
-    app_settings/low_graphics.xml
-    app_settings/mid_graphics.xml
     app_settings/settings.xml
     app_settings/settings_crash_behavior.xml
     app_settings/settings_files.xml
@@ -1715,7 +1712,6 @@ set(viewer_APPSETTINGS_FILES
     app_settings/std_bump.ini
     app_settings/toolbars.xml
     app_settings/trees.xml
-    app_settings/ultra_graphics.xml
     app_settings/viewerart.xml
     ${CMAKE_SOURCE_DIR}/../etc/message.xml
     ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
deleted file mode 100644
index f64937f4437..00000000000
--- a/indra/newview/app_settings/high_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
-	<!--NO SHADERS-->
-	<RenderAvatarCloth value="FALSE"/>
-	<!--Default for now-->
-	<RenderAvatarLODFactor value="1.0"/>
-	<!--Default for now-->
-	<RenderAvatarPhysicsLODFactor value="0.9"/>
-	<!--Short Range-->
-	<RenderFarClip value="128"/>
-	<!--Default for now-->
-	<RenderFlexTimeFactor value="1"/>
-	<!--256... but they do not use this-->
-	<RenderGlowResolutionPow value="9"/>
-	<!--Low number-->
-	<RenderMaxPartCount value="4096"/>
-	<!--bump okay-->
-	<RenderObjectBump value="TRUE"/>
-	<!--NO SHADERS-->
-	<RenderReflectionDetail value="2"/>
-	<!--Simple-->
-	<RenderTerrainDetail value="1"/>
-	<!--Default for now-->
-	<RenderTerrainLODFactor value="2"/>
-	<!--Default for now-->
-	<RenderTreeLODFactor value="0.5"/>
-	<!--Avater Impostors and Visual Muting Limits-->
-    <RenderAvatarMaxNonImpostors     value="20"/>
-    <RenderAvatarMaxComplexity              value="350000"/>
-    <RenderAutoMuteSurfaceAreaLimit  value="1250.0"/>
-	<!--Default for now-->
-	<RenderVolumeLODFactor value="1.125"/>
-	<!--NO SHADERS-->
-	<WindLightUseAtmosShaders value="TRUE"/>
-	<!--Deferred Shading-->
-	<RenderDeferred value="FALSE"/>
-	<!--SSAO Disabled-->
-	<RenderDeferredSSAO value="FALSE"/>
-	<!--Sun Shadows-->
-	<RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
deleted file mode 100644
index b31a040d67e..00000000000
--- a/indra/newview/app_settings/low_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
-	<!--NO SHADERS-->
-	<RenderAvatarCloth value="FALSE"/>
-	<!--Default for now-->
-	<RenderAvatarLODFactor value="0.5"/>
-	<!--Default for now-->
-	<RenderAvatarPhysicsLODFactor value="0.0"/>
-	<!--Short Range-->
-	<RenderFarClip value="64"/>
-	<!--Default for now-->
-	<RenderFlexTimeFactor value="0.5"/>
-	<!--256... but they do not use this-->
-	<RenderGlowResolutionPow value="8"/>
-	<!--Low number-->
-	<RenderMaxPartCount value="1024"/>
-	<!--bump okay-->
-	<RenderObjectBump value="FALSE"/>
-	<!--NO SHADERS-->
-	<RenderReflectionDetail value="0"/>
-	<!--Simple-->
-	<RenderTerrainDetail value="0"/>
-	<!--Default for now-->
-	<RenderTerrainLODFactor value="1.0"/>
-	<!--Default for now-->
-	<RenderTreeLODFactor value="0.5"/>
-	<!--Avater Impostors and Visual Muting Limits-->
-    <RenderAvatarMaxNonImpostors     value="12"/>
-    <RenderAvatarMaxComplexity              value="80000"/>
-    <RenderAutoMuteSurfaceAreaLimit  value="750.0"/>
-	<!--Default for now-->
-	<RenderVolumeLODFactor value="1.125"/>
-	<!--NO SHADERS-->
-	<WindLightUseAtmosShaders value="FALSE"/>
-	<!--No Deferred Shading-->
-	<RenderDeferred value="FALSE"/>
-	<!--SSAO Disabled-->
-	<RenderDeferredSSAO value="FALSE"/>
-	<!--No Shadows-->
-	<RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
deleted file mode 100644
index 9c2c17fc608..00000000000
--- a/indra/newview/app_settings/mid_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
-	<!--NO SHADERS-->
-	<RenderAvatarCloth value="FALSE"/>
-	<!--Default for now-->
-	<RenderAvatarLODFactor value="0.5"/>
-	<!--Default for now-->
-	<RenderAvatarPhysicsLODFactor value="0.75"/>
-	<!--Short Range-->
-	<RenderFarClip value="96"/>
-	<!--Default for now-->
-	<RenderFlexTimeFactor value="1"/>
-	<!--256... but they do not use this-->
-	<RenderGlowResolutionPow value="8"/>
-	<!--Low number-->
-	<RenderMaxPartCount value="2048"/>
-	<!--bump okay-->
-	<RenderObjectBump value="TRUE"/>
-	<!--NO SHADERS-->
-	<RenderReflectionDetail value="0"/>
-	<!--Simple-->
-	<RenderTerrainDetail value="1"/>
-	<!--Default for now-->
-	<RenderTerrainLODFactor value="1.0"/>
-	<!--Default for now-->
-	<RenderTreeLODFactor value="0.5"/>
-	<!--Avater Impostors and Visual Muting Limits-->
-    <RenderAvatarMaxNonImpostors     value="18"/>
-    <RenderAvatarMaxComplexity              value="150000"/>
-    <RenderAutoMuteSurfaceAreaLimit  value="1000.0"/>
-	<!--Default for now-->
-	<RenderVolumeLODFactor value="1.125"/>
-	<!--NO SHADERS-->
-	<WindLightUseAtmosShaders value="FALSE"/>
-	<!--No Deferred Shading-->
-	<RenderDeferred value="FALSE"/>
-	<!--SSAO Disabled-->
-	<RenderDeferredSSAO value="FALSE"/>
-	<!--No Shadows-->
-	<RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f183f490390..2eee9f2f25d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10306,7 +10306,7 @@
     <key>RenderReflectionDetail</key>
     <map>
       <key>Comment</key>
-      <string>Detail of reflection render pass.</string>
+      <string>DEPRECATED -- use RenderTransparentWater and RenderReflectionProbeDetail -- Detail of reflection render pass.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 819e6dcf15a..a5e0adf8fa3 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -26,10 +26,12 @@
 out vec4 frag_color;
 
 uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;   
+uniform sampler2D bumpMap;
+
+#ifdef TRANSPARENT_WATER
 uniform sampler2D screenTex;
-uniform sampler2D refTex;
 uniform sampler2D screenDepth;
+#endif
 
 uniform vec4 fogCol;
 uniform vec3 lightDir;
@@ -43,6 +45,7 @@ uniform float kd;
 uniform vec4 waterPlane;
 uniform vec3 eyeVec;
 uniform vec4 waterFogColor;
+uniform vec3 waterFogColorLinear;
 uniform float waterFogKS;
 uniform vec2 screenRes;
 
@@ -57,8 +60,8 @@ vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 void main() 
 {
 	vec4 color;
-	    
-	//get detail normals
+
+    //get detail normals
 	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
 	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
 	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;    
@@ -67,8 +70,12 @@ void main()
 	//figure out distortion vector (ripply)   
 	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
 	distort = distort+wavef.xy*refScale;
-		
+
+#ifdef TRANSPARENT_WATER
 	vec4 fb = texture2D(screenTex, distort);
-	
+#else
+    vec4 fb = vec4(waterFogColorLinear, 0.0);
+#endif
+    
 	frag_color = applyWaterFogViewLinear(vary_position, fb);
 }
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 9793a0e7862..a6517be433f 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -55,8 +55,10 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
 uniform sampler2D bumpMap;
 uniform sampler2D bumpMap2;
 uniform float     blend_factor;
+#ifdef TRANSPARENT_WATER
 uniform sampler2D screenTex;
 uniform sampler2D screenDepth;
+#endif
 
 uniform sampler2D refTex;
 
@@ -73,6 +75,7 @@ uniform float fresnelScale;
 uniform float fresnelOffset;
 uniform float blurMultiplier;
 uniform vec4 waterFogColor;
+uniform vec3 waterFogColorLinear;
 
 
 //bigWave is (refCoord.w, view.w);
@@ -174,6 +177,7 @@ void main()
     vec2 distort2 = distort + waver.xy * refScale / max(dmod * df1, 1.0);
     distort2 = clamp(distort2, vec2(0), vec2(0.99));
  
+#ifdef TRANSPARENT_WATER
     vec4 fb = texture2D(screenTex, distort2);
     float depth = texture2D(screenDepth, distort2).r;
     vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
@@ -188,6 +192,9 @@ void main()
     }
 
     fb = applyWaterFogViewLinear(refPos, fb);
+#else
+    vec4 fb = vec4(waterFogColorLinear.rgb, 0.0);
+#endif
 
     vec3 sunlit;
     vec3 amblit;
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
deleted file mode 100644
index 8462df207bc..00000000000
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
-	<!--NO SHADERS-->
-	<RenderAvatarCloth value="TRUE"/>
-	<!--Default for now-->
-	<RenderAvatarLODFactor value="1.0"/>
-	<!--Default for now-->
-	<RenderAvatarPhysicsLODFactor value="1.0"/>
-	<!--Short Range-->
-	<RenderFarClip value="256"/>
-	<!--Default for now-->
-	<RenderFlexTimeFactor value="1"/>
-	<!--256... but they do not use this-->
-	<RenderGlowResolutionPow value="9"/>
-	<!--Low number-->
-	<RenderMaxPartCount value="4096"/>
-	<!--bump okay-->
-	<RenderObjectBump value="TRUE"/>
-	<!--NO SHADERS-->
-	<RenderReflectionDetail value="4"/>
-	<!--Simple-->
-	<RenderTerrainDetail value="1"/>
-	<!--Default for now-->
-	<RenderTerrainLODFactor value="2.0"/>
-	<!--Default for now-->
-	<RenderTreeLODFactor value="1.0"/>
-	<!--Avater Impostors and Visual Muting Limits (real defaults set
-        based on default graphics setting -->
-    <RenderAvatarMaxNonImpostors     value="0"/>
-    <RenderAvatarMaxComplexity       value="350000"/>
-    <RenderAutoMuteSurfaceAreaLimit  value="1500.0"/>
-	<!--Default for now-->
-	<RenderVolumeLODFactor value="2.0"/>
-	<!--NO SHADERS-->
-	<WindLightUseAtmosShaders value="TRUE"/>
-	<!--Deferred Shading-->
-	<RenderDeferred value="TRUE"/>
-	<!--SSAO Enabled-->
-	<RenderDeferredSSAO value="TRUE"/>
-	<!--Full Shadows-->
-	<RenderShadowDetail value="2"/>
-</settings>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index ddd24b70c63..2cb48e51d04 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -46,11 +46,10 @@ RenderGround				1	1
 RenderMaxPartCount			1	8192
 RenderObjectBump			1	1
 RenderLocalLights			1	1
-RenderReflectionDetail		1	4
+RenderTransparentWater      1   1
 RenderReflectionProbeDetail		1	2
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
-RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderVBOEnable				1	1
 RenderVBOMappingDisable		1	1
@@ -90,11 +89,10 @@ RenderFlexTimeFactor		1	0
 RenderGlowResolutionPow		1	8
 RenderLocalLights			1	0
 RenderMaxPartCount			1	0
-RenderReflectionDetail		1	0
+RenderTransparentWater      1   0
 RenderReflectionProbeDetail	1	-1
 RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
-RenderTransparentWater		1	0
 RenderTreeLODFactor			1	0
 RenderVolumeLODFactor		1	1.125
 RenderDeferredSSAO			1	0
@@ -116,11 +114,10 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	8
 RenderMaxPartCount			1	2048
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
+RenderTransparentWater      1   0
 RenderReflectionProbeDetail	1	-1
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	1.0
-RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderVolumeLODFactor		1	1.125
 RenderDeferredSSAO			1	0
@@ -142,10 +139,9 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
+RenderTransparentWater      1   0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
-RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderVolumeLODFactor		1	1.125
 RenderDeferredSSAO			1	0
@@ -168,10 +164,9 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
+RenderTransparentWater      1   1
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
-RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderVolumeLODFactor		1	1.125
 RenderDeferredSSAO			1	0
@@ -194,10 +189,9 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
+RenderTransparentWater      1   1
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
-RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderVolumeLODFactor		1	1.125
 RenderDeferredSSAO			1	1
@@ -220,7 +214,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -245,7 +238,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderLocalLights			1	1
 RenderMaxPartCount			1	8192
-RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -283,7 +275,7 @@ RenderAvatarMaxComplexity          1	80000
 RenderLocalLights			1	0
 RenderMaxPartCount			1	1024
 RenderTerrainDetail 		1	0
-RenderReflectionDetail		0	0
+RenderTransparentWater      1   0
 RenderDeferredSSAO			0	0
 RenderShadowDetail			0	0
 RenderReflectionProbeDetail	0	-1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 98f498f59d1..d40e7aff0b7 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -46,7 +46,6 @@ RenderGround				1	1
 RenderMaxPartCount			1	8192
 RenderObjectBump			1	1
 RenderLocalLights			1	1
-RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -88,7 +87,6 @@ RenderFlexTimeFactor		1	0
 RenderGlowResolutionPow		1	8
 RenderLocalLights			1	0
 RenderMaxPartCount			1	0
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
 RenderTransparentWater		1	0
@@ -114,7 +112,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	8
 RenderMaxPartCount			1	2048
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	1.0
 RenderTransparentWater		1	1
@@ -140,7 +137,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -166,7 +162,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -192,7 +187,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -218,7 +212,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderMaxPartCount			1	4096
 RenderLocalLights			1	1
-RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -243,7 +236,6 @@ RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
 RenderLocalLights			1	1
 RenderMaxPartCount			1	8192
-RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
@@ -282,7 +274,6 @@ RenderAvatarMaxComplexity          1	80000
 RenderLocalLights			1	0
 RenderMaxPartCount			1	1024
 RenderTerrainDetail 		1	0
-RenderReflectionDetail		0	0
 RenderDeferredSSAO			0	0
 RenderUseAdvancedAtmospherics 0 0
 RenderShadowDetail			0	0
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 0d9e83a9765..01b2647eaac 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -147,6 +147,11 @@ extern BOOL gCubeSnapshot;
 void LLDrawPoolAlpha::renderPostDeferred(S32 pass) 
 { 
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+    if ((!LLPipeline::sRenderTransparentWater || gCubeSnapshot) && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+    { // don't render alpha objects on the other side of the water plane if water is opaque
+        return;
+    }
     deferred_render = TRUE;
 
     F32 water_sign = 1.f;
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 18e405b1710..3f39716449d 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -57,6 +57,8 @@ BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
 BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
 F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
 
+extern BOOL gCubeSnapshot;
+
 LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER)
 {
 }
@@ -124,15 +126,19 @@ S32 LLDrawPoolWater::getNumPostDeferredPasses()
 
 void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
 {
-    // copy framebuffer contents so far to a texture to be used for
-    // reflections and refractions
-    LLRenderTarget& src = gPipeline.mRT->screen;
-    LLRenderTarget& dst = gPipeline.mWaterDis;
-    dst.copyContents(src, 
-        0, 0, src.getWidth(), src.getHeight(), 
-        0, 0, dst.getWidth(), dst.getHeight(), 
-        GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, 
-        GL_NEAREST);
+    LL_PROFILE_GPU_ZONE("water beginPostDeferredPass")
+    if (LLPipeline::sRenderTransparentWater && !gCubeSnapshot)
+    {
+        // copy framebuffer contents so far to a texture to be used for
+        // reflections and refractions
+        LLRenderTarget& src = gPipeline.mRT->screen;
+        LLRenderTarget& dst = gPipeline.mWaterDis;
+        dst.copyContents(src,
+            0, 0, src.getWidth(), src.getHeight(),
+            0, 0, dst.getWidth(), dst.getHeight(),
+            GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+            GL_NEAREST);
+    }
 }
 
 void LLDrawPoolWater::renderPostDeferred(S32 pass) 
@@ -151,6 +157,7 @@ S32 LLDrawPoolWater::getNumDeferredPasses()
 //===============================
 void LLDrawPoolWater::renderDeferred(S32 pass)
 {
+#if 0
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
 
     if (!LLPipeline::sRenderTransparentWater)
@@ -163,6 +170,7 @@ void LLDrawPoolWater::renderDeferred(S32 pass)
 	deferred_render = TRUE;
 	renderWater();
 	deferred_render = FALSE;
+#endif
 }
 
 //=========================================
@@ -508,6 +516,8 @@ void LLDrawPoolWater::renderWater()
     bool                   moon_up         = environment.getIsMoonUp();
     bool                   has_normal_mips = gSavedSettings.getBOOL("RenderWaterMipNormal");
     bool                   underwater      = LLViewerCamera::getInstance()->cameraUnderWater();
+    LLColor4               fog_color       = LLColor4(pwater->getWaterFogColor(), 0.f);
+    LLColor3               fog_color_linear = linearColor3(fog_color);
 
     if (sun_up)
     {
@@ -543,7 +553,7 @@ void LLDrawPoolWater::renderWater()
     for( int edge = 0 ; edge < 2; edge++ )
     {
         // select shader
-        if (underwater && LLPipeline::sWaterReflections)
+        if (underwater)
         {
             shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram;
         }
@@ -619,7 +629,6 @@ void LLDrawPoolWater::renderWater()
         shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
         shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 
-        LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
         F32      fog_density = pwater->getModifiedWaterFogDensity(underwater);
 
         if (screentex > -1)
@@ -646,6 +655,7 @@ void LLDrawPoolWater::renderWater()
 
         shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
         shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+        shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
 
         shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
         shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 01ebdf6830d..6153d710982 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1194,14 +1194,6 @@ void LLFloaterPreference::refreshEnabledState()
 
 void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
 {
-	LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
-	LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
-
-	// Reflections
-    BOOL reflections = LLCubeMap::sUseCubeMaps;
-	ctrl_reflections->setEnabled(reflections);
-	reflections_text->setEnabled(reflections);
-
     // WindLight
     LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
     LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
@@ -1282,8 +1274,6 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
 
 void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
 {	
-	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");
-	LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
 	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
 	LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
 	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
@@ -1291,25 +1281,17 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
     // disabled deferred SSAO
 	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
 	{
-		ctrl_ssao->setEnabled(FALSE);
+		ctrl_ssao->setEnabled(FALSE);   
 		ctrl_ssao->setValue(FALSE);
 	}
 	
 	// disabled deferred shadows
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
-	{
-		ctrl_shadows->setEnabled(FALSE);
-		ctrl_shadows->setValue(0);
-		shadows_text->setEnabled(FALSE);
-	}
-
-	// disabled reflections
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
-	{
-		ctrl_reflections->setEnabled(FALSE);
-		ctrl_reflections->setValue(FALSE);
-		reflections_text->setEnabled(FALSE);
-	}
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
+    {
+        ctrl_shadows->setEnabled(FALSE);
+        ctrl_shadows->setValue(0);
+        shadows_text->setEnabled(FALSE);
+    }
 }
 
 void LLFloaterPreference::refresh()
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 3c43a7e6257..ddd9c568411 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -965,9 +965,11 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
         F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(underwater);
         shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
 
-        LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f);
+        LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor());
         shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
 
+        shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, linearColor3(fog_color.mV).mV);
+
         F32 blend_factor = env.getCurrentWater()->getBlendFactor();
         shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index b3bc831670a..d570891cbff 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -772,7 +772,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		{
 			LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 3")
 			LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
-			gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
 			gPipeline.generateHighlight(*LLViewerCamera::getInstance());
 			gPipeline.renderPhysicsDisplay();
 		}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index e7dbdf2bea2..718ed9e6662 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -463,7 +463,6 @@ void LLViewerShaderMgr::setShaders()
     initAttribsAndUniforms();
     gPipeline.releaseGLBuffers();
 
-    LLPipeline::sWaterReflections = LLPipeline::sRenderTransparentWater;
     LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); 
     LLPipeline::updateRenderDeferred();
     
@@ -1029,6 +1028,11 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		gWaterProgram.mShaderFiles.clear();
 		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
 		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+        gWaterProgram.clearPermutations();
+        if (LLPipeline::sRenderTransparentWater)
+        {
+            gWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+        }
 		gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
 		gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
 		success = gWaterProgram.createShader(NULL, NULL);
@@ -1050,6 +1054,11 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
 		gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
 		gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
+        gWaterEdgeProgram.clearPermutations();
+        if (LLPipeline::sRenderTransparentWater)
+        {
+            gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
+        }
 		gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
 		gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
 		success = gWaterEdgeProgram.createShader(NULL, NULL);
@@ -1067,6 +1076,11 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
 		gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];        
 		gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;       
+        gUnderWaterProgram.clearPermutations();
+        if (LLPipeline::sRenderTransparentWater)
+        {
+            gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+        }
 		success = gUnderWaterProgram.createShader(NULL, NULL);
 		llassert(success);
 	}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d8af012cc07..93ae6e99a52 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -203,7 +203,6 @@ F32 LLPipeline::RenderEdgeNormCutoff;
 LLVector3 LLPipeline::RenderShadowGaussian;
 F32 LLPipeline::RenderShadowBlurDistFactor;
 bool LLPipeline::RenderDeferredAtmospheric;
-S32 LLPipeline::RenderReflectionDetail;
 F32 LLPipeline::RenderHighlightFadeTime;
 LLVector3 LLPipeline::RenderShadowClipPlanes;
 LLVector3 LLPipeline::RenderShadowOrthoClipPlanes;
@@ -316,7 +315,6 @@ bool	LLPipeline::sNoAlpha = false;
 bool	LLPipeline::sUseTriStrips = true;
 bool	LLPipeline::sUseFarClip = true;
 bool	LLPipeline::sShadowRender = false;
-bool	LLPipeline::sWaterReflections = false;
 bool	LLPipeline::sRenderGlow = false;
 bool	LLPipeline::sReflectionRender = false;
 bool    LLPipeline::sDistortionRender = false;
@@ -570,7 +568,6 @@ void LLPipeline::init()
 	connectRefreshCachedSettingsSafe("RenderShadowGaussian");
 	connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
 	connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
-	connectRefreshCachedSettingsSafe("RenderReflectionDetail");
 	connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
 	connectRefreshCachedSettingsSafe("RenderShadowClipPlanes");
 	connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes");
@@ -1072,7 +1069,6 @@ void LLPipeline::refreshCachedSettings()
 	RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
 	RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
 	RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
-	RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
 	RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
 	RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes");
 	RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
@@ -1193,10 +1189,9 @@ void LLPipeline::createGLBuffers()
 	assertInitialized();
 
 	updateRenderDeferred();
-	if (LLPipeline::sWaterReflections)
+	if (LLPipeline::sRenderTransparentWater)
 	{ //water reflection texture
 		U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
-		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
         mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
 	}
 
@@ -2427,17 +2422,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
 		stop_glerror();
 	}
 
-	if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && 
-		!gPipeline.canUseWindLightShaders() &&
-		gSky.mVOGroundp.notNull() && 
-		gSky.mVOGroundp->mDrawable.notNull() &&
-		!LLPipeline::sWaterReflections)
-	{
-		gSky.mVOGroundp->mDrawable->setVisible(camera);
-		sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
-	}
-	
-	
     if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) && 
         gPipeline.canUseWindLightShaders() &&
         gSky.mVOWLSkyp.notNull() && 
@@ -9347,350 +9331,6 @@ inline float sgn(float a)
     return (0.0F);
 }
 
-void LLPipeline::generateWaterReflection(LLCamera& camera_in)
-{
-#if 0
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-    LL_PROFILE_GPU_ZONE("generateWaterReflection");
-
-    if (!assertInitialized() || gCubeSnapshot)
-    {
-        return;
-    }
-
-    if (LLPipeline::sWaterReflections && LLDrawPoolWater::sNeedsReflectionUpdate)
-    {
-        //disable occlusion culling for reflection/refraction passes (save setting to restore later)
-        S32 occlude = LLPipeline::sUseOcclusion;
-        LLPipeline::sUseOcclusion = 0;
-
-        bool skip_avatar_update = false;
-        if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
-        {
-            skip_avatar_update = true;
-        }
-
-        LLCamera camera = camera_in;
-        camera.setFar(camera_in.getFar() * 0.75f);
-
-        bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
-
-        LLPipeline::sReflectionRender = true;
-
-        gPipeline.pushRenderTypeMask();
-
-        glh::matrix4f saved_modelview  = get_current_modelview();
-        glh::matrix4f saved_projection = get_current_projection();
-        glh::matrix4f mat;
-
-#if 1 // relies on forward rendering, which is deprecated -- TODO - make a deferred implementation of transparent/reflective water
-        S32 reflection_detail  = RenderReflectionDetail;
-#else
-        S32 reflection_detail = WATER_REFLECT_NONE_WATER_TRANSPARENT;
-#endif
-
-        F32 water_height      = gAgent.getRegion()->getWaterHeight(); 
-        F32 camera_height     = camera_in.getOrigin().mV[VZ];
-        F32 distance_to_water = (water_height < camera_height) ? (camera_height - water_height) : (water_height - camera_height);
-
-        LLVector3 reflection_offset      = LLVector3(0, 0, distance_to_water * 2.0f);
-        LLVector3 camera_look_at         = camera_in.getAtAxis();
-        LLVector3 reflection_look_at     = LLVector3(camera_look_at.mV[VX], camera_look_at.mV[VY], -camera_look_at.mV[VZ]);
-        LLVector3 reflect_origin         = camera_in.getOrigin() - reflection_offset;
-        LLVector3 reflect_interest_point = reflect_origin + (reflection_look_at * 5.0f);
-
-        camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
-
-        //plane params
-        LLPlane plane;
-        LLVector3 pnorm;
-
-        if (camera_is_underwater)
-        {
-            //camera is below water, cull above water
-            pnorm.setVec(0, 0, 1);
-        }
-        else
-        {
-            //camera is above water, cull below water
-            pnorm = LLVector3(0, 0, -1);
-        }
-
-        plane.setVec(LLVector3(0, 0, water_height), pnorm);
-
-        if (!camera_is_underwater)
-        {
-            //generate planar reflection map
-            LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
-
-            gGL.matrixMode(LLRender::MM_MODELVIEW);
-            gGL.pushMatrix();
-
-            mat.set_scale(glh::vec3f(1, 1, -1));
-            mat.set_translate(glh::vec3f(0,0,water_height*2.f));
-            mat = saved_modelview * mat;
-
-
-            mReflectionModelView = mat;
-
-            set_current_modelview(mat);
-            gGL.loadMatrix(mat.m);
-
-            LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
-
-            glh::vec3f    origin(0, 0, 0);
-            glh::matrix4f inv_mat = mat.inverse();
-            inv_mat.mult_matrix_vec(origin);
-
-            camera.setOrigin(origin.v);
-
-            glCullFace(GL_FRONT);
-
-            if (LLDrawPoolWater::sNeedsReflectionUpdate)
-            {
-                gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-                glClearColor(0,0,0,0);
-                mWaterRef.bindTarget();
-
-                gGL.setColorMask(true, true);
-                mWaterRef.clear();
-                gGL.setColorMask(true, false);
-                mWaterRef.getViewport(gGLViewport);
-
-                //initial sky pass (no user clip plane)
-                //mask out everything but the sky
-                gPipeline.pushRenderTypeMask();
-                {
-                    if (reflection_detail >= WATER_REFLECT_MINIMAL)
-                    {
-                        gPipeline.andRenderTypeMask(
-                            LLPipeline::RENDER_TYPE_SKY,
-                            LLPipeline::RENDER_TYPE_WL_SKY,
-                            LLPipeline::RENDER_TYPE_CLOUDS,
-                            LLPipeline::END_RENDER_TYPES);
-                    }
-                    else
-                    {
-                        gPipeline.andRenderTypeMask(
-                            LLPipeline::RENDER_TYPE_SKY,
-                            LLPipeline::RENDER_TYPE_WL_SKY,
-                            LLPipeline::END_RENDER_TYPES);
-                    }
-
-                    updateCull(camera, mSky);
-                    stateSort(camera, mSky);
-                    renderGeom(camera, TRUE);
-                }
-                gPipeline.popRenderTypeMask();
-
-                if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
-                {
-                    gPipeline.pushRenderTypeMask();
-                    {
-                        clearRenderTypeMask(
-                            LLPipeline::RENDER_TYPE_WATER,
-                            LLPipeline::RENDER_TYPE_VOIDWATER,
-                            LLPipeline::RENDER_TYPE_GROUND,
-                            LLPipeline::RENDER_TYPE_SKY,
-                            LLPipeline::RENDER_TYPE_CLOUDS,
-                            LLPipeline::END_RENDER_TYPES);
-
-                        if (reflection_detail > WATER_REFLECT_MINIMAL)
-                        { //mask out selected geometry based on reflection detail
-                            if (reflection_detail < WATER_REFLECT_EVERYTHING)
-                            {
-                                clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
-                                if (reflection_detail < WATER_REFLECT_AVATARS)
-                                {
-                                    clearRenderTypeMask(
-                                        LLPipeline::RENDER_TYPE_AVATAR,
-                                        LLPipeline::RENDER_TYPE_CONTROL_AV,
-                                        END_RENDER_TYPES);
-                                    if (reflection_detail < WATER_REFLECT_STATIC_OBJECTS)
-                                    {
-                                        clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
-                                    }
-                                }
-                            }
-
-                            LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
-                            LLGLDisable cull(GL_CULL_FACE);
-                            updateCull(camera, mReflectedObjects, &plane);
-                            stateSort(camera, mReflectedObjects);
-                            renderGeom(camera);
-                        }
-                    }
-                    gPipeline.popRenderTypeMask();
-                }
-
-                mWaterRef.flush();
-            }
-
-            glCullFace(GL_BACK);
-            gGL.matrixMode(LLRender::MM_MODELVIEW);
-            gGL.popMatrix();
-
-            set_current_modelview(saved_modelview);
-        }
-
-        camera.setOrigin(camera_in.getOrigin());
-        //render distortion map
-        static bool last_update = true;
-        if (last_update)
-        {
-            gPipeline.pushRenderTypeMask();
-
-            camera.setFar(camera_in.getFar());
-            clearRenderTypeMask(
-                LLPipeline::RENDER_TYPE_WATER,
-                LLPipeline::RENDER_TYPE_VOIDWATER,
-                LLPipeline::RENDER_TYPE_GROUND,
-                END_RENDER_TYPES);
-
-            // intentionally inverted so that distortion map contents (objects under the water when we're above it)
-            // will properly include water fog effects
-            LLPipeline::sUnderWaterRender = !camera_is_underwater;
-
-            if (LLPipeline::sUnderWaterRender)
-            {
-                clearRenderTypeMask(
-                    LLPipeline::RENDER_TYPE_GROUND,
-                    LLPipeline::RENDER_TYPE_SKY,
-                    LLPipeline::RENDER_TYPE_CLOUDS,
-                    LLPipeline::RENDER_TYPE_WL_SKY,
-                    END_RENDER_TYPES);
-            }
-            LLViewerCamera::updateFrustumPlanes(camera);
-
-            gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-            if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate)
-            {
-                LLPipeline::sDistortionRender = true;
-
-                LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
-                glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
-
-                // HACK FIX -- pretend underwater camera is the world camera to fix weird visibility artifacts
-                // during distortion render (doesn't break main render because the camera is the same perspective
-                // as world camera and occlusion culling is disabled for this pass)
-                //LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
-                LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
-                mWaterDis.bindTarget();
-                mWaterDis.getViewport(gGLViewport);
-
-                gGL.setColorMask(true, true);
-                mWaterDis.clear();
-                gGL.setColorMask(true, false);
-
-                F32 water_dist = water_height;
-
-                //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;
-
-                if (camera_is_underwater)
-                {
-                    //nudge clip plane below water to avoid visible holes in objects intersecting water surface
-                    water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin;
-                    //camera is below water, clip plane points up
-                    pnorm.setVec(0, 0, -1);
-                }
-                else
-                {
-                    //nudge clip plane above water to avoid visible holes in objects intersecting water surface
-                    water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin;
-                    //camera is above water, clip plane points down
-                    pnorm = LLVector3(0, 0, 1);
-                }
-
-                plane.setVec(LLVector3(0, 0, water_dist), pnorm);
-
-                LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
-
-                gGL.setColorMask(true, true);
-                mWaterDis.clear();
-                gGL.setColorMask(true, false);
-
-#if 0  // DEPRECATED - requires forward rendering, TODO - make a deferred implementation
-                if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
-                {
-                    updateCull(camera, mRefractedObjects, &plane);
-                    stateSort(camera, mRefractedObjects);
-                    renderGeom(camera);
-                }
-#endif
-
-
-                gUIProgram.bind();
-
-                LLWorld::getInstance()->renderPropertyLines();
-
-                gUIProgram.unbind();
-
-                mWaterDis.flush();
-            }
-
-            LLPipeline::sDistortionRender = false;
-
-            gPipeline.popRenderTypeMask();
-        }
-        last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
-
-        gPipeline.popRenderTypeMask();
-
-        LLPipeline::sUnderWaterRender = false;
-        LLPipeline::sReflectionRender = false;
-
-        LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
-        LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
-
-        if (!LLRenderTarget::sUseFBO)
-        {
-            glClear(GL_DEPTH_BUFFER_BIT);
-        }
-        glClearColor(0.f, 0.f, 0.f, 0.f);
-        gViewerWindow->setup3DViewport();
-
-        LLGLState::checkStates();
-
-        if (!skip_avatar_update)
-        {
-            gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
-        }
-
-        LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
-        // restore occlusion culling
-        LLPipeline::sUseOcclusion = occlude;
-    }
-    else
-    {
-        // Initial sky pass is still needed even if water reflection is not rendering
-        bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
-        if (!camera_is_underwater)
-        {
-            gPipeline.pushRenderTypeMask();
-            {
-                gPipeline.andRenderTypeMask(
-                    LLPipeline::RENDER_TYPE_SKY,
-                    LLPipeline::RENDER_TYPE_WL_SKY,
-                    LLPipeline::END_RENDER_TYPES);
-
-                LLCamera camera = camera_in;
-                camera.setFar(camera_in.getFar() * 0.75f);
-
-                updateCull(camera, mSky);
-                stateSort(camera, mSky);
-                renderGeom(camera, TRUE);
-            }
-            gPipeline.popRenderTypeMask();
-        }
-    }
-#endif
-}
-
 glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
 {
 	glh::matrix4f ret;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 2c9b264fe6c..59858cfcfc8 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -309,7 +309,6 @@ class LLPipeline
 	void renderDeferredLighting();
 	void postDeferredGammaCorrect(LLRenderTarget* screen_target);
 
-	void generateWaterReflection(LLCamera& camera);
 	void generateSunShadow(LLCamera& camera);
     LLRenderTarget* getSunShadowTarget(U32 i);
     LLRenderTarget* getSpotShadowTarget(U32 i);
@@ -634,7 +633,6 @@ class LLPipeline
 	static bool				sUseTriStrips;
 	static bool				sUseFarClip;
 	static bool				sShadowRender;
-	static bool				sWaterReflections;
 	static bool				sDynamicLOD;
 	static bool				sPickAvatar;
 	static bool				sReflectionRender;
@@ -1015,7 +1013,6 @@ class LLPipeline
 	static LLVector3 RenderShadowGaussian;
 	static F32 RenderShadowBlurDistFactor;
 	static bool RenderDeferredAtmospheric;
-	static S32 RenderReflectionDetail;
 	static F32 RenderHighlightFadeTime;
 	static LLVector3 RenderShadowClipPlanes;
 	static LLVector3 RenderShadowOrthoClipPlanes;
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 6ff27ad50b5..4a08cc5285b 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -550,57 +550,6 @@
     top_delta="16"
     width="300" />
 
-  <text
-    type="string"
-    length="1"
-    follows="left|top"
-    height="16"
-    layout="topleft"
-    name="ReflectionsText"
-    text_readonly_color="LabelDisabledColor"
-    top_delta="16"
-    left="420"
-    width="128">
-       Water Reflections:
-  </text>
-  <combo_box
-    control_name="RenderReflectionDetail"
-    height="18"
-    layout="topleft"
-    left_delta="170"
-    top_delta="0"
-    name="Reflections"
-    width="150">
-      <combo_box.item
-        label="None; opaque"
-        name="0"
-        value="-2"/>
-      <combo_box.item
-        label="None; transparent"
-        name="0"
-        value="-1"/>
-      <combo_box.item
-        label="Minimal"
-        name="0"
-        value="0"/>
-      <combo_box.item
-        label="Terrain and trees"
-        name="1"
-        value="1"/>
-      <combo_box.item
-        label="All static objects"
-        name="2"
-        value="2"/>
-      <combo_box.item
-        label="All avatars and objects"
-        name="3"
-        value="3"/>
-      <combo_box.item
-        label="Everything"
-        name="4"
-        value="4"/>
-  </combo_box>
-
   <slider
     control_name="WLSkyDetail"
     decimal_digits="0"
-- 
GitLab