From c85bb7846d270ba23c447c1b0073cd238d5fd1bc Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 19 Jul 2023 12:52:36 -0500
Subject: [PATCH] DRTVWR-559 Fix for shadows not respecting double sided on
 opaque PBR surfaces

---
 indra/newview/lldrawpool.cpp | 82 ++++++++++++++++++++++++++++++++++++
 indra/newview/lldrawpool.h   | 21 ++++++++-
 indra/newview/pipeline.cpp   | 24 ++++++++++-
 indra/newview/pipeline.h     |  3 +-
 4 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index a9f35b33608..fca0f1c978b 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -696,6 +696,18 @@ void teardown_texture_matrix(LLDrawInfo& params)
     }
 }
 
+void LLRenderPass::pushGLTFBatches(U32 type, bool textured)
+{
+    if (textured)
+    {
+        pushGLTFBatches(type);
+    }
+    else
+    {
+        pushRiggedGLTFBatches(type);
+    }
+}
+
 void LLRenderPass::pushGLTFBatches(U32 type)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -711,6 +723,21 @@ void LLRenderPass::pushGLTFBatches(U32 type)
     }
 }
 
+void LLRenderPass::pushUntexturedGLTFBatches(U32 type)
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    auto* begin = gPipeline.beginRenderMap(type);
+    auto* end = gPipeline.endRenderMap(type);
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+    {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
+        LLDrawInfo& params = **i;
+        LLCullResult::increment_iterator(i, end);
+
+        pushUntexturedGLTFBatch(params);
+    }
+}
+
 void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
 {
     auto& mat = params.mGLTFMaterial;
@@ -729,6 +756,30 @@ void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
     teardown_texture_matrix(params);
 }
 
+void LLRenderPass::pushUntexturedGLTFBatch(LLDrawInfo& params)
+{
+    auto& mat = params.mGLTFMaterial;
+
+    LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+    applyModelMatrix(params);
+
+    params.mVertexBuffer->setBuffer();
+    params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+}
+
+void LLRenderPass::pushRiggedGLTFBatches(U32 type, bool textured)
+{
+    if (textured)
+    {
+        pushRiggedGLTFBatches(type);
+    }
+    else
+    {
+        pushUntexturedRiggedGLTFBatches(type);
+    }
+}
+
 void LLRenderPass::pushRiggedGLTFBatches(U32 type)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -747,6 +798,25 @@ void LLRenderPass::pushRiggedGLTFBatches(U32 type)
     }
 }
 
+void LLRenderPass::pushUntexturedRiggedGLTFBatches(U32 type)
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    LLVOAvatar* lastAvatar = nullptr;
+    U64 lastMeshId = 0;
+
+    auto* begin = gPipeline.beginRenderMap(type);
+    auto* end = gPipeline.endRenderMap(type);
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+    {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
+        LLDrawInfo& params = **i;
+        LLCullResult::increment_iterator(i, end);
+
+        pushUntexturedRiggedGLTFBatch(params, lastAvatar, lastMeshId);
+    }
+}
+
+
 void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
 {
     if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
@@ -759,3 +829,15 @@ void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvat
     pushGLTFBatch(params);
 }
 
+void LLRenderPass::pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
+{
+    if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
+    {
+        uploadMatrixPalette(params);
+        lastAvatar = params.mAvatar;
+        lastMeshId = params.mSkinInfo->mHash;
+    }
+
+    pushUntexturedGLTFBatch(params);
+}
+
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index d5ef734c4b9..5414dba6bf5 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -356,10 +356,29 @@ class LLRenderPass : public LLDrawPool
 
     void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false);
     void pushUntexturedRiggedBatches(U32 type);
+
+    // push full GLTF batches
+    // assumes draw infos of given type have valid GLTF materials
     void pushGLTFBatches(U32 type);
-    void pushGLTFBatch(LLDrawInfo& params);
+
+    // like pushGLTFBatches, but will not bind textures or set up texture transforms
+    void pushUntexturedGLTFBatches(U32 type);
+
+    // helper function for dispatching to textured or untextured pass based on bool
+    void pushGLTFBatches(U32 type, bool textured);
+
+
+    // rigged variants of above
     void pushRiggedGLTFBatches(U32 type);
+    void pushRiggedGLTFBatches(U32 type, bool textured);
+    void pushUntexturedRiggedGLTFBatches(U32 type);
+
+    // push a single GLTF draw call
+    void pushGLTFBatch(LLDrawInfo& params);
     void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+    void pushUntexturedGLTFBatch(LLDrawInfo& params);
+    void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+
 	void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
     void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
 	void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d50e671e059..14025910154 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6494,6 +6494,25 @@ void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool
 	gGLLastMatrix = NULL;		
 }
 
+void LLPipeline::renderGLTFObjects(U32 type, bool texture, bool rigged)
+{
+    assertInitialized();
+    gGL.loadMatrix(gGLModelView);
+    gGLLastMatrix = NULL;
+
+    if (rigged)
+    {
+        mSimplePool->pushRiggedGLTFBatches(type + 1, texture);
+    }
+    else
+    {
+        mSimplePool->pushGLTFBatches(type, texture);
+    }
+
+    gGL.loadMatrix(gGLModelView);
+    gGLLastMatrix = NULL;
+}
+
 // Currently only used for shadows -Cosmic,2023-04-19
 void LLPipeline::renderAlphaObjects(bool rigged)
 {
@@ -8601,8 +8620,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
         LLRenderPass::PASS_NORMMAP,
         LLRenderPass::PASS_NORMMAP_EMISSIVE,
         LLRenderPass::PASS_NORMSPEC,
-        LLRenderPass::PASS_NORMSPEC_EMISSIVE,
-        LLRenderPass::PASS_GLTF_PBR
+        LLRenderPass::PASS_NORMSPEC_EMISSIVE
     };
 
     LLGLEnable cull(GL_CULL_FACE);
@@ -8665,6 +8683,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
             renderObjects(type, false, false, rigged);
         }
 
+        renderGLTFObjects(LLRenderPass::PASS_GLTF_PBR, false, rigged);
+
         gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
     }
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c0559ce83bc..427240aad72 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -284,7 +284,8 @@ class LLPipeline
 	void forAllVisibleDrawables(void (*func)(LLDrawable*));
 
     void renderObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
-
+    void renderGLTFObjects(U32 type, bool texture = true, bool rigged = false);
+    
     void renderAlphaObjects(bool rigged = false);
 	void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
     void renderFullbrightMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
-- 
GitLab