From 4abf39c968c31a9da943a53434388102b99d487f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 10 Jan 2023 11:42:12 -0600
Subject: [PATCH] SL-18869 Optimizations -- Bring back water plane clipping for
 above/below water where applicable.

---
 indra/newview/lldrawpoolalpha.cpp | 29 +++++++++++++++++++++++++++++
 indra/newview/pipeline.cpp        | 27 ++++++++++++++++++++++++---
 indra/newview/pipeline.h          |  4 +++-
 3 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 3ce2ced2558..07381acd257 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -600,6 +600,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
         begin = gPipeline.beginAlphaGroups();
         end = gPipeline.endAlphaGroups();
     }
+    
+    LLEnvironment& env = LLEnvironment::instance();
+    F32 water_height = env.getWaterHeight();
+
+    bool above_water = getType() == LLDrawPool::POOL_ALPHA_POST_WATER;
+    if (LLPipeline::sUnderWaterRender)
+    {
+        above_water = !above_water;
+    }
+
 
     for (LLCullResult::sg_iterator i = begin; i != end; ++i)
 	{
@@ -611,6 +621,25 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 		if (group->getSpatialPartition()->mRenderByGroup &&
 		    !group->isDead())
 		{
+
+            LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
+            const LLVector4a* ext = bridge ? bridge->getSpatialExtents() : group->getExtents();
+
+            if (above_water)
+            { // reject any spatial groups that have no part above water
+                if (ext[1].getF32ptr()[2] < water_height)
+                {
+                    continue;
+                }
+            }
+            else
+            { // reject any spatial groups that he no part below water
+                if (ext[0].getF32ptr()[2] > water_height)
+                {
+                    continue;
+                }
+            }
+
             static std::vector<LLDrawInfo*> emissives;
             static std::vector<LLDrawInfo*> rigged_emissives;
             emissives.resize(0);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b5271a6ca12..5e585852f4d 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2335,13 +2335,34 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
 
 static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
 
-void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep)
+void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
 
-    if (planep != nullptr)
+    bool water_clip = !sRenderTransparentWater;
+
+    if (water_clip)
     {
-        camera.setUserClipPlane(*planep);
+        
+        LLVector3 pnorm;
+
+        F32 water_height = LLEnvironment::instance().getWaterHeight();
+
+        if (sUnderWaterRender)
+        {
+            //camera is below water, cull above water
+            pnorm.setVec(0, 0, 1);
+        }
+        else
+        {
+            //camera is above water, cull below water
+            pnorm = LLVector3(0, 0, -1);
+        }
+        
+        LLPlane plane;
+        plane.setVec(LLVector3(0, 0, water_height), pnorm);
+
+        camera.setUserClipPlane(plane);
     }
     else
     {
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index ae4ac4c7ff8..d3793da3477 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -243,7 +243,9 @@ class LLPipeline
 	bool visibleObjectsInFrustum(LLCamera& camera);
 	bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
 	bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
-	void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL);  //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
+
+    // Populate given LLCullResult with results of a frustum cull of the entire scene against the given LLCamera
+	void updateCull(LLCamera& camera, LLCullResult& result);
 	void createObjects(F32 max_dtime);
 	void createObject(LLViewerObject* vobj);
 	void processPartitionQ();
-- 
GitLab