From 0e91d18da3f203bcef681d3134b736978114c2bd Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Mon, 5 Feb 2024 15:36:42 -0600
Subject: #677 Add mirror clipping to rigged shaders

---
 .../shaders/class1/deferred/materialV.glsl         |   2 -
 indra/newview/llenvironment.cpp                    |   6 +-
 indra/newview/llviewershadermgr.cpp                | 118 +++++++++++++--------
 indra/newview/llviewershadermgr.h                  |   5 +-
 4 files changed, 83 insertions(+), 48 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 41112bce30..ddf878ae60 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -78,9 +78,7 @@ void main()
 
 	vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
 
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 	vary_position = pos;
-#endif
 
 	gl_Position = projection_matrix*vec4(pos,1.0);
 
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 60c2682078..affea3f69c 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1675,8 +1675,6 @@ void LLEnvironment::update(const LLViewerCamera * cam)
 
     updateSettingsUniforms();
 
-    // *TODO: potential optimization - this block may only need to be
-    // executed some of the time.  For example for water shaders only.
     {
         LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
         end_shaders = LLViewerShaderMgr::instance()->endShaders();
@@ -1687,6 +1685,10 @@ void LLEnvironment::update(const LLViewerCamera * cam)
                 || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
             {
                 shaders_iter->mUniformsDirty = TRUE;
+                if (shaders_iter->mRiggedVariant)
+                {
+                    shaders_iter->mRiggedVariant->mUniformsDirty = TRUE;
+                }
             }
         }
     }
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 1fecf90c1f..164b36af65 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -104,7 +104,6 @@ LLGLSLShader		gObjectPreviewProgram;
 LLGLSLShader        gSkinnedObjectPreviewProgram;
 LLGLSLShader        gPhysicsPreviewProgram;
 LLGLSLShader		gObjectFullbrightAlphaMaskProgram;
-LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;
 LLGLSLShader		gObjectBumpProgram;
 LLGLSLShader        gSkinnedObjectBumpProgram;
 LLGLSLShader		gObjectAlphaMaskNoColorProgram;
@@ -226,7 +225,7 @@ LLGLSLShader            gDeferredSkinnedPBRAlphaProgram;
 LLGLSLShader			gDeferredPBRTerrainProgram;
 
 //helper for making a rigged variant of a given shader
-bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
+static bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
 {
     riggedShader.mName = llformat("Skinned %s", shader.mName.c_str());
     riggedShader.mFeatures = shader.mFeatures;
@@ -241,73 +240,94 @@ bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
     return riggedShader.createShader(NULL, NULL);
 }
 
+static bool no_redundant_shaders(const std::vector<LLGLSLShader*>& shaders)
+{
+    std::set<std::string> names;
+    for (LLGLSLShader* shader : shaders)
+    {
+        if (names.find(shader->mName) != names.end())
+        {
+            LL_WARNS("Shader") << "Redundant shader: " << shader->mName << LL_ENDL;
+            return false;
+        }
+        names.insert(shader->mName);
+
+        if (shader->mRiggedVariant)
+        {
+            if (names.find(shader->mRiggedVariant->mName) != names.end())
+            {
+                LL_WARNS("Shader") << "Redundant shader: " << shader->mRiggedVariant->mName << LL_ENDL;
+                return false;
+            }
+            names.insert(shader->mRiggedVariant->mName);
+        }
+    }
+    return true;
+}
+
+
 LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderLevel(SHADER_COUNT, 0),
 	mMaxAvatarShaderLevel(0)
 {   
+}
+
+LLViewerShaderMgr::~LLViewerShaderMgr()
+{
+	mShaderLevel.clear();
+	mShaderList.clear();
+}
+
+void LLViewerShaderMgr::finalizeShaderList()
+{
     //ONLY shaders that need WL Param management should be added here
-	mShaderList.push_back(&gAvatarProgram);
-	mShaderList.push_back(&gWaterProgram);
-	mShaderList.push_back(&gWaterEdgeProgram);
-	mShaderList.push_back(&gAvatarEyeballProgram); 
-	mShaderList.push_back(&gImpostorProgram);
-	mShaderList.push_back(&gObjectBumpProgram);
-    mShaderList.push_back(&gSkinnedObjectBumpProgram);
-	mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
-    mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
-	mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
-	mShaderList.push_back(&gUnderWaterProgram);
-	mShaderList.push_back(&gDeferredSunProgram);
+    mShaderList.push_back(&gAvatarProgram);
+    mShaderList.push_back(&gWaterProgram);
+    mShaderList.push_back(&gWaterEdgeProgram);
+    mShaderList.push_back(&gAvatarEyeballProgram);
+    mShaderList.push_back(&gImpostorProgram);
+    mShaderList.push_back(&gObjectBumpProgram);
+    mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
+    mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
+    mShaderList.push_back(&gUnderWaterProgram);
+    mShaderList.push_back(&gDeferredSunProgram);
     mShaderList.push_back(&gHazeProgram);
     mShaderList.push_back(&gHazeWaterProgram);
-	mShaderList.push_back(&gDeferredSoftenProgram);
-	mShaderList.push_back(&gDeferredAlphaProgram);
+    mShaderList.push_back(&gDeferredSoftenProgram);
+    mShaderList.push_back(&gDeferredAlphaProgram);
     mShaderList.push_back(&gHUDAlphaProgram);
-    mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
-	mShaderList.push_back(&gDeferredAlphaImpostorProgram);
-    mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
-	mShaderList.push_back(&gDeferredFullbrightProgram);
+    mShaderList.push_back(&gDeferredAlphaImpostorProgram);
+    mShaderList.push_back(&gDeferredFullbrightProgram);
     mShaderList.push_back(&gHUDFullbrightProgram);
-	mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
+    mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram);
     mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
-	mShaderList.push_back(&gDeferredFullbrightShinyProgram);
+    mShaderList.push_back(&gDeferredFullbrightShinyProgram);
     mShaderList.push_back(&gHUDFullbrightShinyProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
-	mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
-	mShaderList.push_back(&gDeferredEmissiveProgram);
-    mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
-	mShaderList.push_back(&gDeferredAvatarEyesProgram);
-	mShaderList.push_back(&gDeferredAvatarAlphaProgram);
-	mShaderList.push_back(&gDeferredWLSkyProgram);
-	mShaderList.push_back(&gDeferredWLCloudProgram);
+    mShaderList.push_back(&gDeferredEmissiveProgram);
+    mShaderList.push_back(&gDeferredAvatarEyesProgram);
+    mShaderList.push_back(&gDeferredAvatarAlphaProgram);
+    mShaderList.push_back(&gDeferredWLSkyProgram);
+    mShaderList.push_back(&gDeferredWLCloudProgram);
     mShaderList.push_back(&gDeferredWLMoonProgram);
     mShaderList.push_back(&gDeferredWLSunProgram);
     mShaderList.push_back(&gDeferredPBRAlphaProgram);
     mShaderList.push_back(&gHUDPBRAlphaProgram);
-    mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
     mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
     mShaderList.push_back(&gNoPostGammaCorrectProgram);
     mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
     mShaderList.push_back(&gDeferredDiffuseProgram);
-    mShaderList.push_back(&gObjectBumpProgram);
     mShaderList.push_back(&gDeferredBumpProgram);
     mShaderList.push_back(&gDeferredPBROpaqueProgram);
-    mShaderList.push_back(&gDeferredPBRAlphaProgram);
     mShaderList.push_back(&gDeferredAvatarProgram);
     mShaderList.push_back(&gDeferredTerrainProgram);
     mShaderList.push_back(&gDeferredDiffuseAlphaMaskProgram);
     mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram);
     mShaderList.push_back(&gDeferredTreeProgram);
-}
 
-LLViewerShaderMgr::~LLViewerShaderMgr()
-{
-	mShaderLevel.clear();
-	mShaderList.clear();
+    // make sure there are no redundancies 
+    llassert(no_redundant_shaders(mShaderList));
 }
 
 // static
@@ -362,6 +382,8 @@ void LLViewerShaderMgr::setShaders()
         return;
     }
 
+    mShaderList.clear();
+
     LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors;
 
     if (!gGLManager.mHasRequirements)
@@ -545,6 +567,8 @@ void LLViewerShaderMgr::setShaders()
     }
     gPipeline.createGLBuffers();
 
+    finalizeShaderList();
+
     reentrance = false;
 }
 
@@ -1077,9 +1101,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	{
 		if (success)
 		{
-            mShaderList.push_back(&gDeferredMaterialProgram[i]);
+            bool has_skin = i & 0x10;
 
-			gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
+            if (!has_skin)
+            {
+                mShaderList.push_back(&gDeferredMaterialProgram[i]);
+                gDeferredMaterialProgram[i].mName = llformat("Material Shader %d", i);
+            }
+            else
+            {
+                gDeferredMaterialProgram[i].mName = llformat("Skinned Material Shader %d", i);
+            }
 			
 			U32 alpha_mode = i & 0x3;
 
@@ -1116,7 +1148,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
                 gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
             }
 
-            bool has_skin = i & 0x10;
+            
             gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
             gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
             gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 21c8d2089b..9b4583cacf 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -41,6 +41,10 @@ public:
 	LLViewerShaderMgr();
 	/* virtual */ ~LLViewerShaderMgr();
 
+    // Add shaders to mShaderList for later uniform propagation
+    // Will assert on redundant shader entries in debug builds
+    void finalizeShaderList();
+
 	// singleton pattern implementation
 	static LLViewerShaderMgr * instance();
 	static void releaseInstance();
@@ -172,7 +176,6 @@ extern LLGLSLShader			gOneTextureFilterProgram;
 //object shaders
 extern LLGLSLShader		gObjectPreviewProgram;
 extern LLGLSLShader        gPhysicsPreviewProgram;
-extern LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;
 extern LLGLSLShader		gObjectBumpProgram;
 extern LLGLSLShader        gSkinnedObjectBumpProgram;
 extern LLGLSLShader		gObjectAlphaMaskNoColorProgram;
-- 
cgit v1.2.3