From 9448db5d4af7bba094e5bc51f85e5c2491d3f5a1 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 6 Oct 2022 18:40:01 -0500
Subject: SL-18190 Water shader WIP.  Better parallax correction for sphere
 probes.  Reduce probe memory footprint.  Remove framebuffer copies and move
 to deprecate stencil buffer usage.

---
 indra/llrender/llcubemaparray.cpp                  |  4 +-
 indra/llrender/llglcommonfunc.cpp                  |  5 +-
 indra/llrender/llrendertarget.cpp                  |  6 +-
 indra/llwindow/llwindowwin32.cpp                   |  4 +-
 .../shaders/class1/deferred/deferredUtil.glsl      |  7 ++
 .../shaders/class1/interface/irradianceGenF.glsl   | 12 +--
 .../shaders/class1/interface/radianceGenF.glsl     | 12 +--
 .../shaders/class1/interface/reflectionmipF.glsl   | 26 ++++++-
 .../shaders/class2/environment/waterF.glsl         | 17 ++--
 .../shaders/class3/deferred/reflectionProbeF.glsl  | 66 ++++++++++++----
 indra/newview/lldrawpool.cpp                       |  2 +-
 indra/newview/lldrawpoolalpha.cpp                  |  6 +-
 indra/newview/lldrawpoolbump.cpp                   |  4 +-
 indra/newview/lldrawpoolmaterials.cpp              |  2 +-
 indra/newview/lldrawpoolwater.cpp                  |  2 +-
 indra/newview/llface.cpp                           |  2 +-
 indra/newview/llhudeffectlookat.cpp                |  2 +-
 indra/newview/llhudeffectpointat.cpp               |  2 +-
 indra/newview/llhudicon.cpp                        |  2 +-
 indra/newview/llhudnametag.cpp                     |  2 +-
 indra/newview/llhudtext.cpp                        |  2 +-
 indra/newview/llmaniprotate.cpp                    |  2 +-
 indra/newview/llmanipscale.cpp                     |  2 +-
 indra/newview/llmaniptranslate.cpp                 | 22 +++---
 indra/newview/llreflectionmapmanager.cpp           | 37 ++++++---
 indra/newview/llviewerdisplay.cpp                  | 12 +--
 indra/newview/llviewershadermgr.cpp                |  1 +
 indra/newview/llviewerwindow.cpp                   | 12 +--
 indra/newview/llvoicevisualizer.cpp                |  2 +-
 indra/newview/pipeline.cpp                         | 90 ++++++++++++++--------
 .../skins/default/xui/en/floater_build_options.xml |  4 +-
 31 files changed, 240 insertions(+), 131 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index abb93093e0..a21f7d084e 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -122,7 +122,9 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL us
 
     bind(0);
 
-    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGB16F, resolution, resolution, count*6, 0,
+    U32 format = components == 4 ? GL_RGBA12 : GL_RGB10;
+    
+    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, format, resolution, resolution, count*6, 0,
         GL_RGB, GL_UNSIGNED_BYTE, nullptr);
 
     mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
index e9ec28927f..04d29b9430 100644
--- a/indra/llrender/llglcommonfunc.cpp
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -31,7 +31,8 @@ namespace LLGLCommonFunc
 {
 	void selected_stencil_test()
 	{
-		glStencilFunc(GL_ALWAYS, 2, 0xffff);
-		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+        // deprecated
+		//glStencilFunc(GL_ALWAYS, 2, 0xffff);
+		//glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
 	}
 }
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 7fcb130ac6..01ccf3d314 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -150,6 +150,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
 		if (mDepth)
 		{
 			glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+            llassert(!mStencil); // use of stencil buffer is deprecated (performance penalty)
 			if (mStencil)
 			{
 				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
@@ -370,6 +371,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
 		glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
 		stop_glerror();
 
+        llassert(!mStencil); // deprecated -- performance penalty
 		if (mStencil)
 		{
 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
@@ -417,6 +419,7 @@ void LLRenderTarget::release()
 
 		if (mUseDepth)
 		{ //detach shared depth buffer
+            llassert(!mStencil); //deprecated, performance penalty
 			if (mStencil)
 			{ //attached as a renderbuffer
 				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
@@ -515,7 +518,8 @@ void LLRenderTarget::clear(U32 mask_in)
 	U32 mask = GL_COLOR_BUFFER_BIT;
 	if (mUseDepth)
 	{
-		mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
+        mask |= GL_DEPTH_BUFFER_BIT; // stencil buffer is deprecated, performance pnealty | GL_STENCIL_BUFFER_BIT;
+        
 	}
 	if (mFBO)
 	{
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 553507bc0c..aadf895271 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -1376,8 +1376,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO
 		attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB;
 		attrib_list[cur_attrib++] = 24;
 
-		attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB;
-		attrib_list[cur_attrib++] = 8;
+		//attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB; //stencil buffer is deprecated (performance penalty)
+		//attrib_list[cur_attrib++] = 8;
 
 		attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB;
 		attrib_list[cur_attrib++] = GL_TRUE;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 1c2034de69..2ec859fdae 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -179,6 +179,13 @@ vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensi
     return packedNormalEnvIntensityFlags;
 }
 
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar)
+{
+    d = d * 2.0 - 1.0;
+    return znear * 2.0 * zfar / (zfar + znear - d * (zfar - znear));
+}
+
 float getDepth(vec2 pos_screen)
 {
     float depth = texture2DRect(depthMap, pos_screen).r;
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
index 63e2fce40f..b633813819 100644
--- a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
@@ -177,10 +177,10 @@ float computeLod(float pdf)
     return lod;
 }
 
-vec3 filterColor(vec3 N)
+vec4 filterColor(vec3 N)
 {
     //return  textureLod(uCubeMap, N, 3.0).rgb;
-    vec3 color = vec3(0.f);
+    vec4 color = vec4(0.f);
     float weight = 0.0f;
 
     for(int i = 0; i < u_sampleCount; ++i)
@@ -198,7 +198,7 @@ vec3 filterColor(vec3 N)
 
         lod = clamp(lod, 0, 7);
         // sample lambertian at a lower resolution to avoid fireflies
-        vec3 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod).rgb;
+        vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod);
 
         color += lambertian;
     }
@@ -212,16 +212,16 @@ vec3 filterColor(vec3 N)
         color /= float(u_sampleCount);
     }
 
-    return color.rgb ;
+    return color;
 }
 
 // entry point
 void main()
 {
-    vec3 color = vec3(0);
+    vec4 color = vec4(0);
 
     color = filterColor(vary_dir);
     
-    frag_color = vec4(color,1.0);
+    frag_color = color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
index bb4a79247d..f4879b52de 100644
--- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -26,11 +26,7 @@
 
 /*[EXTRA_CODE_HERE]*/
 
-#ifdef DEFINE_GL_FRAGCOLOR
 out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
 
 uniform samplerCubeArray   reflectionProbes;
 uniform int sourceIdx;
@@ -122,11 +118,11 @@ float D_GGX(float dotNH, float roughness)
 	return (alpha2)/(PI * denom*denom); 
 }
 
-vec3 prefilterEnvMap(vec3 R)
+vec4 prefilterEnvMap(vec3 R)
 {
 	vec3 N = R;
 	vec3 V = R;
-	vec3 color = vec3(0.0);
+	vec4 color = vec4(0.0);
 	float totalWeight = 0.0;
 	float envMapDim = 256.0;
     int numSamples = 4;
@@ -157,7 +153,7 @@ vec3 prefilterEnvMap(vec3 R)
 			// Biased (+1.0) mip level for better result
 			float mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
             //float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
-			color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip).rgb * dotNL;
+			color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip) * dotNL;
 			totalWeight += dotNL;
 
 		}
@@ -168,6 +164,6 @@ vec3 prefilterEnvMap(vec3 R)
 void main()
 {		
 	vec3 N = normalize(vary_dir);
-	frag_color = vec4(prefilterEnvMap(N), 1.0);
+	frag_color = prefilterEnvMap(N);
 }
 // =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
index e8452a9c14..9dd97a80b2 100644
--- a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
@@ -33,10 +33,20 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
-uniform sampler2DRect screenMap;
+// NOTE screenMap should always be texture channel 0 and 
+// depthmap should always be channel 1
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect depthMap;
+
+uniform float resScale;
+uniform float znear;
+uniform float zfar;
 
 VARYING vec2 vary_texcoord0;
 
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar);
+
 void main() 
 {
 #if 0
@@ -74,6 +84,18 @@ void main()
 
     frag_color = vec4(color, 1.0);
 #else
-    frag_color = vec4(texture2DRect(screenMap, vary_texcoord0.xy).rgb, 1.0);
+    vec2 depth_tc = vary_texcoord0.xy * resScale;
+    float depth = texture(depthMap, depth_tc).r;
+    float dist = linearDepth(depth, znear, zfar);
+
+    // convert linear depth to distance
+    vec3 v;
+    v.xy = depth_tc / 512.0 * 2.0 - 1.0;
+    v.z = 1.0;
+    v = normalize(v);
+    dist /= v.z;
+
+    vec3 col = texture2DRect(diffuseRect, vary_texcoord0.xy).rgb;
+    frag_color = vec4(col, dist/256.0); 
 #endif
 }
diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
index 59e7e64fbb..b51583de26 100644
--- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
@@ -163,7 +163,7 @@ void main()
 	
     float df1 = df.x + df.y + df.z;
 
-    wavef = normalize(wavef + vary_normal);
+    //wavef = normalize(wavef - vary_normal);
     //wavef = vary_normal;
 
     vec3 waver = reflect(viewVec, -wavef)*3;
@@ -194,13 +194,13 @@ void main()
     vec3 additive;
     vec3 atten;
 
-    calcAtmosphericVarsLinear(pos.xyz, wavef, lightDir, sunlit, amblit, additive, atten);
-    
+    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+    sunlit = vec3(1); // TODO -- figure out why sunlit is breaking at some view angles
     vec3 v = -viewVec;
     float NdotV = clamp(abs(dot(wavef.xyz, v)), 0.001, 1.0);
 
     float metallic = fresnelOffset * 0.1; // fudge -- use fresnelOffset as metalness
-    float roughness = 0.08;
+    float roughness = 0.1;
     float gloss = 1.0 - roughness;
 
     vec3 baseColor = vec3(0.25);
@@ -210,8 +210,8 @@ void main()
 
     vec3 specularColor = mix(f0, baseColor.rgb, metallic);
 
-    //vec3 refnorm = normalize(wavef + vary_normal);
-    vec3 refnorm = wavef;
+    vec3 refnorm = normalize(wavef + vary_normal);
+    //vec3 refnorm = wavef;
     
    
     vec3 irradiance = vec3(0);
@@ -221,7 +221,6 @@ void main()
     irradiance = fb.rgb;
 
     color.rgb = pbrIbl(diffuseColor, specularColor, radiance, irradiance, gloss, NdotV, 0.0);
-
     
     // fudge -- for punctual lighting, pretend water is metallic
     diffuseColor = vec3(0);
@@ -229,7 +228,7 @@ void main()
     roughness = 0.1;
     float scol = 1.0; // TODO -- incorporate shadow map
 
-    //color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
+    color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
 	color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
 	color.rgb = scaleSoftClipFragLinear(color.rgb);
 
@@ -239,6 +238,8 @@ void main()
     //color.rgb = srgb_to_linear(normalize(refPos) * 0.5 + 0.5);
     //color.rgb = srgb_to_linear(normalize(pos) * 0.5 + 0.5);
     //color.rgb = srgb_to_linear(wavef * 0.5 + 0.5);
+
+    //color.rgb = radiance;
 	frag_color = color;
 
 #if defined(WATER_EDGE)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 80f9e29123..ec9218f00e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -239,7 +239,7 @@ bool intersect(const Ray &ray) const
         return true; 
 } */
 
-// adapted -- assume that origin is inside sphere, return distance from origin to edge of sphere
+// adapted -- assume that origin is inside sphere, return intersection of ray with edge of sphere
 vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2)
 { 
         float t0, t1; // solutions for t if the ray intersects 
@@ -310,17 +310,19 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i)
 // Tap a reflection probe
 // pos - position of pixel
 // dir - pixel normal
+// vi - return value of intersection point with influence volume
+// wi - return value of approximate world space position of sampled pixel
 // lod - which mip to bias towards (lower is higher res, sharper reflections)
 // c - center of probe
 // r2 - radius of probe squared
 // i - index of probe 
-// vi - point at which reflection vector struck the influence volume, in clip space
-vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
+vec3 tapRefMap(vec3 pos, vec3 dir, out vec3 vi, out vec3 wi, float lod, vec3 c, float r2, int i)
 {
     //lod = max(lod, 1);
     // parallax adjustment
 
     vec3 v;
+
     if (refIndex[i].w < 0)
     {
         v = boxIntersect(pos, dir, i);
@@ -330,11 +332,18 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
         v = sphereIntersect(pos, dir, c, r2);
     }
 
+    vi = v;
+
     v -= c;
+    vec3 d = normalize(v);
+
     v = env_mat * v;
-    {
-        return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod).rgb;
-    }
+    
+    vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod);
+
+    wi = d * ret.a * 256.0+c;
+
+    return ret.rgb;
 }
 
 // Tap an irradiance map
@@ -343,7 +352,6 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
 // c - center of probe
 // r2 - radius of probe squared
 // i - index of probe 
-// vi - point at which reflection vector struck the influence volume, in clip space
 vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i)
 {
     //lod = max(lod, 1);
@@ -383,26 +391,48 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
         float p = float(abs(refIndex[i].w)); // priority
         
         float rr = r*r; // radius squred
-        float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
+        float r1 = r * 0.1; // 90% of radius (outer sphere to start interpolating down)
         vec3 delta = pos.xyz-refSphere[i].xyz;
         float d2 = dot(delta,delta);
         float r2 = r1*r1; 
         
         {
-            vec3 refcol = tapRefMap(pos, dir, lod, refSphere[i].xyz, rr, i);
-            
-            float w = 1.0/d2;
+            vec3 vi, wi;
+
+            vec3 refcol = tapRefMap(pos, dir, vi, wi, lod, refSphere[i].xyz, rr, i);
 
             float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);
+
+            if (refIndex[i].w >= 0)
+            {
+                //adjust lookup by distance result
+                float d = length(vi - wi);
+                vi += dir * d;
+
+                vi -= refSphere[i].xyz;
+
+                vi = env_mat * vi;
+
+                refcol = textureLod(reflectionProbes, vec4(vi, refIndex[i].x), lod).rgb;
+            }
+
+            //float w = 1.0 / max(d3, 1.0);
+            vec3 pi = normalize(wi - pos);
+            float w = max(dot(pi, dir), 0.1);
+            w = pow(w, 32.0);
+            
             w *= atten;
+
+
             //w *= p; // boost weight based on priority
-            col += refcol*w;
-            
+            col += refcol.rgb*w;
+
             wsum += w;
         }
     }
 
-    if (probeInfluences <= 1)
+#if 1
+    if (probeInfluences < 1)
     { //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera 
         for (int idx = 0; idx < 8; ++idx)
         {
@@ -415,15 +445,17 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
             float d2 = dot(delta,delta);
             
             {
-                vec3 refcol = tapRefMap(pos, dir, lod, refSphere[i].xyz, d2, i);
-                
+                vec3 vi, wi;
+                vec3 refcol = tapRefMap(pos, dir, vi, wi, lod, refSphere[i].xyz, d2, i);
+
                 float w = 1.0/d2;
                 w *= w;
-                col += refcol*w;
+                col += refcol.rgb*w;
                 wsum += w;
             }
         }
     }
+#endif
 
     if (wsum > 0.0)
     {
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 074d223b59..015e520179 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -570,7 +570,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
 
     LLGLDisable cull(params.mGLTFMaterial && params.mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
 
-    LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+    //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
 
     params.mVertexBuffer->setBufferFast(mask);
     params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index a985807a38..fb2a4d78fc 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -167,10 +167,10 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
     if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot)
     { 
         //update depth buffer sampler
-        gPipeline.mRT->screen.flush();
+        /*gPipeline.mRT->screen.flush();
         gPipeline.mRT->deferredDepth.copyContents(gPipeline.mRT->deferredScreen, 0, 0, gPipeline.mRT->deferredScreen.getWidth(), gPipeline.mRT->deferredScreen.getHeight(),
             0, 0, gPipeline.mRT->deferredDepth.getWidth(), gPipeline.mRT->deferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
-        gPipeline.mRT->deferredDepth.bindTarget();
+        gPipeline.mRT->deferredDepth.bindTarget();*/
         simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
 
         simple_shader->bind();
@@ -798,7 +798,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
                 bool tex_setup = TexSetup(&params, (mat != nullptr));
 
 				{
-					LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+					//LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
 
 					gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
 
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 235672b07a..75917d0ae3 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -1467,11 +1467,11 @@ void LLDrawPoolInvisible::render(S32 pass)
 	}
 
 	U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
-	glStencilMask(0);
+	//glStencilMask(0); //deprecated
 	gGL.setColorMask(false, false);
 	pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
 	gGL.setColorMask(true, false);
-	glStencilMask(0xFFFFFFFF);
+	//glStencilMask(0xFFFFFFFF); //deprecated
 
 	if (gPipeline.shadersLoaded())
 	{
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 2b05f4c453..d97f0714ef 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -260,7 +260,7 @@ void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool
             (GLfloat*)&(mpc.mGLMp[0]));
     }
 
-	LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+	//LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
 
 	params.mVertexBuffer->setBufferFast(mask);
 	params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 0b9bca06db..fc8df01002 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -255,7 +255,7 @@ void LLDrawPoolWater::render(S32 pass)
 	
 	glClearStencil(1);
 	glClear(GL_STENCIL_BUFFER_BIT);
-	LLGLEnable gls_stencil(GL_STENCIL_TEST);
+	//LLGLEnable gls_stencil(GL_STENCIL_TEST);
 	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
 	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
 
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index b24bc69791..431a9ebb29 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -666,7 +666,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
 
     {
         LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
-        LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+        //LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
 
         if (!wireframe_selection)
         { //modify wireframe into outline selection mode
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 6898dce7b1..0f230067bc 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -495,7 +495,7 @@ void LLHUDEffectLookAt::render()
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+		//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 
 		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index ecf6d42d69..dfa299528a 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -322,7 +322,7 @@ void LLHUDEffectPointAt::render()
 	update();
 	if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
 	{
-		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+		//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 60294f6a51..38be2b69fd 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -79,7 +79,7 @@ void LLHUDIcon::render()
 {
 	LLGLSUIDefault texture_state;
 	LLGLDepthTest gls_depth(GL_TRUE);
-	LLGLDisable gls_stencil(GL_STENCIL_TEST);
+	//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 	
 	if (mHidden)
 		return;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 952fbf8e4b..e2d63ecc0a 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -228,7 +228,7 @@ void LLHUDNameTag::render()
 	if (sDisplayText)
 	{
 		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+		//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		renderText(FALSE);
 	}
 }
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 5952edfc44..7511dabd5b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -102,7 +102,7 @@ void LLHUDText::render()
 	if (!mOnHUDAttachment && sDisplayText)
 	{
 		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+		//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		renderText();
 	}
 }
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d85a846f4d..6b9543d433 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -277,7 +277,7 @@ void LLManipRotate::render()
 			LLGLEnable cull_face(GL_CULL_FACE);
 			LLGLEnable clip_plane0(GL_CLIP_PLANE0);
 			LLGLDepthTest gls_depth(GL_FALSE);
-			LLGLDisable gls_stencil(GL_STENCIL_TEST);
+			//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 
 			// First pass: centers. Second pass: sides.
 			for( S32 i=0; i<2; i++ )
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index e74fd1241b..c15f1da26b 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -757,7 +757,7 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
 {
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_FALSE);
-	LLGLDisable gls_stencil(GL_STENCIL_TEST);
+	//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 
 	gGL.pushMatrix();
 	{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 0b2a1ef389..b9e68bd6a9 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1063,7 +1063,7 @@ void LLManipTranslate::render()
 		renderGuidelines();
 	}
 	{
-		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+		//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		renderTranslationHandles();
 		renderSnapGuides();
 	}
@@ -1529,7 +1529,7 @@ void LLManipTranslate::renderSnapGuides()
 			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 
 			{
-				LLGLDisable stencil(GL_STENCIL_TEST);
+				//LLGLDisable stencil(GL_STENCIL_TEST);
 				{
 					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
 					gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
@@ -1628,6 +1628,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 											 LLQuaternion grid_rotation, 
 											 LLColor4 inner_color)
 {
+#if 0 // DEPRECATED
 	if (!gSavedSettings.getBOOL("GridCrossSections"))
 	{
 		return;
@@ -1651,13 +1652,13 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 	}
 		
 	{
-		glStencilMask(stencil_mask);
-		glClearStencil(1);
-		glClear(GL_STENCIL_BUFFER_BIT);
+		//glStencilMask(stencil_mask); //deprecated
+		//glClearStencil(1);
+		//glClear(GL_STENCIL_BUFFER_BIT);
 		LLGLEnable cull_face(GL_CULL_FACE);
-		LLGLEnable stencil(GL_STENCIL_TEST);
+		//LLGLEnable stencil(GL_STENCIL_TEST);
 		LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
-		glStencilFunc(GL_ALWAYS, 0, stencil_mask);
+		//glStencilFunc(GL_ALWAYS, 0, stencil_mask);
 		gGL.setColorMask(false, false);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
@@ -1690,14 +1691,14 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 		}
 		
 		//stencil in volumes
-		glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+		//glStencilOp(GL_INCR, GL_INCR, GL_INCR);
 		glCullFace(GL_FRONT);
 		for (U32 i = 0; i < num_types; i++)
 		{
 			gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
 		}
 
-		glStencilOp(GL_DECR, GL_DECR, GL_DECR);
+		//glStencilOp(GL_DECR, GL_DECR, GL_DECR);
 		glCullFace(GL_BACK);
 		for (U32 i = 0; i < num_types; i++)
 		{
@@ -1741,7 +1742,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLDepthTest depth(GL_FALSE);
-		LLGLEnable stencil(GL_STENCIL_TEST);
+		//LLGLEnable stencil(GL_STENCIL_TEST);
 		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 		glStencilFunc(GL_EQUAL, 0, stencil_mask);
 		renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
@@ -1752,6 +1753,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
 
 	gGL.popMatrix();
+#endif
 }
 
 void LLManipTranslate::renderText()
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index cbefb93ca9..8f1ee8f70b 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -83,7 +83,7 @@ void LLReflectionMapManager::update()
     {
         U32 color_fmt = GL_RGB16F;
         const bool use_depth_buffer = true;
-        const bool use_stencil_buffer = true;
+        const bool use_stencil_buffer = false;
         U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample
         mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE);
     }
@@ -96,7 +96,7 @@ void LLReflectionMapManager::update()
         mMipChain.resize(count);
         for (int i = 0; i < count; ++i)
         {
-            mMipChain[i].allocate(res, res, GL_RGB16F, false, false, LLTexUnit::TT_RECT_TEXTURE);
+            mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_RECT_TEXTURE);
             res /= 2;
         }
     }
@@ -385,12 +385,10 @@ void LLReflectionMapManager::doProbeUpdate()
 
 void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
 {
-    mRenderTarget.bindTarget();
     // hacky hot-swap of camera specific render targets
     gPipeline.mRT = &gPipeline.mAuxillaryRT;
     probe->update(mRenderTarget.getWidth(), face);
     gPipeline.mRT = &gPipeline.mMainRT;
-    mRenderTarget.flush();
 
     S32 targetIdx = mReflectionProbeCount;
 
@@ -399,12 +397,15 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
         targetIdx += 1;
     }
 
+    gGL.setColorMask(true, true);
+
     // downsample to placeholder map
     {
         LLGLDepthTest depth(GL_FALSE, GL_FALSE);
         LLGLDisable cull(GL_CULL_FACE);
 
         gReflectionMipProgram.bind();
+
         gGL.matrixMode(gGL.MM_MODELVIEW);
         gGL.pushMatrix();
         gGL.loadIdentity();
@@ -418,6 +419,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
 
         S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
 
+        S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
+        S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
+
+        LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
+        LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
+
         for (int i = 0; i < mMipChain.size(); ++i)
         {
             LL_PROFILE_GPU_ZONE("probe mip");
@@ -425,13 +432,24 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
 
             if (i == 0)
             {
-                gGL.getTexUnit(0)->bind(&mRenderTarget);
+                
+                gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
             }
             else
             {
-                gGL.getTexUnit(0)->bind(&(mMipChain[i - 1]));
+                gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
             }
 
+            gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
+
+            static LLStaticHashedString resScale("resScale");
+            static LLStaticHashedString znear("znear");
+            static LLStaticHashedString zfar("zfar");
+            
+            gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i));
+            gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
+            gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
+
             gGL.begin(gGL.QUADS);
 
             gGL.texCoord2f(0, 0);
@@ -471,6 +489,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
         gGL.matrixMode(gGL.MM_MODELVIEW);
         gGL.popMatrix();
 
+        gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE);
+        gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE);
         gReflectionMipProgram.unbind();
     }
 
@@ -851,10 +871,10 @@ void LLReflectionMapManager::initReflectionMaps()
         mTexture = new LLCubeMapArray();
 
         // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
-        mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, mReflectionProbeCount + 2);
+        mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 4, mReflectionProbeCount + 2);
 
         mIrradianceMaps = new LLCubeMapArray();
-        mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE);
+        mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE);
     }
 
     if (mVertexBuffer.isNull())
@@ -875,6 +895,5 @@ void LLReflectionMapManager::initReflectionMaps()
         buff->flush();
 
         mVertexBuffer = buff;
-
     }
 }
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 118dbb833e..0d2a44867e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -161,7 +161,7 @@ void display_startup()
 	LLGLState::checkStates();
 	LLGLState::checkTextureChannels();
 
-	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
 	LLGLSUIDefault gls_ui;
 	gPipeline.disableLights();
 
@@ -763,7 +763,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				LLGLState::checkTextureChannels();
 
 			}
-			glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+            glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
 		}
 
 		LLGLState::checkStates();
@@ -998,12 +998,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
         LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
         rt.flush();
 
-        if (rt.sUseFBO)
+        /*if (rt.sUseFBO)
         {
             LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
                                                       rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
                                                       GL_NEAREST);
-        }
+        }*/
 
         if (LLPipeline::sRenderDeferred)
         {
@@ -1106,7 +1106,7 @@ void display_cube_face()
     glClearColor(0, 0, 0, 0);
     gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
         
-    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
 
     {
         LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
@@ -1151,7 +1151,7 @@ void display_cube_face()
     LLPipeline::sUnderWaterRender = FALSE;
 
     // Finalize scene
-    gPipeline.renderFinalize();
+    //gPipeline.renderFinalize();
 
     LLSpatialGroup::sNoDelete = FALSE;
     gPipeline.clearReferences();
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 46abd83449..05978e1144 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -3807,6 +3807,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
     if (success)
     {
         gReflectionMipProgram.mName = "Reflection Mip Shader";
+        gReflectionMipProgram.mFeatures.isDeferred = true;
         gReflectionMipProgram.mShaderFiles.clear();
         gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
         gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index b2728b294e..8ef65b665d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4845,7 +4845,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	// PRE SNAPSHOT
 	gDisplaySwapBuffers = FALSE;
 	
-	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
 	setCursor(UI_CURSOR_WAIT);
 
 	// Hide all the UI widgets first and draw a frame
@@ -5144,7 +5144,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
     LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
     gDisplaySwapBuffers = FALSE;
 
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
     setCursor(UI_CURSOR_WAIT);
 
     BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
@@ -5248,10 +5248,10 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
     llassert(LLPipeline::sRenderDeferred);
     llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress
     
-    U32 res = LLRenderTarget::sCurResX;
+    U32 res = gPipeline.mRT->deferredScreen.getWidth();
 
-    llassert(res <= gPipeline.mRT->deferredScreen.getWidth());
-    llassert(res <= gPipeline.mRT->deferredScreen.getHeight());
+    //llassert(res <= gPipeline.mRT->deferredScreen.getWidth());
+    //llassert(res <= gPipeline.mRT->deferredScreen.getHeight());
 
     // save current view/camera settings so we can restore them afterwards
     S32 old_occlusion = LLPipeline::sUseOcclusion;
@@ -5271,7 +5271,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
     camera->setOrigin(origin);
     camera->setNear(near_clip);
 
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
     
     U32 dynamic_render_types[] = {
         LLPipeline::RENDER_TYPE_AVATAR,
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 6e08a2ff12..34e561174c 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -356,7 +356,7 @@ void LLVoiceVisualizer::render()
 		//---------------------------------------------------------------
 		LLGLSPipelineAlpha alpha_blend;
 		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+		//LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		
 		//-------------------------------------------------------------
 		// create coordinates of the geometry for the dot
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 08c99266f8..7eaa3a065c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -885,14 +885,17 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 		const U32 occlusion_divisor = 3;
 
 		//allocate deferred rendering color buffers
-		if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
-		if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+		if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+		//if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 		if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 		if (!addDeferredAttachments(mRT->deferredScreen)) return false;
 	
 		GLuint screenFormat = GL_RGBA16;
         
 		if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+        mRT->deferredScreen.shareDepthBuffer(mRT->screen);
+
 		if (samples > 0)
 		{
 			if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
@@ -929,17 +932,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 		mRT->fxaaBuffer.release();
 		mRT->screen.release();
 		mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first
-		mRT->deferredDepth.release();
+		//mRT->deferredDepth.release();
 		mRT->occlusionDepth.release();
 						
 		if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		
 	}
 	
-	if (LLPipeline::sRenderDeferred)
-	{ //share depth buffer between deferred targets
-		mRT->deferredScreen.shareDepthBuffer(mRT->screen);
-	}
-
 	gGL.getTexUnit(0)->disable();
 
 	stop_glerror();
@@ -2575,6 +2573,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
 	if (scratch_space)
 	{
         GLint bits = 0;
+        llassert(!source.hasStencil()); // stencil buffer usage is deprecated
         bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
         bits |= GL_DEPTH_BUFFER_BIT;
 		scratch_space->copyContents(source, 
@@ -2632,10 +2631,17 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
     llassert(!gCubeSnapshot);
+#if 0
 	downsampleDepthBuffer(source, dest, scratch_space);
 	dest.bindTarget();
 	doOcclusion(camera);
 	dest.flush();
+#else
+    // none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries
+    //source.bindTarget();
+    doOcclusion(camera);
+    //source.flush();
+#endif
 }
 
 void LLPipeline::doOcclusion(LLCamera& camera)
@@ -4052,10 +4058,10 @@ void render_hud_elements()
 	LLGLDisable fog(GL_FOG);
 	LLGLSUIDefault gls_ui;
 
-	LLGLEnable stencil(GL_STENCIL_TEST);
-	glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
-	glStencilMask(0xFFFFFFFF);
-	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+	//LLGLEnable stencil(GL_STENCIL_TEST);
+	//glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
+	//glStencilMask(0xFFFFFFFF);
+	//glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
 	
 	gGL.color4f(1,1,1,1);
 	
@@ -4112,14 +4118,15 @@ void LLPipeline::renderHighlights()
 		LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
 		LLGLDisable test(GL_ALPHA_TEST);
 
-		LLGLEnable stencil(GL_STENCIL_TEST);
+		//LLGLEnable stencil(GL_STENCIL_TEST);
 		gGL.flush();
-		glStencilMask(0xFFFFFFFF);
-		glClearStencil(1);
-		glClear(GL_STENCIL_BUFFER_BIT);
+        // stencil ops are deprecated
+		//glStencilMask(0xFFFFFFFF);
+		//glClearStencil(1);
+		//glClear(GL_STENCIL_BUFFER_BIT);
 
-		glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
-		glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+		//glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
+		//glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
 
 		gGL.setColorMask(false, false);
 
@@ -4131,8 +4138,8 @@ void LLPipeline::renderHighlights()
 		}
 		gGL.setColorMask(true, false);
 
-		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
+		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // deprecated
+		//glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
 		
 		//gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 
@@ -4711,7 +4718,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 			gGLLastMatrix = NULL;
 			gGL.loadMatrix(gGLModelView);
 			LLGLSLShader::bindNoShader();
-			doOcclusion(camera, mRT->screen, mRT->occlusionDepth, &mRT->deferredDepth);
+			//doOcclusion(camera, mRT->screen, mRT->occlusionDepth, &mRT->deferredDepth);
+            doOcclusion(camera, mRT->screen, mRT->occlusionDepth);
 			gGL.setColorMask(true, false);
 		}
 
@@ -4990,7 +4998,7 @@ void LLPipeline::renderDebug()
 						const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
 						gGL.setColorMask(true, true);
 						glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
-						glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);					
+                        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT);
 						gGL.setColorMask(true, false);
 						glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );	
 					}
@@ -8063,6 +8071,7 @@ void LLPipeline::renderFinalize()
             shader->unbind();
         }
     }
+#if 0 // DEPRECATED
     else // not deferred
     {
         U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
@@ -8105,7 +8114,7 @@ void LLPipeline::renderFinalize()
 
         gGlowCombineProgram.unbind();
     }
-
+#endif
     gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
     if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
@@ -8139,12 +8148,12 @@ void LLPipeline::renderFinalize()
         gSplatTextureRectProgram.unbind();
     }
 
-    if (LLRenderTarget::sUseFBO && !gCubeSnapshot)
+    /*if (LLRenderTarget::sUseFBO && !gCubeSnapshot)
     { // copy depth buffer from mRT->screen to framebuffer
         LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0,
                                                   mRT->screen.getWidth(), mRT->screen.getHeight(),
                                                   GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-    }
+    }*/
 
     gGL.matrixMode(LLRender::MM_PROJECTION);
     gGL.popMatrix();
@@ -8162,7 +8171,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
     LL_PROFILE_GPU_ZONE("bindDeferredShader");
     LLRenderTarget* deferred_target       = &mRT->deferredScreen;
-    LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
+    //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
     LLRenderTarget* deferred_light_target = &mRT->deferredLight;
 
 	shader.bind();
@@ -8198,12 +8207,21 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
     }
 
 
+#if 0
     channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
 	if (channel > -1)
 	{
         gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
 		stop_glerror();
     }
+#else
+    channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
+    if (channel > -1)
+    {
+        gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+        stop_glerror();
+    }
+#endif
 		
     glh::matrix4f projection = get_current_projection();
 		glh::matrix4f inv_proj = projection.inverse();
@@ -8452,13 +8470,15 @@ void LLPipeline::renderDeferredLighting()
     }
 
     LLRenderTarget *screen_target         = &mRT->screen;
-    LLRenderTarget *deferred_target       = &mRT->deferredScreen;
-    LLRenderTarget *deferred_depth_target = &mRT->deferredDepth;
-    LLRenderTarget *deferred_light_target = &mRT->deferredLight;
+    //LLRenderTarget *deferred_target       = &mRT->deferredScreen;
+    //LLRenderTarget *deferred_depth_target = &mRT->deferredDepth;
+    LLRenderTarget* deferred_light_target = &mRT->deferredLight;
 
     {
         LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
         LLViewerCamera *camera = LLViewerCamera::getInstance();
+        
+#if 0
         {
             LLGLDepthTest depth(GL_TRUE);
             deferred_depth_target->copyContents(*deferred_target,
@@ -8473,6 +8493,7 @@ void LLPipeline::renderDeferredLighting()
                                                 GL_DEPTH_BUFFER_BIT,
                                                 GL_NEAREST);
         }
+#endif
 
         LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
 
@@ -8482,7 +8503,7 @@ void LLPipeline::renderDeferredLighting()
         }
 
         // ati doesn't seem to love actually using the stencil buffer on FBO's
-        LLGLDisable stencil(GL_STENCIL_TEST);
+        //LLGLDisable stencil(GL_STENCIL_TEST);
         // glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
         // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 
@@ -8707,7 +8728,7 @@ void LLPipeline::renderDeferredLighting()
 #if 0
         {  // render non-deferred geometry (fullbright, alpha, etc)
             LLGLDisable blend(GL_BLEND);
-            LLGLDisable stencil(GL_STENCIL_TEST);
+            //LLGLDisable stencil(GL_STENCIL_TEST);
             gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
             gPipeline.pushRenderTypeMask();
@@ -8986,7 +9007,7 @@ void LLPipeline::renderDeferredLighting()
 
     {  // render non-deferred geometry (alpha, fullbright, glow)
         LLGLDisable blend(GL_BLEND);
-        LLGLDisable stencil(GL_STENCIL_TEST);
+        //LLGLDisable stencil(GL_STENCIL_TEST);
 
         pushRenderTypeMask();
         andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
@@ -9234,7 +9255,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
 {
     LLRenderTarget* deferred_target       = &mRT->deferredScreen;
-    LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
+    //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
     LLRenderTarget* deferred_light_target = &mRT->deferredLight;
 
 	stop_glerror();
@@ -9243,7 +9264,8 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
     shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
     shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
     shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT);
-    shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+    //shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+    shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
     shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
 	shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
 	shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
index 38428b36fc..7278e55d57 100644
--- a/indra/newview/skins/default/xui/en/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
@@ -46,14 +46,14 @@
      name="GridSubUnit"
      top_pad="0"
      width="200" />
-    <check_box
+    <!-- <check_box
      control_name="GridCrossSections"
      height="16"
      label="View cross-sections"
      layout="topleft"
      name="GridCrossSection"
      top_pad="5"
-     width="200" />
+     width="200" />-->
    <text
          type="string"
          length="1"
-- 
cgit v1.2.3


From 176f34791bf26e3cb14c05260e538e7107329f7a Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 7 Oct 2022 10:05:44 -0500
Subject: SL-18190 Fix for mac build

---
 indra/newview/pipeline.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7eaa3a065c..b8df8bb95f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -132,12 +132,12 @@
 // NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
 // NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
 //  const S32 WATER_REFLECT_NONE_WATER_OPAQUE       = -2;
-    const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT  = -1;
-    const S32 WATER_REFLECT_MINIMAL                 =  0;
+    //const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT  = -1;
+    //const S32 WATER_REFLECT_MINIMAL                 =  0;
 //  const S32 WATER_REFLECT_TERRAIN                 =  1;
-    const S32 WATER_REFLECT_STATIC_OBJECTS          =  2;
-    const S32 WATER_REFLECT_AVATARS                 =  3;
-    const S32 WATER_REFLECT_EVERYTHING              =  4;
+    //const S32 WATER_REFLECT_STATIC_OBJECTS          =  2;
+    //const S32 WATER_REFLECT_AVATARS                 =  3;
+    //const S32 WATER_REFLECT_EVERYTHING              =  4;
 
 bool gShiftFrame = false;
 
-- 
cgit v1.2.3


From 26f99409d247a0c872239d73ac05451ef8531ff4 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 7 Oct 2022 12:52:43 -0500
Subject: SL-18190 Temporarily disable occlusion culling by default -- not
 compatible with depth buffer management changes.

---
 .../shaders/class1/interface/occlusionF.glsl       | 12 +++---
 indra/newview/featuretable.txt                     |  4 +-
 indra/newview/featuretable_mac.txt                 |  4 +-
 indra/newview/llspatialpartition.cpp               |  4 +-
 indra/newview/llviewerdisplay.cpp                  |  2 +-
 indra/newview/llvieweroctree.cpp                   |  2 +-
 indra/newview/pipeline.cpp                         | 47 ++++++++++------------
 indra/newview/pipeline.h                           |  4 +-
 8 files changed, 38 insertions(+), 41 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index db130e456c..f5d2804c7f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
@@ -23,13 +23,13 @@
  * $/LicenseInfo$
  */
  
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+out vec4 frag_data[4];
 
 void main() 
 {
-	frag_color = vec4(1,1,1,1);
+    // emissive red PBR material for debugging
+    frag_data[0] = vec4(0, 0, 0, 0);
+    frag_data[1] = vec4(0, 0, 0, 0);
+    frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+    frag_data[3] = vec4(1, 0, 0, 0);
 }
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index cfcb623caf..ddd24b70c6 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 39
+version 40
 // The version number above should be incremented IF AND ONLY IF some
 // change has been made that is sufficiently important to justify
 // resetting the graphics preferences of all users to the recommended
@@ -56,7 +56,7 @@ RenderVBOEnable				1	1
 RenderVBOMappingDisable		1	1
 RenderVolumeLODFactor		1	2.0
 UseStartScreen				1	1
-UseOcclusion				1	1
+UseOcclusion				1	0
 WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 79ce057c30..98f498f59d 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 40
+version 41
 // The version number above should be incremented IF AND ONLY IF some
 // change has been made that is sufficiently important to justify
 // resetting the graphics preferences of all users to the recommended
@@ -55,7 +55,7 @@ RenderVBOEnable				1	1
 RenderVBOMappingDisable		1	1
 RenderVolumeLODFactor		1	2.0
 UseStartScreen				1	1
-UseOcclusion				1	1
+UseOcclusion				1	0
 WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index d02c5861b1..96c41416fa 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1013,11 +1013,11 @@ public:
 	virtual void processGroup(LLViewerOctreeGroup* base_group)
 	{
 		LLSpatialGroup* group = (LLSpatialGroup*)base_group;
-		if (group->needsUpdate() ||
+		/*if (group->needsUpdate() ||
 			group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
 		{
 			group->doOcclusion(mCamera);
-		}
+		}*/
 		gPipeline.markNotCulled(group, *mCamera);
 	}
 };
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0d2a44867e..5ae7f522f2 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -962,7 +962,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gGL.setColorMask(true, false);
 			if (LLPipeline::sRenderDeferred)
 			{
-				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
 			}
 			else
 			{
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index a75eb518f3..1f16161780 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1169,7 +1169,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
     else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
     {	//check occlusion has been issued for occluded node that has not had a query issued
         assert_states_valid(this);
-        clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+        //clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
         assert_states_valid(this);
     }
 }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b8df8bb95f..c360a7fc63 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2538,6 +2538,13 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
 		sCull->pushVisibleGroup(group);
 	}
 
+    if (group->needsUpdate() ||
+        group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
+    {
+        // include this group in occlusion groups, not because it is an occluder, but because we want to run
+        // an occlusion query to find out if it's an occluder
+        markOccluder(group);
+    }
 	mNumVisibleNodes++;
 }
 
@@ -4585,12 +4592,14 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
 #endif
 }
 
-void LLPipeline::renderGeomDeferred(LLCamera& camera)
+void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
 {
 	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
 	LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
     LL_PROFILE_GPU_ZONE("renderGeomDeferred");
 
+    bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
+
 	{
 		LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
 
@@ -4630,6 +4639,17 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 		
 			cur_type = poolp->getType();
 
+            if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
+            {
+                llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
+                occlude = false;
+                gGLLastMatrix = NULL;
+                gGL.loadMatrix(gGLModelView);
+                LLGLSLShader::bindNoShader();
+                doOcclusion(camera);
+                gGL.setColorMask(true, false);
+            }
+
 			pool_set_t::iterator iter2 = iter1;
 			if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
 			{
@@ -4686,7 +4706,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 	} // Tracy ZoneScoped
 }
 
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 {
 	LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS);
     LL_PROFILE_GPU_ZONE("renderGeomPostDeferred");
@@ -4703,7 +4723,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 	gGL.setColorMask(true, false);
 
 	pool_set_t::iterator iter1 = mPools.begin();
-	bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
 
 	while ( iter1 != mPools.end() )
 	{
@@ -4711,18 +4730,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 		
 		cur_type = poolp->getType();
 
-		if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
-		{
-            llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
-			occlude = false;
-			gGLLastMatrix = NULL;
-			gGL.loadMatrix(gGLModelView);
-			LLGLSLShader::bindNoShader();
-			//doOcclusion(camera, mRT->screen, mRT->occlusionDepth, &mRT->deferredDepth);
-            doOcclusion(camera, mRT->screen, mRT->occlusionDepth);
-			gGL.setColorMask(true, false);
-		}
-
 		pool_set_t::iterator iter2 = iter1;
 		if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
 		{
@@ -4774,16 +4781,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.loadMatrix(gGLModelView);
 
-	if (occlude)
-	{
-		occlude = false;
-		LLGLSLShader::bindNoShader();
-		doOcclusion(camera);
-		gGLLastMatrix = NULL;
-		gGL.matrixMode(LLRender::MM_MODELVIEW);
-		gGL.loadMatrix(gGLModelView);
-	}
-
     if (!gCubeSnapshot)
     {
         // debug displays
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index a31df9c16f..23ddfb51e5 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -290,8 +290,8 @@ public:
 
 
 	void renderGeom(LLCamera& camera, bool forceVBOUpdate = false);
-	void renderGeomDeferred(LLCamera& camera);
-	void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
+	void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
+	void renderGeomPostDeferred(LLCamera& camera);
 	void renderGeomShadow(LLCamera& camera);
 	void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
 	void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
-- 
cgit v1.2.3


From 4a4b0f8ee8834de01e52d32aecdb0479ed5fb7a9 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 7 Oct 2022 13:25:40 -0500
Subject: SL-18190 Rearrange render order so 3D UI has access to the depth
 buffer.

---
 indra/newview/llviewerdisplay.cpp |  71 ++++++++++---------
 indra/newview/pipeline.cpp        | 140 +++++++++++++++++++-------------------
 2 files changed, 108 insertions(+), 103 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 5ae7f522f2..112d669740 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1374,10 +1374,10 @@ void render_ui(F32 zoom_factor, int subfield)
 		gGL.popMatrix();
 	}
 
-	// Finalize scene
-	gPipeline.renderFinalize();
-
 	{
+        // draw hud and 3D ui elements into screen render target so they'll be able to use 
+        // the depth buffer (avoids extra copy of depth buffer per frame)
+        gPipeline.mRT->screen.bindTarget();
 		// SL-15709
 		// NOTE: Tracy only allows one ZoneScoped per function.
 		// Solutions are:
@@ -1394,41 +1394,46 @@ void render_ui(F32 zoom_factor, int subfield)
 			gPipeline.disableLights();
 		}
 
-		{
-			gGL.color4f(1,1,1,1);
-			if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
-			{
-				if (!gDisconnected)
-				{
-					LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
-					render_ui_3d();
-					LLGLState::checkStates();
-				}
-				else
-				{
-					render_disconnected_background();
-				}
+        gGL.color4f(1,1,1,1);
 
-				LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
-				render_ui_2d();
-				LLGLState::checkStates();
-			}
-			gGL.flush();
+        bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+        if (render_ui)
+        {
+            if (!gDisconnected)
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
+                render_ui_3d();
+                LLGLState::checkStates();
+            }
+            else
+            {
+                render_disconnected_background();
+            }
+        }
 
-			gViewerWindow->setup2DRender();
-			gViewerWindow->updateDebugText();
-			gViewerWindow->drawDebugText();
+        gPipeline.mRT->screen.flush();
 
-			LLVertexBuffer::unbind();
-		}
+        // apply gamma correction and post effects before rendering 2D UI
+        gPipeline.renderFinalize();
 
-		if (!gSnapshot)
-		{
-			set_current_modelview(saved_view);
-			gGL.popMatrix();
-		}
+        if (render_ui)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
+            render_ui_2d();
+            LLGLState::checkStates();
+            gGL.flush();
+        }
 
-	} // Tracy integration
+        gViewerWindow->setup2DRender();
+        gViewerWindow->updateDebugText();
+        gViewerWindow->drawDebugText();
+	}
+
+	if (!gSnapshot)
+	{
+		set_current_modelview(saved_view);
+		gGL.popMatrix();
+	}
 }
 
 static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c360a7fc63..87a5cd9cc8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7599,6 +7599,76 @@ void LLPipeline::renderFinalize()
     gGL.setColorMask(true, true);
     glClearColor(0, 0, 0, 0);
 
+    if (!gCubeSnapshot)
+    {
+        // gamma correct lighting
+        gGL.matrixMode(LLRender::MM_PROJECTION);
+        gGL.pushMatrix();
+        gGL.loadIdentity();
+        gGL.matrixMode(LLRender::MM_MODELVIEW);
+        gGL.pushMatrix();
+        gGL.loadIdentity();
+
+        {
+            LL_PROFILE_GPU_ZONE("gamma correct");
+
+            LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+            LLRenderTarget* screen_target = &mRT->screen;
+
+            LLVector2 tc1(0, 0);
+            LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2);
+
+            screen_target->bindTarget();
+            // Apply gamma correction to the frame here.
+            gDeferredPostGammaCorrectProgram.bind();
+            // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+            S32 channel = 0;
+            channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
+            if (channel > -1)
+            {
+                screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+            }
+
+            gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
+
+            F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+            gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+            gGL.vertex2f(-1, -1);
+
+            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+            gGL.vertex2f(-1, 3);
+
+            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+            gGL.vertex2f(3, -1);
+
+            gGL.end();
+
+            gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
+            gDeferredPostGammaCorrectProgram.unbind();
+            screen_target->flush();
+        }
+
+        gGL.matrixMode(LLRender::MM_PROJECTION);
+        gGL.popMatrix();
+        gGL.matrixMode(LLRender::MM_MODELVIEW);
+        gGL.popMatrix();
+
+        LLVertexBuffer::unbind();
+
+        if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+        {
+            // Render debugging beacons.
+            gObjectList.renderObjectBeacons();
+            gObjectList.resetObjectBeacons();
+            gSky.addSunMoonBeacons();
+        }
+    }
+
     if (sRenderGlow)
     {
         LL_PROFILE_GPU_ZONE("glow");
@@ -9037,76 +9107,6 @@ void LLPipeline::renderDeferredLighting()
     }
 
     screen_target->flush();
-
-    if (!gCubeSnapshot)
-    {
-        // gamma correct lighting
-        gGL.matrixMode(LLRender::MM_PROJECTION);
-        gGL.pushMatrix();
-        gGL.loadIdentity();
-        gGL.matrixMode(LLRender::MM_MODELVIEW);
-        gGL.pushMatrix();
-        gGL.loadIdentity();
-
-        {
-            LL_PROFILE_GPU_ZONE("gamma correct");
-
-            LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
-            LLVector2 tc1(0, 0);
-            LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2);
-
-            screen_target->bindTarget();
-            // Apply gamma correction to the frame here.
-            gDeferredPostGammaCorrectProgram.bind();
-            // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-            S32 channel = 0;
-            channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
-            if (channel > -1)
-            {
-                screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
-            }
-
-            gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
-
-            F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
-
-            gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
-
-            gGL.begin(LLRender::TRIANGLE_STRIP);
-            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-            gGL.vertex2f(-1, -1);
-
-            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-            gGL.vertex2f(-1, 3);
-
-            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-            gGL.vertex2f(3, -1);
-
-            gGL.end();
-
-            gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
-            gDeferredPostGammaCorrectProgram.unbind();
-            screen_target->flush();
-        }
-
-        gGL.matrixMode(LLRender::MM_PROJECTION);
-        gGL.popMatrix();
-        gGL.matrixMode(LLRender::MM_MODELVIEW);
-        gGL.popMatrix();
-    
-        LLVertexBuffer::unbind();
-
-        if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
-        {
-            // Render debugging beacons.
-            gObjectList.renderObjectBeacons();
-            gObjectList.resetObjectBeacons();
-            gSky.addSunMoonBeacons();
-        }
-    }
-
-    screen_target->flush();
 }
 
 void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
-- 
cgit v1.2.3


From 18309bc7fbfefa7aec29b24b727de7fe07da96fe Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 7 Oct 2022 15:25:48 -0500
Subject: SL-18190 Fix for DoF

---
 indra/newview/lldrawpoolalpha.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index fb2a4d78fc..8a912b00d9 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -184,8 +184,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
         renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, 
             true); // <--- discard mostly transparent faces
 
-        gPipeline.mRT->deferredDepth.flush();
-        gPipeline.mRT->screen.bindTarget();
+        //gPipeline.mRT->deferredDepth.flush();
+        //gPipeline.mRT->screen.bindTarget();
         gGL.setColorMask(true, false);
     }
 
-- 
cgit v1.2.3


From 2fa8bce1cffe932089a05ad1c7834bb20b435fcf Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 7 Oct 2022 23:46:01 +0300
Subject: SL-18326 GLTF material functionality in a Notecard

---
 indra/newview/llmaterialeditor.cpp       | 166 +++++++++++++++++++++++++------
 indra/newview/llmaterialeditor.h         |   7 +-
 indra/newview/llpanelobjectinventory.cpp |   4 +-
 indra/newview/llpreview.h                |   2 +-
 indra/newview/llviewertexteditor.cpp     |  25 +++++
 indra/newview/llviewertexteditor.h       |   1 +
 6 files changed, 172 insertions(+), 33 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index a2cd68259b..27b5d508e0 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llmaterialeditor.cpp
- * @brief Implementation of the notecard editor
+ * @brief Implementation of the gltf material editor
  *
  * $LicenseInfo:firstyear=2022&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -150,16 +150,44 @@ void LLFloaterComboOptions::onCancel()
 class LLMaterialEditorCopiedCallback : public LLInventoryCallback
 {
 public:
-    LLMaterialEditorCopiedCallback(const std::string &buffer, const LLUUID &old_item_id) : mBuffer(buffer), mOldItemId(old_item_id) {}
+    LLMaterialEditorCopiedCallback(
+        const std::string &buffer,
+        const LLSD &old_key,
+        bool has_unsaved_changes)
+        : mBuffer(buffer),
+          mOldKey(old_key),
+          mHasUnsavedChanges(has_unsaved_changes)
+    {}
+
+    LLMaterialEditorCopiedCallback(
+        const LLSD &old_key,
+        const std::string &new_name)
+        : mOldKey(old_key),
+          mNewName(new_name),
+          mHasUnsavedChanges(false)
+    {}
 
     virtual void fire(const LLUUID& inv_item_id)
     {
-        LLMaterialEditor::finishSaveAs(mOldItemId, inv_item_id, mBuffer);
+        if (!mNewName.empty())
+        {
+            // making a copy from a notecard doesn't change name, do it now
+            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+            if (item->getName() != mNewName)
+            {
+                LLSD updates;
+                updates["name"] = mNewName;
+                update_inventory_item(inv_item_id, updates, NULL);
+            }
+        }
+        LLMaterialEditor::finishSaveAs(mOldKey, inv_item_id, mBuffer, mHasUnsavedChanges);
     }
 
 private:
     std::string mBuffer;
-    LLUUID mOldItemId;
+    LLSD mOldKey;
+    std::string mNewName;
+    bool mHasUnsavedChanges;
 };
 
 ///----------------------------------------------------------------------------
@@ -190,6 +218,15 @@ void LLMaterialEditor::setObjectID(const LLUUID& object_id)
     }
 }
 
+void LLMaterialEditor::setAuxItem(const LLInventoryItem* item)
+{
+    LLPreview::setAuxItem(item);
+    if (item)
+    {
+        mAssetID = item->getAssetUUID();
+    }
+}
+
 BOOL LLMaterialEditor::postBuild()
 {
     mBaseColorTextureCtrl = getChild<LLTextureCtrl>("base_color_texture");
@@ -456,10 +493,25 @@ void LLMaterialEditor::setDoubleSided(bool double_sided)
 
 void LLMaterialEditor::setHasUnsavedChanges(bool value)
 {
-    if (value != mHasUnsavedChanges)
+    mHasUnsavedChanges = value;
+    childSetVisible("unsaved_changes", value);
+
+    if (mHasUnsavedChanges)
     {
-        mHasUnsavedChanges = value;
-        childSetVisible("unsaved_changes", value);
+        const LLInventoryItem* item = getItem();
+        if (item)
+        {
+            LLPermissions perm(item->getPermissions());
+            bool allow_modify = canModify(mObjectUUID, item);
+            bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+            bool source_notecard = mNotecardInventoryID.notNull();
+
+            setCanSave(allow_modify && !source_library && !source_notecard);
+        }
+    }
+    else
+    {
+        setCanSave(false);
     }
 
     S32 upload_texture_count = 0;
@@ -1019,23 +1071,39 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID
     }
 }
 
-void LLMaterialEditor::finishSaveAs(const LLUUID &oldItemId, const LLUUID &newItemId, const std::string &buffer)
+void LLMaterialEditor::finishSaveAs(
+    const LLSD &oldKey,
+    const LLUUID &newItemId,
+    const std::string &buffer,
+    bool has_unsaved_changes)
 {
-    LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(oldItemId));
+    LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", oldKey);
     LLViewerInventoryItem* item = gInventory.getItem(newItemId);
     if (item)
     {
         if (me)
         {
             me->mItemUUID = newItemId;
+            me->mObjectUUID = LLUUID::null;
+            me->mNotecardInventoryID = LLUUID::null;
+            me->mNotecardObjectID = LLUUID::null;
+            me->mAuxItem = nullptr;
             me->setKey(LLSD(newItemId)); // for findTypedInstance
             me->setMaterialName(item->getName());
-            if (!saveToInventoryItem(buffer, newItemId, LLUUID::null))
+            if (has_unsaved_changes)
             {
+                if (!saveToInventoryItem(buffer, newItemId, LLUUID::null))
+                {
+                    me->setEnabled(true);
+                }
+            }
+            else
+            {
+                me->loadAsset();
                 me->setEnabled(true);
             }
         }
-        else
+        else if(has_unsaved_changes)
         {
             saveToInventoryItem(buffer, newItemId, LLUUID::null);
         }
@@ -1052,17 +1120,24 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id)
     if (new_item_id.notNull())
     {
         mItemUUID = new_item_id;
-        if (mObjectUUID.isNull())
+        if (mNotecardInventoryID.notNull())
         {
-            setKey(LLSD(new_item_id));
+            LLSD floater_key;
+            floater_key["objectid"] = mNotecardObjectID;
+            floater_key["notecardid"] = mNotecardInventoryID;
+            setKey(floater_key);
         }
-        else
+        else if (mObjectUUID.notNull())
         {
             LLSD floater_key;
             floater_key["taskid"] = new_item_id;
             floater_key["itemid"] = mObjectUUID;
             setKey(floater_key);
         }
+        else
+        {
+            setKey(LLSD(new_item_id));
+        }
     }
     LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL;
     loadAsset();
@@ -1094,7 +1169,15 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD&
         LLInventoryObject::correctInventoryName(new_name);
         if (!new_name.empty())
         {
-            const LLInventoryItem* item = getItem();
+            const LLInventoryItem* item;
+            if (mNotecardInventoryID.notNull())
+            {
+                item = mAuxItem.get();
+            }
+            else
+            {
+                item = getItem();
+            }
             if (item)
             {
                 const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
@@ -1105,15 +1188,27 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD&
                 }
 
                 // A two step process, first copy an existing item, then create new asset
-                std::string buffer = getEncodedAsset();
-                LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, item->getUUID());
-                copy_inventory_item(
-                    gAgent.getID(),
-                    item->getPermissions().getOwner(),
-                    item->getUUID(),
-                    parent_id,
-                    new_name,
-                    cb);
+                if (mNotecardInventoryID.notNull())
+                {
+                    LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(getKey(), new_name);
+                    copy_inventory_from_notecard(parent_id,
+                        mNotecardObjectID,
+                        mNotecardInventoryID,
+                        mAuxItem.get(),
+                        gInventoryCallbacks.registerCB(cb));
+                }
+                else
+                {
+                    std::string buffer = getEncodedAsset();
+                    LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mHasUnsavedChanges);
+                    copy_inventory_item(
+                        gAgent.getID(),
+                        item->getPermissions().getOwner(),
+                        item->getUUID(),
+                        parent_id,
+                        new_name,
+                        cb);
+                }
 
                 mAssetStatus = PREVIEW_ASSET_LOADING;
                 setEnabled(false);
@@ -1772,19 +1867,26 @@ void LLMaterialEditor::loadAsset()
     // TODO: see commented out "editor" references and make them do something appropriate to the UI
    
     // request the asset.
-    const LLInventoryItem* item = getItem();
+    const LLInventoryItem* item;
+    if (mNotecardInventoryID.notNull())
+    {
+        item = mAuxItem.get();
+    }
+    else
+    {
+        item = getItem();
+    }
     
     bool fail = false;
 
     if (item)
     {
         LLPermissions perm(item->getPermissions());
-        BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
-        BOOL allow_modify = canModify(mObjectUUID, item);
-        BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+        bool allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
+        bool allow_modify = canModify(mObjectUUID, item);
+        bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
 
         setCanSaveAs(allow_copy);
-        setCanSave(allow_modify && !source_library);
         setMaterialName(item->getName());
 
         {
@@ -1801,7 +1903,11 @@ void LLMaterialEditor::loadAsset()
                 LLHost source_sim = LLHost();
                 LLSD* user_data = new LLSD();
 
-                if (mObjectUUID.notNull())
+                if (mNotecardInventoryID.notNull())
+                {
+                    user_data->with("objectid", mNotecardObjectID).with("notecardid", mNotecardInventoryID);
+                }
+                else if (mObjectUUID.notNull())
                 {
                     LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
                     if (objectp && objectp->getRegion())
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
index 4e17cee154..d329222648 100644
--- a/indra/newview/llmaterialeditor.h
+++ b/indra/newview/llmaterialeditor.h
@@ -136,7 +136,11 @@ public:
 
     static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
 
-    static void finishSaveAs(const LLUUID &oldItemId, const LLUUID &newItemId, const std::string &buffer);
+    static void finishSaveAs(
+        const LLSD &oldKey,
+        const LLUUID &newItemId,
+        const std::string &buffer,
+        bool has_unsaved_changes);
 
     void refreshFromInventory(const LLUUID& new_item_id = LLUUID::null);
 
@@ -147,6 +151,7 @@ public:
 
     // llpreview
     void setObjectID(const LLUUID& object_id) override;
+    void setAuxItem(const LLInventoryItem* item) override;
 
 	// llpanel
 	BOOL postBuild() override;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index c5bf18a065..d61cc26f62 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1198,10 +1198,12 @@ void LLTaskMaterialBridge::openItem()
         LLSD floater_key;
         floater_key["taskid"] = mPanel->getTaskUUID();
         floater_key["itemid"] = mUUID;
-        LLMaterialEditor* mat = LLFloaterReg::showTypedInstance<LLMaterialEditor>("material_editor", floater_key, TAKE_FOCUS_YES);
+        LLMaterialEditor* mat = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
         if (mat)
         {
             mat->setObjectID(mPanel->getTaskUUID());
+            mat->openFloater(floater_key);
+            mat->setFocus(TRUE);
         }
     }
 }
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index 9ac15d1639..ab60f4c008 100644
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
@@ -83,7 +83,7 @@ public:
 	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
 	virtual void onOpen(const LLSD& key);
 	
-	void setAuxItem( const LLInventoryItem* item );
+	virtual void setAuxItem( const LLInventoryItem* item );
 
 	static void			onBtnCopyToInv(void* userdata);
 
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 7c860936a5..3f302d4f45 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -42,6 +42,7 @@
 #include "lllandmark.h"
 #include "lllandmarkactions.h"
 #include "lllandmarklist.h"
+#include "llmaterialeditor.h"
 #include "llmemorystream.h"
 #include "llmenugl.h"
 #include "llnotecard.h"
@@ -542,6 +543,7 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
 			case LLAssetType::AT_GESTURE:		img_name = "Inv_Gesture";	break;
 			case LLAssetType::AT_MESH:      	img_name = "Inv_Mesh";	    break;
             case LLAssetType::AT_SETTINGS:      img_name = "Inv_Settings"; break;
+            case LLAssetType::AT_MATERIAL:      img_name = "Inv_Material"; break;
 			default:                        	img_name = "Inv_Invalid";  break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981)
 
 		}
@@ -1127,6 +1129,9 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwch
 		case LLAssetType::AT_SETTINGS:
 			openEmbeddedSetting(item, wc);
 			return TRUE;
+        case LLAssetType::AT_MATERIAL:
+            openEmbeddedGLTFMaterial(item, wc);
+            return TRUE;
 		case LLAssetType::AT_NOTECARD:
 		case LLAssetType::AT_LSL_TEXT:
 		case LLAssetType::AT_CLOTHING:
@@ -1213,6 +1218,26 @@ void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc)
 	}
 }
 
+void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc)
+{
+    if (!item)
+    {
+        return;
+    }
+
+    LLSD floater_key;
+    floater_key["objectid"] = mObjectID;
+    floater_key["notecardid"] = mNotecardInventoryID;
+    LLMaterialEditor* preview = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+    if (preview)
+    {
+        preview->setAuxItem(item);
+        preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
+        preview->openFloater(floater_key);
+        preview->setFocus(TRUE);
+    }
+}
+
 void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
 {
 	LLSD payload;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index a6d7fef409..6170d476b8 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -108,6 +108,7 @@ private:
 	void			openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
 	void			openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
 	void			openEmbeddedSetting(LLInventoryItem* item, llwchar wc);
+    void			openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc);
 	void			showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
 	void			showUnsavedAlertDialog( LLInventoryItem* item );
 
-- 
cgit v1.2.3


From 25bff0c21dafcfca4d098f2d51a46a09c543a12c Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 7 Oct 2022 19:27:19 -0500
Subject: SL-18190 Move water shaders to class 3, add debug stub for
 underWaterF.glsl, make underWaterF and softenLightF apply water fog in linear
 space.

---
 .../shaders/class1/environment/underWaterF.glsl    |  49 +---
 .../shaders/class1/environment/waterFogF.glsl      |   6 +
 .../shaders/class2/environment/waterF.glsl         | 196 +++++-----------
 .../shaders/class3/deferred/softenLightF.glsl      |   4 +-
 .../shaders/class3/environment/underWaterF.glsl    |  74 ++++++
 .../shaders/class3/environment/waterF.glsl         | 258 +++++++++++++++++++++
 indra/newview/llviewershadermgr.cpp                |   2 +-
 7 files changed, 401 insertions(+), 188 deletions(-)
 create mode 100644 indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class3/environment/waterF.glsl

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 8c8bd6d0d5..ad105c616c 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -23,55 +23,10 @@
  * $/LicenseInfo$
  */
  
-#ifdef DEFINE_GL_FRAGCOLOR
 out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;   
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform sampler2D screenDepth;
-
-uniform vec4 fogCol;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform vec2 fbScale;
-uniform float refScale;
-uniform float znear;
-uniform float zfar;
-uniform float kd;
-uniform vec4 waterPlane;
-uniform vec3 eyeVec;
-uniform vec4 waterFogColor;
-uniform float waterFogKS;
-uniform vec2 screenRes;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec4 applyWaterFogView(vec3 pos, vec4 color);
 
+// debug stub
 void main() 
 {
-	vec4 color;
-	    
-	//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;    
-	vec3 wavef = normalize(wave1+wave2+wave3);
-	
-	//figure out distortion vector (ripply)   
-	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-	distort = distort+wavef.xy*refScale;
-		
-	vec4 fb = texture2D(screenTex, distort);
-	
-	frag_color = applyWaterFogView(view.xyz, fb);
+    frag_color = vec4(0, 1, 1, 0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 7dbba12502..011b3c8643 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -75,10 +75,16 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
 
 vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
 {
+    if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
+    {
+        return color;
+    }
+
     vec3 view = normalize(pos);
     //normalize view vector
     float es = -(dot(view, waterPlane.xyz));
 
+    
     //find intersection point with water plane and eye vector
 
     //get eye depth
diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
index b51583de26..d485379a56 100644
--- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
@@ -22,40 +22,22 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+//class2/environment/waterF.glsl
+
 #ifdef DEFINE_GL_FRAGCOLOR
 out vec4 frag_color;
 #else
 #define frag_color gl_FragColor
 #endif
 
-vec3 scaleSoftClipFragLinear(vec3 l);
-vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
-void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
-
-// PBR interface
-vec3 pbrIbl(vec3 diffuseColor,
-    vec3 specularColor,
-    vec3 radiance, // radiance map sample
-    vec3 irradiance, // irradiance map sample
-    float ao,       // ambient occlusion factor
-    float nv,       // normal dot view vector
-    float perceptualRoughness);
-
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
-    float perceptualRoughness,
-    float metallic,
-    vec3 n, // normal
-    vec3 v, // surface point to camera
-    vec3 l); //surface point to light
+vec3 scaleSoftClip(vec3 inColor);
+vec3 atmosTransport(vec3 inColor);
 
 uniform sampler2D bumpMap;
 uniform sampler2D bumpMap2;
 uniform float     blend_factor;
 uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
-
 uniform sampler2D refTex;
 
 uniform float sunAngle;
@@ -70,17 +52,12 @@ uniform vec3 normScale;
 uniform float fresnelScale;
 uniform float fresnelOffset;
 uniform float blurMultiplier;
-uniform vec4 waterFogColor;
 
 
 //bigWave is (refCoord.w, view.w);
 VARYING vec4 refCoord;
 VARYING vec4 littleWave;
 VARYING vec4 view;
-in vec3 vary_position;
-in vec3 vary_normal;
-in vec3 vary_tangent;
-in vec3 vary_light_dir;
 
 vec3 BlendNormal(vec3 bump1, vec3 bump2)
 {
@@ -88,37 +65,15 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
     return n;
 }
 
-vec3 srgb_to_linear(vec3 col);
-
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
-    vec3 pos, vec3 norm, float glossiness, float envIntensity);
-
-vec3 vN, vT, vB;
-
-vec3 transform_normal(vec3 vNt)
-{
-    return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
-}
-
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
-    vec3 pos, vec3 norm, float glossiness);
-
-vec3 getPositionWithNDC(vec3 ndc);
 
 void main() 
 {
 	vec4 color;
-
-    vN = vary_normal;
-    vT = vary_tangent;
-    vB = cross(vN, vT);
-
-    vec3 pos = vary_position.xyz;
-
-	float dist = length(pos.xyz);
+	
+	float dist = length(view.xy);
 	
 	//normalize view vector
-	vec3 viewVec = normalize(pos.xyz);
+	vec3 viewVec = normalize(view.xyz);
 	
 	//get wave normals
     vec2 bigwave = vec2(refCoord.w, view.w);
@@ -126,6 +81,7 @@ void main()
     vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
     vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
 
+
     vec3 wave1_b = texture2D(bumpMap2, bigwave      ).xyz*2.0-1.0;
     vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
     vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
@@ -134,15 +90,6 @@ void main()
     vec3 wave2 = BlendNormal(wave2_a, wave2_b);
     vec3 wave3 = BlendNormal(wave3_a, wave3_b);
 
-    wave1 = transform_normal(wave1);
-    wave2 = transform_normal(wave2);
-    wave3 = transform_normal(wave3);
-
-    vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
-
-    wavef.z *= max(-viewVec.z, 0.1);
-
-    wavef = normalize(wavef);
 
 	//get base fresnel components	
 	
@@ -151,6 +98,7 @@ void main()
 					dot(viewVec, (wave2 + wave3) * 0.5),
 					dot(viewVec, wave3)
 				 ) * fresnelScale + fresnelOffset;
+	df *= df;
 		    
 	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
 	
@@ -161,85 +109,57 @@ void main()
 	
 	vec2 dmod_scale = vec2(dmod*dmod, dmod);
 	
-    float df1 = df.x + df.y + df.z;
-
-    //wavef = normalize(wavef - vary_normal);
-    //wavef = vary_normal;
+	//get reflected color
+	vec2 refdistort1 = wave1.xy*normScale.x;
+	vec2 refvec1 = distort+refdistort1/dmod_scale;
+	vec4 refcol1 = texture2D(refTex, refvec1);
+	
+	vec2 refdistort2 = wave2.xy*normScale.y;
+	vec2 refvec2 = distort+refdistort2/dmod_scale;
+	vec4 refcol2 = texture2D(refTex, refvec2);
+	
+	vec2 refdistort3 = wave3.xy*normScale.z;
+	vec2 refvec3 = distort+refdistort3/dmod_scale;
+	vec4 refcol3 = texture2D(refTex, refvec3);
 
-    vec3 waver = reflect(viewVec, -wavef)*3;
+	vec4 refcol = refcol1 + refcol2 + refcol3;
+	float df1 = df.x + df.y + df.z;
+	refcol *= df1 * 0.333;
+	
+	vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+	
+	wavef.z *= max(-viewVec.z, 0.1);
+	wavef = normalize(wavef);
+	
+	float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
+	
+	vec2 refdistort4 = wavef.xy*0.125;
+	refdistort4.y -= abs(refdistort4.y);
+	vec2 refvec4 = distort+refdistort4/dmod;
+	float dweight = min(dist2*blurMultiplier, 1.0);
+	vec4 baseCol = texture2D(refTex, refvec4);
+	refcol = mix(baseCol*df2, refcol, dweight);
+
+	//get specular component
+	float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
+		
+	//harden specular
+	spec = pow(spec, 128.0);
 
 	//figure out distortion vector (ripply)   
-    vec2 distort2 = distort + waver.xy * refScale / max(dmod * df1, 1.0);
-    distort2 = clamp(distort2, vec2(0), vec2(0.99));
- 
-    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));
-
-#if 1
-    if (refPos.z > pos.z-0.05)
-    {
-        //we sampled an above water sample, don't distort
-        distort2 = distort;
-        fb = texture2D(screenTex, distort2);
-        depth = texture2D(screenDepth, distort2).r;
-        refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
-    }
-#endif
-
-    fb = applyWaterFogViewLinear(refPos, fb);
-
-    vec3 sunlit;
-    vec3 amblit;
-    vec3 additive;
-    vec3 atten;
-
-    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
-    sunlit = vec3(1); // TODO -- figure out why sunlit is breaking at some view angles
-    vec3 v = -viewVec;
-    float NdotV = clamp(abs(dot(wavef.xyz, v)), 0.001, 1.0);
-
-    float metallic = fresnelOffset * 0.1; // fudge -- use fresnelOffset as metalness
-    float roughness = 0.1;
-    float gloss = 1.0 - roughness;
-
-    vec3 baseColor = vec3(0.25);
-    vec3 f0 = vec3(0.04);
-    vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
-    diffuseColor *= gloss;
-
-    vec3 specularColor = mix(f0, baseColor.rgb, metallic);
-
-    vec3 refnorm = normalize(wavef + vary_normal);
-    //vec3 refnorm = wavef;
-    
-   
-    vec3 irradiance = vec3(0);
-    vec3 radiance = vec3(0);
-    sampleReflectionProbes(irradiance, radiance, pos, refnorm, gloss);
-    radiance *= 0.5;
-    irradiance = fb.rgb;
-
-    color.rgb = pbrIbl(diffuseColor, specularColor, radiance, irradiance, gloss, NdotV, 0.0);
-    
-    // fudge -- for punctual lighting, pretend water is metallic
-    diffuseColor = vec3(0);
-    specularColor = vec3(1);
-    roughness = 0.1;
-    float scol = 1.0; // TODO -- incorporate shadow map
-
-    color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
-	color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-	color.rgb = scaleSoftClipFragLinear(color.rgb);
-
-    color.a = 0.f;
-    //color.rgb = fb.rgb;
-    //color.rgb = vec3(depth*depth*depth*depth);
-    //color.rgb = srgb_to_linear(normalize(refPos) * 0.5 + 0.5);
-    //color.rgb = srgb_to_linear(normalize(pos) * 0.5 + 0.5);
-    //color.rgb = srgb_to_linear(wavef * 0.5 + 0.5);
-
-    //color.rgb = radiance;
+	vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
+		
+	vec4 fb = texture2D(screenTex, distort2);
+	
+	//mix with reflection
+	// Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
+	color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
+	color.rgb += spec * specular;
+	
+	color.rgb = atmosTransport(color.rgb);
+	color.rgb = scaleSoftClip(color.rgb);
+	color.a = spec * sunAngle2;
+	
 	frag_color = color;
 
 #if defined(WATER_EDGE)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index e5ffe55163..eea497bce5 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -86,7 +86,7 @@ vec3 linear_to_srgb(vec3 c);
 vec3 srgb_to_linear(vec3 c);
 
 #ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 #endif
 
 // PBR interface
@@ -236,7 +236,7 @@ void main()
     }
 
     #ifdef WATER_FOG
-        vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
+        vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
         color       = fogged.rgb;
     #endif
 
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
new file mode 100644
index 0000000000..819e6dcf15
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -0,0 +1,74 @@
+/**
+ * @file class3\environment\underWaterF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+out vec4 frag_color;
+
+uniform sampler2D diffuseMap;
+uniform sampler2D bumpMap;   
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform sampler2D screenDepth;
+
+uniform vec4 fogCol;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform vec2 fbScale;
+uniform float refScale;
+uniform float znear;
+uniform float zfar;
+uniform float kd;
+uniform vec4 waterPlane;
+uniform vec3 eyeVec;
+uniform vec4 waterFogColor;
+uniform float waterFogKS;
+uniform vec2 screenRes;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+in vec3 vary_position;
+
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+
+void main() 
+{
+	vec4 color;
+	    
+	//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;    
+	vec3 wavef = normalize(wave1+wave2+wave3);
+	
+	//figure out distortion vector (ripply)   
+	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+	distort = distort+wavef.xy*refScale;
+		
+	vec4 fb = texture2D(screenTex, distort);
+	
+	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
new file mode 100644
index 0000000000..4c361884a5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -0,0 +1,258 @@
+/** 
+ * @file waterF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+// class3/environment/waterF.glsl
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+
+// PBR interface
+vec3 pbrIbl(vec3 diffuseColor,
+    vec3 specularColor,
+    vec3 radiance, // radiance map sample
+    vec3 irradiance, // irradiance map sample
+    float ao,       // ambient occlusion factor
+    float nv,       // normal dot view vector
+    float perceptualRoughness);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+    float perceptualRoughness,
+    float metallic,
+    vec3 n, // normal
+    vec3 v, // surface point to camera
+    vec3 l); //surface point to light
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float     blend_factor;
+uniform sampler2D screenTex;
+uniform sampler2D screenDepth;
+
+uniform sampler2D refTex;
+
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec4 waterFogColor;
+
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+in vec3 vary_position;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+in vec3 vary_light_dir;
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+    vec3 n = mix(bump1, bump2, blend_factor);
+    return n;
+}
+
+vec3 srgb_to_linear(vec3 col);
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+    vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
+vec3 vN, vT, vB;
+
+vec3 transform_normal(vec3 vNt)
+{
+    return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+    vec3 pos, vec3 norm, float glossiness);
+
+vec3 getPositionWithNDC(vec3 ndc);
+
+void main() 
+{
+	vec4 color;
+
+    vN = vary_normal;
+    vT = vary_tangent;
+    vB = cross(vN, vT);
+
+    vec3 pos = vary_position.xyz;
+
+	float dist = length(pos.xyz);
+	
+	//normalize view vector
+	vec3 viewVec = normalize(pos.xyz);
+	
+	//get wave normals
+    vec2 bigwave = vec2(refCoord.w, view.w);
+    vec3 wave1_a = texture(bumpMap, bigwave, -2      ).xyz*2.0-1.0;
+    vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+    vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+    vec3 wave1_b = texture(bumpMap2, bigwave      ).xyz*2.0-1.0;
+    vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+    vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+    vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+    vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+    vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+    wave1 = transform_normal(wave1);
+    wave2 = transform_normal(wave2);
+    wave3 = transform_normal(wave3);
+
+    vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+
+    //wavef.z *= max(-viewVec.z, 0.1);
+
+    wavef = normalize(wavef);
+
+	//get base fresnel components	
+	
+	vec3 df = vec3(
+					dot(viewVec, wave1),
+					dot(viewVec, (wave2 + wave3) * 0.5),
+					dot(viewVec, wave3)
+				 ) * fresnelScale + fresnelOffset;
+		    
+	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+	
+	float dist2 = dist;
+	dist = max(dist, 5.0);
+	
+	float dmod = sqrt(dist);
+	
+	vec2 dmod_scale = vec2(dmod*dmod, dmod);
+	
+    float df1 = df.x + df.y + df.z;
+
+    //wavef = normalize(wavef - vary_normal);
+    //wavef = vary_normal;
+
+    vec3 waver = reflect(viewVec, -wavef)*3;
+
+	//figure out distortion vector (ripply)   
+    vec2 distort2 = distort + waver.xy * refScale / max(dmod * df1, 1.0);
+    distort2 = clamp(distort2, vec2(0), vec2(0.99));
+ 
+    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));
+
+    if (refPos.z > pos.z-0.05)
+    {
+        //we sampled an above water sample, don't distort
+        distort2 = distort;
+        fb = texture2D(screenTex, distort2);
+        depth = texture2D(screenDepth, distort2).r;
+        refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
+    }
+
+    fb = applyWaterFogViewLinear(refPos, fb);
+
+    vec3 sunlit;
+    vec3 amblit;
+    vec3 additive;
+    vec3 atten;
+
+    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+    sunlit = vec3(1); // TODO -- figure out why sunlit is breaking at some view angles
+    vec3 v = -viewVec;
+    float NdotV = clamp(abs(dot(wavef.xyz, v)), 0.001, 1.0);
+
+    float metallic = fresnelOffset * 0.1; // fudge -- use fresnelOffset as metalness
+    float roughness = 0.1;
+    float gloss = 1.0 - roughness;
+
+    vec3 baseColor = vec3(0.25);
+    vec3 f0 = vec3(0.04);
+    vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
+    diffuseColor *= gloss;
+
+    vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+    vec3 refnorm = normalize(wavef + vary_normal);
+    //vec3 refnorm = wavef;
+    
+    vec3 irradiance = vec3(0);
+    vec3 radiance = vec3(0);
+    sampleReflectionProbes(irradiance, radiance, pos, refnorm, gloss);
+    radiance *= 0.5;
+    irradiance = fb.rgb;
+
+    color.rgb = pbrIbl(diffuseColor, specularColor, radiance, irradiance, gloss, NdotV, 0.0);
+    
+    // fudge -- for punctual lighting, pretend water is metallic
+    diffuseColor = vec3(0);
+    specularColor = vec3(1);
+    roughness = 0.1;
+    float scol = 1.0; // TODO -- incorporate shadow map
+
+    //color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
+
+    //get specular component
+    float spec = clamp(dot(vary_light_dir, (reflect(viewVec, wavef))), 0.0, 1.0);
+
+    //harden specular
+    spec = pow(spec, 128.0);
+
+    color.rgb += spec * specular;
+
+	color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+	color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+    color.a = 0.f;
+    //color.rgb = fb.rgb;
+    //color.rgb = vec3(depth*depth*depth*depth);
+    //color.rgb = srgb_to_linear(normalize(refPos) * 0.5 + 0.5);
+    //color.rgb = srgb_to_linear(normalize(pos) * 0.5 + 0.5);
+    //color.rgb = srgb_to_linear(wavef * 0.5 + 0.5);
+
+    //color.rgb = radiance;
+	frag_color = color;
+
+#if defined(WATER_EDGE)
+    gl_FragDepth = 0.9999847f;
+#endif
+	
+}
+
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 05978e1144..d4c93eec06 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -505,7 +505,7 @@ void LLViewerShaderMgr::setShaders()
     S32 obj_class = 2;
     S32 effect_class = 2;
     S32 wl_class = 1;
-    S32 water_class = 2;
+    S32 water_class = 3;
     S32 deferred_class = 0;
 
     if (useRenderDeferred)
-- 
cgit v1.2.3