From 767fb53aeb1ac92a141586b1c0b5d1e5d327b281 Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Thu, 31 Jan 2019 09:56:37 -0800
Subject: [PATCH] 9996 partial fix (works for non-ALM rendering only)

Use a new edge water shader to allow forcing frag depth to avoid z-fighting at back edge of water edge pieces.

This will not work for ALM because forcing the depth breaks the use of the depth to backproject gbuffer position which breaks lighting calcs.
---
 .../shaders/class1/deferred/waterF.glsl       |  5 -
 .../shaders/class1/environment/waterF.glsl    |  5 +-
 indra/newview/lldrawpoolwater.cpp             | 99 +++++++++++--------
 indra/newview/llviewershadermgr.cpp           | 25 +----
 indra/newview/llviewershadermgr.h             |  1 -
 5 files changed, 63 insertions(+), 72 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index df7b8f3f927..40d4c24d342 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -169,11 +169,6 @@ void main()
 
     vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
 
-#if defined(WATER_EDGE)
-    // force frag depth which doesn't z-fight
-    gl_FragDepth = 0.99999f;    
-#endif
-
     frag_data[0] = vec4(color.rgb, color); // 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/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index 415d0b9db4b..f228deb9387 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -157,9 +157,8 @@ void main()
     color.rgb = scaleSoftClip(color.rgb);
     color.a = spec * sunAngle2;
 
-#if defined(WATER_EDGE)
-    // force frag depth to fix z-fighting at back edge of water edge pieces
-    gl_FragDepth = 0.99999;
+#if WATER_EDGE
+    gl_FragDepth = 0.9999847f;
 #endif
 
     frag_color = color;
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 826aa1cf246..c674d9a5767 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -534,30 +534,6 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
         gGL.getTexUnit(bumpTex2)->bind(tex_b);
     }
 
-    if (mWaterNormp[0])
-    {
-	    if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
-	    {
-		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-	    }
-	    else 
-	    {
-		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
-	    }
-	}
-
-    if (mWaterNormp[1])
-    {
-	    if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
-	    {
-            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-	    }
-	    else 
-	    {
-            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
-	    }
-	}
-
     shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 
     shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getWaterFogColor().mV);
@@ -642,21 +618,42 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
         sNeedsReflectionUpdate = TRUE;			
         sNeedsDistortionUpdate = TRUE;
 
-        for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
-		{
-			LLFace *face = *iter;
-            if (face)
-            {
-                LLVOWater* water = (LLVOWater*) face->getViewerObject();
-			    gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
-                bool edge_patch = water && water->getIsEdgePatch();
-                if (edge_patch == edge)
+        if (edge)
+        {
+            for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
+		    {
+			    LLFace *face = *iter;
+                if (face)
                 {
-                    face->renderIndexed();
+                    LLVOWater* water = (LLVOWater*) face->getViewerObject();
+			        gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+                    bool edge_patch = water && water->getIsEdgePatch();
+                    if (edge_patch)
+                    {
+                        face->renderIndexed();
+                    }
                 }
-            }
-		}
+		    }
+        }
+        else
+        {
+            for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
+		    {
+			    LLFace *face = *iter;
+                if (face)
+                {
+                    LLVOWater* water = (LLVOWater*) face->getViewerObject();
+			        gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+                    bool edge_patch = water && water->getIsEdgePatch();
+                    if (!edge_patch)
+                    {
+                        face->renderIndexed();
+                    }
+                }
+		    }
+        }
     }
 
 	shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@@ -743,12 +740,36 @@ void LLDrawPoolWater::shade()
 	else if (deferred_render)
 	{
 		shader = &gDeferredWaterProgram;
-        //edge_shader = &gDeferredWaterEdgeProgram;
+        edge_shader = nullptr;
 	}
 	else
 	{
 		shader = &gWaterProgram;
-        //edge_shader = &gWaterEdgeProgram;
+        edge_shader = &gWaterEdgeProgram;
+	}
+
+    if (mWaterNormp[0])
+    {
+	    if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+	    {
+		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+	    }
+	    else 
+	    {
+		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
+	    }
+	}
+
+    if (mWaterNormp[1])
+    {
+	    if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+	    {
+            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+	    }
+	    else 
+	    {
+            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
+	    }
 	}
 
     shade2(false, shader, light_diffuse, light_dir, light_exp);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 5bc4c1a6aa0..54c1a602d9b 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -187,7 +187,6 @@ LLGLSLShader			gPostNightVisionProgram;
 // Deferred rendering shaders
 LLGLSLShader			gDeferredImpostorProgram;
 LLGLSLShader			gDeferredWaterProgram;
-LLGLSLShader			gDeferredWaterEdgeProgram;
 LLGLSLShader			gDeferredUnderWaterProgram;
 LLGLSLShader			gDeferredDiffuseProgram;
 LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;
@@ -350,7 +349,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gDeferredEmissiveProgram);
 	mShaderList.push_back(&gDeferredAvatarEyesProgram);
 	mShaderList.push_back(&gDeferredWaterProgram);
-    mShaderList.push_back(&gDeferredWaterEdgeProgram);
 	mShaderList.push_back(&gDeferredUnderWaterProgram);	
 	mShaderList.push_back(&gDeferredAvatarAlphaProgram);
 	mShaderList.push_back(&gDeferredWLSkyProgram);
@@ -1138,7 +1136,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
         gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
         gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
 		gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
-		success = gWaterProgram.createShader(NULL, NULL);
+		success = gWaterEdgeProgram.createShader(NULL, NULL);
         llassert(success);
 	}
 
@@ -1298,7 +1296,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredPostGammaCorrectProgram.unload();
 		gFXAAProgram.unload();
 		gDeferredWaterProgram.unload();
-        gDeferredWaterEdgeProgram.unload();
 		gDeferredUnderWaterProgram.unload();
 		gDeferredWLSkyProgram.unload();
 		gDeferredWLCloudProgram.unload();
@@ -2019,26 +2016,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         llassert(success);
 	}
 
-    if (success)
-	{
-		// load water shader
-		gDeferredWaterEdgeProgram.mName = "Deferred Water Shader";
-		gDeferredWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredWaterEdgeProgram.mFeatures.hasGamma = true;
-		gDeferredWaterEdgeProgram.mFeatures.hasTransport = true;
-        gDeferredWaterEdgeProgram.mFeatures.encodesNormal = true;
-        gDeferredWaterEdgeProgram.mFeatures.hasShadows = true;
-
-		gDeferredWaterEdgeProgram.mShaderFiles.clear();
-		gDeferredWaterEdgeProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredWaterEdgeProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
-        gDeferredWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-        gDeferredWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-        gDeferredWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
-		success = gDeferredWaterEdgeProgram.createShader(NULL, NULL);
-        llassert(success);
-	}
-
 	if (success)
 	{
 		// load water shader
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 05e1681b405..411949f9f3c 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -274,7 +274,6 @@ extern LLGLSLShader			gPostNightVisionProgram;
 // Deferred rendering shaders
 extern LLGLSLShader			gDeferredImpostorProgram;
 extern LLGLSLShader			gDeferredWaterProgram;
-extern LLGLSLShader			gDeferredWaterEdgeProgram;
 extern LLGLSLShader			gDeferredUnderWaterProgram;
 extern LLGLSLShader			gDeferredDiffuseProgram;
 extern LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;
-- 
GitLab