From 001f2915ea24a030b9a6fb26a3ecbeedee6402bc Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Mon, 6 Nov 2023 16:15:52 -0600
Subject: SL-20570 Fix for lossy (and square) normal maps when importing GLTF
 materials.

---
 indra/newview/llmaterialeditor.cpp | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 7a65231a2d..5be1aa08ab 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1622,17 +1622,9 @@ static void pack_textures(
 
     if (normal_img)
     {
-        normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img);
-
-        LLPointer<LLImageJ2C> test;
-        test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true);
-
-        S32 lossy_bytes = normal_j2c->getDataSize();
-        S32 lossless_bytes = test->getDataSize();
-
-        LL_DEBUGS("MaterialEditor") << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL;
-
-        normal_j2c = test;
+        // create a losslessly compressed version of the normal map
+        normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 1024, false, true);
+        LL_DEBUGS("MaterialEditor") << "Normal: " << normal_j2c->getDataSize() << LL_ENDL;
     }
 
     if (mr_img)
-- 
cgit v1.2.3


From e7b71cd8a10898320cf3e0aebc05bfdec3d2ffa3 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 8 Nov 2023 11:50:46 -0600
Subject: SL-20582 Fix for overriding to alpha mode blend not working. 
 Incidental decruft of dead code (thanks, Rye!)

---
 indra/llprimitive/llgltfmaterial.cpp |  1 +
 indra/llprimitive/llprimitive.cpp    | 36 ------------------------------------
 indra/llprimitive/llprimitive.h      |  5 +----
 3 files changed, 2 insertions(+), 40 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index f42c11ee21..c1f2a04154 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -715,6 +715,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
     if (am.isInteger())
     {
         mAlphaMode = (AlphaMode) am.asInteger();
+        mOverrideAlphaMode = true;
     }
 
     const LLSD& ac = data["ac"];
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 350d84ae6c..904747af2d 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -2376,42 +2376,6 @@ void LLRenderMaterialParams::copy(const LLNetworkData& data)
     mEntries = param.mEntries;
 }
 
-LLSD LLRenderMaterialParams::asLLSD() const
-{
-    LLSD ret;
-
-    for (int i = 0; i < mEntries.size(); ++i)
-    {
-        ret[i]["te_idx"] = mEntries[i].te_idx;
-        ret[i]["id"] = mEntries[i].id;
-    }
-
-    return ret;
-}
-
-bool LLRenderMaterialParams::fromLLSD(LLSD& sd)
-{
-    if (sd.isArray())
-    {
-        mEntries.resize(sd.size());
-        for (int i = 0; i < sd.size(); ++i)
-        {
-            if (sd[i].has("te_idx") && sd.has("id"))
-            {
-                mEntries[i].te_idx = sd[i]["te_idx"].asInteger();
-                mEntries[i].id = sd[i]["id"].asUUID();
-            }
-            else
-            {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    return false;
-}
 
 void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id)
 {
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index d2adfa4a3d..0b7dbd703a 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -382,10 +382,7 @@ public:
     BOOL unpack(LLDataPacker& dp) override;
     bool operator==(const LLNetworkData& data) const override;
     void copy(const LLNetworkData& data) override;
-    LLSD asLLSD() const;
-    operator LLSD() const { return asLLSD(); }
-    bool fromLLSD(LLSD& sd);
-
+    
     void setMaterial(U8 te_idx, const LLUUID& id);
     const LLUUID& getMaterial(U8 te_idx) const;
 
-- 
cgit v1.2.3


From de844bfce11ea46d428d775d377460db8a2cf54b Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Tue, 7 Nov 2023 23:20:40 +0200
Subject: SL-20569 Notify user when reflection probe can't be selected

---
 indra/newview/llpanelvolume.cpp                      | 17 +++++++++++++++++
 indra/newview/skins/default/xui/en/notifications.xml | 13 +++++++++++++
 2 files changed, 30 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index d6c36bbfb7..d47383b29a 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -746,6 +746,21 @@ void LLPanelVolume::sendIsLight()
 	LL_INFOS() << "update light sent" << LL_ENDL;
 }
 
+void notify_cant_select_reflection_probe()
+{
+    static bool show_notification = true;
+    if (show_notification)
+    {
+        // show only once per session if not ignored
+        show_notification = false;
+        if (!gSavedSettings.getBOOL("SelectReflectionProbes"))
+        {
+            LLNotificationsUtil::add("CantSelectReflectionProbe");
+        }
+        // else: user used the setting, don't show again this session
+    }
+}
+
 void LLPanelVolume::sendIsReflectionProbe()
 {
     LLViewerObject* objectp = mObject;
@@ -764,6 +779,7 @@ void LLPanelVolume::sendIsReflectionProbe()
     }
     else
     {
+        notify_cant_select_reflection_probe();
         volobjp->setIsReflectionProbe(value);
     }
 }
@@ -780,6 +796,7 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS
         }
         LLVOVolume* volobjp = (LLVOVolume*)objectp;
 
+        notify_cant_select_reflection_probe();
         volobjp->setIsReflectionProbe(true);
 
         { // has become a reflection probe, slam to a 10m sphere and pop up a message
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d1838fc7ef..16fc79b77d 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7013,6 +7013,19 @@ Please try again.
     Not connected to a materials capable region.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="CantSelectReflectionProbe"
+   type="alertmodal">
+    <unique/>
+    You have placed a reflection probe, but option for selecting reflection probes is disabled. To be able to select reflection probes enable Build &gt; Options &gt; Select Reflection Probes.
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Don't show again."
+     name="okignore"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="notifytip.tga"
    name="ScriptMissing"
-- 
cgit v1.2.3


From 901de39ca791253d59b60d311d99c0432e0179a5 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Wed, 8 Nov 2023 02:05:33 +0200
Subject: SL-20569 Notify user when reflection probe can't be selected #2

---
 indra/newview/llpanelvolume.cpp                      | 19 ++-----------------
 indra/newview/skins/default/xui/en/notifications.xml |  2 +-
 2 files changed, 3 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index d47383b29a..b1d3ac2245 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -746,21 +746,6 @@ void LLPanelVolume::sendIsLight()
 	LL_INFOS() << "update light sent" << LL_ENDL;
 }
 
-void notify_cant_select_reflection_probe()
-{
-    static bool show_notification = true;
-    if (show_notification)
-    {
-        // show only once per session if not ignored
-        show_notification = false;
-        if (!gSavedSettings.getBOOL("SelectReflectionProbes"))
-        {
-            LLNotificationsUtil::add("CantSelectReflectionProbe");
-        }
-        // else: user used the setting, don't show again this session
-    }
-}
-
 void LLPanelVolume::sendIsReflectionProbe()
 {
     LLViewerObject* objectp = mObject;
@@ -779,7 +764,7 @@ void LLPanelVolume::sendIsReflectionProbe()
     }
     else
     {
-        notify_cant_select_reflection_probe();
+        LLNotificationsUtil::add("CantSelectReflectionProbe");
         volobjp->setIsReflectionProbe(value);
     }
 }
@@ -796,7 +781,7 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS
         }
         LLVOVolume* volobjp = (LLVOVolume*)objectp;
 
-        notify_cant_select_reflection_probe();
+        LLNotificationsUtil::add("CantSelectReflectionProbe");
         volobjp->setIsReflectionProbe(true);
 
         { // has become a reflection probe, slam to a 10m sphere and pop up a message
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 16fc79b77d..6c841ac049 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7018,7 +7018,7 @@ Please try again.
    name="CantSelectReflectionProbe"
    type="alertmodal">
     <unique/>
-    You have placed a reflection probe, but option for selecting reflection probes is disabled. To be able to select reflection probes enable Build &gt; Options &gt; Select Reflection Probes.
+    You have placed a reflection probe, but 'Select Reflection Probes' is disabled. To be able to select reflection probes, check Build &gt; Options &gt; Select Reflection Probes.
     <tag>confirm</tag>
     <usetemplate
      ignoretext="Don't show again."
-- 
cgit v1.2.3


From b3384a057d9556b2429a9c5847e8e1240103585a Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 9 Nov 2023 00:39:34 +0200
Subject: SL-20228 When a reflection probe is unchecked in a link set, it
 should stop being phantom

---
 indra/newview/llpanelvolume.cpp | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index b1d3ac2245..f58aab3080 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -764,7 +764,20 @@ void LLPanelVolume::sendIsReflectionProbe()
     }
     else
     {
-        LLNotificationsUtil::add("CantSelectReflectionProbe");
+        if (value)
+        {
+            LLNotificationsUtil::add("CantSelectReflectionProbe");
+        }
+        else if (objectp->flagPhantom())
+        {
+            LLViewerObject* root = objectp->getRootEdit();
+            bool in_linkeset = root != objectp || objectp->numChildren() > 0;
+            if (in_linkeset)
+            {
+                // In linkset with a phantom flag
+                objectp->setFlags(FLAGS_PHANTOM, FALSE);
+            }
+        }
         volobjp->setIsReflectionProbe(value);
     }
 }
@@ -1213,6 +1226,17 @@ void LLPanelVolume::onPasteLight()
         }
         else
         {
+            if (objectp->flagPhantom())
+            {
+                LLViewerObject* root = objectp->getRootEdit();
+                bool in_linkeset = root != objectp || objectp->numChildren() > 0;
+                if (in_linkeset)
+                {
+                    // In linkset with a phantom flag
+                    objectp->setFlags(FLAGS_PHANTOM, FALSE);
+                }
+            }
+
             volobjp->setIsReflectionProbe(false);
         }
     }
-- 
cgit v1.2.3


From 711354c2f526421b7cd2918f584731624a9995e5 Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Thu, 2 Nov 2023 09:55:44 -0700
Subject: SL-20553: Save material button in build floater now depends on agent
 inventory rather than object inventory

---
 indra/newview/llmaterialeditor.cpp | 92 +++++++++++++++++++++++++++++++++-----
 indra/newview/llpanelface.cpp      | 65 ++++++++++++++++++++++++---
 indra/newview/llpanelface.h        |  6 ++-
 3 files changed, 142 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 5be1aa08ab..bae4afb7e6 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -38,6 +38,7 @@
 #include "llgltfmateriallist.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
+#include "llinventoryfunctions.h"
 #include "lllocalgltfmaterials.h"
 #include "llnotificationsutil.h"
 #include "lltexturectrl.h"
@@ -1796,8 +1797,49 @@ void LLMaterialEditor::loadLive()
     }
 }
 
+namespace
+{
+    // Which inventory to consult for item permissions
+    enum class ItemSource
+    {
+        // Consult the permissions of the item in the object's inventory. If
+        // the item is not present, then usage of the asset is allowed.
+        OBJECT,
+        // Consult the permissions of the item in the agent's inventory. If
+        // the item is not present, then usage of the asset is not allowed.
+        AGENT
+    };
+
+    class LLAssetIDMatchesWithPerms : public LLInventoryCollectFunctor
+    {
+    public:
+        LLAssetIDMatchesWithPerms(const LLUUID& asset_id, const std::vector<PermissionBit>& ops) : mAssetID(asset_id), mOps(ops) {}
+        virtual ~LLAssetIDMatchesWithPerms() {}
+        bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+        {
+            if (!item || item->getAssetUUID() != mAssetID)
+            {
+                return false;
+            }
+            LLPermissions item_permissions = item->getPermissions();
+            for (PermissionBit op : mOps)
+            {
+                if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+    protected:
+        LLUUID mAssetID;
+        std::vector<PermissionBit> mOps;
+    };
+};
+
 // *NOTE: permissions_out includes user preferences for new item creation (LLFloaterPerms)
-bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<PermissionBit>& ops, LLPermissions& permissions_out, LLViewerInventoryItem*& item_out)
+bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<PermissionBit>& ops, const ItemSource item_source, LLPermissions& permissions_out, LLViewerInventoryItem*& item_out)
 {
     if (!LLMaterialEditor::capabilitiesAvailable())
     {
@@ -1830,19 +1872,45 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
         }
     }
 
-    item_out = selected_object->getInventoryItemByAsset(func.mMaterialId);
-
-    LLPermissions item_permissions;
-    if (item_out)
+    // Look for the item to base permissions off of
+    item_out = nullptr;
+    if (func.mMaterialId != LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID)
     {
-        item_permissions.set(item_out->getPermissions());
-        for (PermissionBit op : ops)
+        LLAssetIDMatchesWithPerms item_has_perms(func.mMaterialId, ops);
+        if (item_source == ItemSource::OBJECT)
         {
-            if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE))
+            item_out = selected_object->getInventoryItemByAsset(func.mMaterialId);
+            if (item_out && !item_has_perms(nullptr, item_out))
             {
                 return false;
             }
         }
+        else
+        {
+            llassert(item_source == ItemSource::AGENT);
+
+            LLViewerInventoryCategory::cat_array_t cats;
+            LLViewerInventoryItem::item_array_t items;
+            gInventory.collectDescendentsIf(LLUUID::null,
+                                    cats,
+                                    items,
+                                    // *NOTE: PBRPickerAgentListener will need
+                                    // to be changed if checking the trash is
+                                    // disabled
+                                    LLInventoryModel::INCLUDE_TRASH,
+                                    item_has_perms);
+            if (items.empty())
+            {
+                return false;
+            }
+            item_out = items[0];
+        }
+    }
+
+    LLPermissions item_permissions;
+    if (item_out)
+    {
+        item_permissions = item_out->getPermissions();
         // Update flags for new owner
         if (!item_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true))
         {
@@ -1913,7 +1981,7 @@ bool LLMaterialEditor::canModifyObjectsMaterial()
     LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item_out;
-    return can_use_objects_material(func, std::vector({PERM_MODIFY}), permissions, item_out);
+    return can_use_objects_material(func, std::vector({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out);
 }
 
 bool LLMaterialEditor::canSaveObjectsMaterial()
@@ -1921,7 +1989,7 @@ bool LLMaterialEditor::canSaveObjectsMaterial()
     LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item_out;
-    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item_out);
+    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out);
 }
 
 bool LLMaterialEditor::canClipboardObjectsMaterial()
@@ -1947,7 +2015,7 @@ bool LLMaterialEditor::canClipboardObjectsMaterial()
     LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item_out;
-    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), permissions, item_out);
+    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out);
 }
 
 void LLMaterialEditor::saveObjectsMaterialAs()
@@ -1955,7 +2023,7 @@ void LLMaterialEditor::saveObjectsMaterialAs()
     LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item = nullptr;
-    bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item);
+    bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item);
     if (!allowed)
     {
         LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 9150b89de3..02c00e7f87 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1880,15 +1880,55 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 	}
 }
 
+// One-off listener that updates the build floater UI when the agent inventory adds or removes an item
+class PBRPickerAgentListener : public LLInventoryObserver
+{
+protected:
+    bool mChangePending = true;
+public:
+	PBRPickerAgentListener() : LLInventoryObserver()
+    {
+        gInventory.addObserver(this);
+    }
+
+    const bool isListening()
+    {
+        return mChangePending;
+    }
+
+	void changed(U32 mask) override
+    {
+        if (!(mask & (ADD | REMOVE)))
+        {
+            return;
+        }
+
+        if (gFloaterTools)
+        {
+            gFloaterTools->dirty();
+        }
+        gInventory.removeObserver(this);
+        mChangePending = false;
+    }
+
+    ~PBRPickerAgentListener() override
+    {
+        gInventory.removeObserver(this);
+        mChangePending = false;
+
+        LLInventoryObserver::~LLInventoryObserver();
+    }
+};
+
 // One-off listener that updates the build floater UI when the prim inventory updates
-class PBRPickerItemListener : public LLVOInventoryListener
+class PBRPickerObjectListener : public LLVOInventoryListener
 {
 protected:
     LLViewerObject* mObjectp;
     bool mChangePending = true;
 public:
 
-    PBRPickerItemListener(LLViewerObject* object)
+    PBRPickerObjectListener(LLViewerObject* object)
     : mObjectp(object)
     {
         registerVOInventoryListener(mObjectp, nullptr);
@@ -1912,7 +1952,7 @@ public:
         mChangePending = false;
     }
 
-    ~PBRPickerItemListener()
+    ~PBRPickerObjectListener()
     {
         removeVOInventoryListener();
         mChangePending = false;
@@ -1931,9 +1971,9 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
 
     // pbr material
     LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+    LLUUID pbr_id;
     if (pbr_ctrl)
     {
-        LLUUID pbr_id;
         LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr, has_pbr_material, has_faces_without_pbr);
 
         pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
@@ -1956,14 +1996,25 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
     if (objectp->isInventoryPending())
     {
         // Reuse the same listener when possible
-        if (!mInventoryListener || !mInventoryListener->isListeningFor(objectp))
+        if (!mVOInventoryListener || !mVOInventoryListener->isListeningFor(objectp))
         {
-            mInventoryListener = std::make_unique<PBRPickerItemListener>(objectp);
+            mVOInventoryListener = std::make_unique<PBRPickerObjectListener>(objectp);
         }
     }
     else
     {
-        mInventoryListener = nullptr;
+        mVOInventoryListener = nullptr;
+    }
+    if (!identical_pbr || pbr_id.isNull() || pbr_id == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID)
+    {
+        mAgentInventoryListener = nullptr;
+    }
+    else
+    {
+        if (!mAgentInventoryListener || !mAgentInventoryListener->isListening())
+        {
+            mAgentInventoryListener = std::make_unique<PBRPickerAgentListener>();
+        }
     }
 
     const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index d36662c11b..5ca6a95699 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -53,7 +53,8 @@ class LLMaterialID;
 class LLMediaCtrl;
 class LLMenuButton;
 
-class PBRPickerItemListener;
+class PBRPickerAgentListener;
+class PBRPickerObjectListener;
 
 // Represents an edit for use in replicating the op across one or more materials in the selection set.
 //
@@ -508,7 +509,8 @@ private:
 
     static Selection sMaterialOverrideSelection;
 
-    std::unique_ptr<PBRPickerItemListener> mInventoryListener;
+    std::unique_ptr<PBRPickerAgentListener> mAgentInventoryListener;
+    std::unique_ptr<PBRPickerObjectListener> mVOInventoryListener;
 
 public:
 	#if defined(DEF_GET_MAT_STATE)
-- 
cgit v1.2.3


From 2d69611c470e8ca0f85f6ad5857799ca2536f193 Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Fri, 3 Nov 2023 09:57:19 -0700
Subject: SL-20553: Fix save material to inventory not working with new
 agent-based permissions

---
 indra/newview/llmaterialeditor.cpp | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index bae4afb7e6..cc7e69d60c 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1852,6 +1852,10 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
     llassert(func.mIsOverride);
     LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/);
 
+    if (item_source == ItemSource::AGENT)
+    {
+        func.mObjectId = LLUUID::null;
+    }
     LLViewerObject* selected_object = func.mObject;
     if (!selected_object)
     {
@@ -1879,11 +1883,12 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
         LLAssetIDMatchesWithPerms item_has_perms(func.mMaterialId, ops);
         if (item_source == ItemSource::OBJECT)
         {
-            item_out = selected_object->getInventoryItemByAsset(func.mMaterialId);
-            if (item_out && !item_has_perms(nullptr, item_out))
+            LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId);
+            if (item && !item_has_perms(nullptr, item))
             {
                 return false;
             }
+            item_out = item;
         }
         else
         {
@@ -2118,8 +2123,9 @@ void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_materi
     }
     else
     {
-        if (item_id.notNull())
+        if (item_id.notNull() && object_id.notNull())
         {
+            llassert(false); // *TODO: Remove this code path if unused
             // Copy existing item from object inventory, and create new composite asset on top of it
             LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback, _1, _2, permissions, object_id, item_id));
         }
-- 
cgit v1.2.3


From ee8b96f3ef55d10f5b84e368c052692a362ebcbc Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Fri, 3 Nov 2023 13:49:47 -0700
Subject: SL-20553: Clean up dead code

---
 indra/newview/llmaterialeditor.cpp  | 58 ++---------------------------------
 indra/newview/llmaterialeditor.h    |  1 -
 indra/newview/llviewerinventory.cpp | 61 -------------------------------------
 indra/newview/llviewerinventory.h   |  5 ---
 4 files changed, 2 insertions(+), 123 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index cc7e69d60c..958925c9e4 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -2123,63 +2123,9 @@ void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_materi
     }
     else
     {
-        if (item_id.notNull() && object_id.notNull())
-        {
-            llassert(false); // *TODO: Remove this code path if unused
-            // Copy existing item from object inventory, and create new composite asset on top of it
-            LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback, _1, _2, permissions, object_id, item_id));
-        }
-        else
-        {
-            LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, permissions));
-        }
-    }
-}
-
-// static
-void LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id)
-{
-    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-    if (0 != option)
-    {
-        return;
+        llassert(object_id.isNull()); // Case for copying item from object inventory is no longer implemented
+        LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, permissions));
     }
-
-    LLSD asset;
-    asset["version"] = LLGLTFMaterial::ASSET_VERSION;
-    asset["type"] = LLGLTFMaterial::ASSET_TYPE;
-    // This is the string serialized from LLGLTFMaterial::asJSON
-    asset["data"] = notification["payload"]["data"];
-
-    std::ostringstream str;
-    LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
-
-    LLViewerObject* object = gObjectList.findObject(object_id);
-    if (!object)
-    {
-        return;
-    }
-    const LLInventoryItem* item = object->getInventoryItem(item_id);
-    if (!item)
-    {
-        return;
-    }
-
-    std::string new_name = response["message"].asString();
-    LLInventoryObject::correctInventoryName(new_name);
-    if (new_name.empty())
-    {
-        return;
-    }
-
-    const LLUUID destination_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
-
-    LLPointer<LLInventoryCallback> cb = new LLObjectsMaterialItemCallback(permissions, str.str(), new_name);
-    // NOTE: This should be an item copy. Saving a material to an inventory should be disabled when the associated material is no-copy.
-    move_or_copy_inventory_from_object(destination_id,
-                                       object_id,
-                                       item_id,
-                                       cb);
 }
 
 // static
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
index 1c40fcc348..2e25a9ca3d 100644
--- a/indra/newview/llmaterialeditor.h
+++ b/indra/newview/llmaterialeditor.h
@@ -116,7 +116,6 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
     static bool canSaveObjectsMaterial();
     static bool canClipboardObjectsMaterial();
     static void saveObjectsMaterialAs();
-    static void onCopyObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id);
     static void onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions);
 
     static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 5ee613d49d..1b70e5f84f 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1658,67 +1658,6 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
     }
 }
 
-void move_or_copy_inventory_from_object(const LLUUID& destination_id,
-                                        const LLUUID& object_id,
-                                        const LLUUID& item_id,
-                                        LLPointer<LLInventoryCallback> cb)
-{
-    LLViewerObject* object = gObjectList.findObject(object_id);
-    if (!object)
-    {
-        return;
-    }
-    const LLInventoryItem* item = object->getInventoryItem(item_id);
-    if (!item)
-    {
-        return;
-    }
-
-    class LLItemAddedObserver : public LLInventoryObserver
-    {
-    public:
-        LLItemAddedObserver(const LLUUID& copied_asset_id, LLPointer<LLInventoryCallback> cb)
-        : LLInventoryObserver(),
-          mAssetId(copied_asset_id),
-          mCallback(cb)
-        {
-        }
-
-        void changed(U32 mask) override
-        {
-            if((mask & (LLInventoryObserver::ADD)) == 0)
-            {
-                return;
-            }
-            for (const LLUUID& changed_id : gInventory.getChangedIDs())
-            {
-                LLViewerInventoryItem* changed_item = gInventory.getItem(changed_id);
-                if (changed_item->getAssetUUID() == mAssetId)
-                {
-                    changeComplete(changed_item->getUUID());
-                    return;
-                }
-            }
-        }
-
-    private:
-        void changeComplete(const LLUUID& item_id)
-        {
-			mCallback->fire(item_id);
-            gInventory.removeObserver(this);
-            delete this;
-        }
-
-        LLUUID mAssetId;
-        LLPointer<LLInventoryCallback> mCallback;
-    };
-
-	const LLUUID& asset_id = item->getAssetUUID();
-    LLItemAddedObserver* observer = new LLItemAddedObserver(asset_id, cb);
-    gInventory.addObserver(observer);
-    object->moveInventory(destination_id, item_id);
-}
-
 void create_new_item(const std::string& name,
 				   const LLUUID& parent_id,
 				   LLAssetType::EType asset_type,
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index bce8da0a69..e043285ffb 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -463,11 +463,6 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
 								  const LLInventoryItem *src,
 								  U32 callback_id = 0);
 
-void move_or_copy_inventory_from_object(const LLUUID& destination_id,
-                                        const LLUUID& object_id,
-                                        const LLUUID& item_id,
-                                        LLPointer<LLInventoryCallback> cb);
-
 void menu_create_inventory_item(LLInventoryPanel* root,
 								LLFolderBridge* bridge,
 								const LLSD& userdata,
-- 
cgit v1.2.3


From 6ba5954d66523cedf5e69928e223f9820bd141ac Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Fri, 3 Nov 2023 13:54:05 -0700
Subject: SL-20553: Permissions touch-up

---
 indra/newview/llmaterialeditor.cpp | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 958925c9e4..2f31889f32 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1968,13 +1968,24 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
     // creation history when there's no material item present. In that case,
     // the agent who saved the material will be considered the creator.
     // -Cosmic,2023-08-07
-    if (item_out)
+    if (item_source == ItemSource::AGENT)
     {
+        llassert(item_out);
+
         permissions_out.set(item_permissions);
     }
     else
     {
-        permissions_out.set(object_permissions);
+        llassert(item_source == ItemSource::OBJECT);
+
+        if (item_out)
+        {
+            permissions_out.set(item_permissions);
+        }
+        else
+        {
+            permissions_out.set(object_permissions);
+        }
     }
     permissions_out.accumulate(floater_perm);
 
-- 
cgit v1.2.3


From 0d50f29697f999c91a4bed702b9bae281b247250 Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Tue, 7 Nov 2023 17:33:00 -0800
Subject: SL-20553: Fix inventory item not updating with correct permission
 label in UI

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

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 74a5442586..ca13b9eb03 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1465,6 +1465,10 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 		{
 			mask |= LLInventoryObserver::LABEL;
 		}
+        if (old_item->getPermissions() != item->getPermissions())
+        {
+            mask |= LLInventoryObserver::INTERNAL;
+        }
 		old_item->copyViewerItem(item);
 		if (update_parent_on_server)
 		{
-- 
cgit v1.2.3


From 4ad7e250f3302a6158378a5acbf88ac27dd95ced Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Wed, 8 Nov 2023 14:51:48 -0800
Subject: SL-20553: Fix assert

---
 indra/newview/llmaterialeditor.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 2f31889f32..2f4c29446e 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1878,7 +1878,8 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
 
     // Look for the item to base permissions off of
     item_out = nullptr;
-    if (func.mMaterialId != LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID)
+    const bool blank_material = func.mMaterialId == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+    if (!blank_material)
     {
         LLAssetIDMatchesWithPerms item_has_perms(func.mMaterialId, ops);
         if (item_source == ItemSource::OBJECT)
@@ -1970,7 +1971,7 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
     // -Cosmic,2023-08-07
     if (item_source == ItemSource::AGENT)
     {
-        llassert(item_out);
+        llassert(blank_material || item_out); // See comment at ItemSource::AGENT definition
 
         permissions_out.set(item_permissions);
     }
-- 
cgit v1.2.3


From a66a990165a2ade9cba26963fe0c7b4a21b9dcac Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Wed, 8 Nov 2023 16:23:36 -0800
Subject: SL-20553: Fix new material item still sometimes not updating in UI

---
 indra/newview/llmaterialeditor.cpp | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 2f4c29446e..8f016b9125 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1313,16 +1313,22 @@ public:
             return;
         }
 
+        // Name may or may not have already been applied
+        const bool changed_name = item->getName() != mNewName;
         // create_inventory_item/copy_inventory_item don't allow presetting some permissions, fix it now
-        item->setPermissions(mPermissions);
-        item->updateServer(FALSE);
-        gInventory.updateItem(item);
-        gInventory.notifyObservers();
-
-        if (item->getName() != mNewName)
+        const bool changed_permissions = item->getPermissions() != mPermissions;
+        const bool changed = changed_name || changed_permissions;
+        LLSD updates;
+        if (changed)
         {
-            LLSD updates;
-            updates["name"] = mNewName;
+            if (changed_name)
+            {
+                updates["name"] = mNewName;
+            }
+            if (changed_permissions)
+            {
+                updates["permissions"] = ll_create_sd_from_permissions(mPermissions);
+            }
             update_inventory_item(inv_item_id, updates, NULL);
         }
 
@@ -1332,10 +1338,16 @@ public:
                 inv_item_id,
                 LLAssetType::AT_MATERIAL,
                 mAssetData,
-                [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response)
+                [changed, updates](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response)
                 {
                     // done callback
                     LL_INFOS("Material") << "inventory item uploaded.  item: " << item_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL;
+
+                    // *HACK: Sometimes permissions do not stick in the UI. They are correct on the server-side, though.
+                    if (changed)
+                    {
+                        update_inventory_item(new_item_id, updates, NULL);
+                    }
                 },
                 nullptr // failure callback, floater already closed
             );
-- 
cgit v1.2.3


From 8d538ef77b395e2f8ba6d4f89c2633dd57124c04 Mon Sep 17 00:00:00 2001
From: cosmic-linden <111533034+cosmic-linden@users.noreply.github.com>
Date: Tue, 14 Nov 2023 08:06:45 -0800
Subject: SL-18343: Simple interim GLTF material preview - base color only
 (#511)

---
 indra/newview/llfetchedgltfmaterial.cpp | 54 +++++++++++++++++++++++++++++++++
 indra/newview/llfetchedgltfmaterial.h   |  5 +++
 indra/newview/lltexturectrl.cpp         | 36 +++++++++++++++++-----
 3 files changed, 87 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index fc9d42bfb6..b6d62d1d12 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -29,6 +29,8 @@
 
 #include "llviewertexturelist.h"
 #include "llavatarappearancedefines.h"
+#include "llviewerobject.h"
+#include "llselectmgr.h"
 #include "llshadermgr.h"
 #include "pipeline.h"
 
@@ -175,3 +177,55 @@ void LLFetchedGLTFMaterial::materialComplete()
     materialCompleteCallbacks.clear();
     materialCompleteCallbacks.shrink_to_fit();
 }
+
+LLPointer<LLViewerFetchedTexture> LLFetchedGLTFMaterial::getUITexture()
+{
+    if (mFetching)
+    {
+        return nullptr;
+    }
+
+    auto fetch_texture_for_ui = [](LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
+    {
+        if (id.notNull())
+        {
+            if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+            {
+                LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+                if (obj)
+                {
+                    LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
+                    img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+                }
+
+            }
+            else
+            {
+                img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+            }
+        }
+        if (img)
+        {
+            img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+            img->forceToSaveRawImage(0);
+        }
+    };
+
+    fetch_texture_for_ui(mBaseColorTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+    fetch_texture_for_ui(mNormalTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+    fetch_texture_for_ui(mMetallicRoughnessTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+    fetch_texture_for_ui(mEmissiveTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+
+    if ((mBaseColorTexture && (mBaseColorTexture->getRawImageLevel() != 0)) ||
+        (mNormalTexture && (mNormalTexture->getRawImageLevel() != 0)) ||
+        (mMetallicRoughnessTexture && (mMetallicRoughnessTexture->getRawImageLevel() != 0)) ||
+        (mEmissiveTexture && (mEmissiveTexture->getRawImageLevel() != 0)))
+    {
+        return nullptr;
+    }
+
+    // *HACK: Use one of the PBR texture components as the preview texture for now
+    mPreviewTexture = mBaseColorTexture;
+
+    return mPreviewTexture;
+}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 1668657281..eb9639723a 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -50,12 +50,17 @@ public:
 
     bool isFetching() const { return mFetching; }
 
+    LLPointer<LLViewerFetchedTexture> getUITexture();
+
     // Textures used for fetching/rendering
     LLPointer<LLViewerFetchedTexture> mBaseColorTexture;
     LLPointer<LLViewerFetchedTexture> mNormalTexture;
     LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;
     LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
 
+    // Texture used for previewing the material in the UI
+    LLPointer<LLViewerFetchedTexture> mPreviewTexture;
+
 protected:
     // Lifetime management
     
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 10667b02d9..50e2f5e1d9 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -719,17 +719,27 @@ void LLFloaterTexturePicker::draw()
 
 		// If the floater is focused, don't apply its alpha to the texture (STORM-677).
 		const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
-		if( mTexturep )
+        LLViewerTexture* texture = nullptr;
+        if (mGLTFMaterial)
+        {
+            texture = mGLTFMaterial->getUITexture();
+        }
+        else
+        {
+            texture = mTexturep.get();
+        }
+
+		if( texture )
 		{
-			if( mTexturep->getComponents() == 4 )
+			if( texture->getComponents() == 4 )
 			{
 				gl_rect_2d_checkerboard( interior, alpha );
 			}
 
-			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha );
+			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), texture, UI_VERTEX_COLOR % alpha );
 
 			// Pump the priority
-			mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+			texture->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
 		}
 		else if (!mFallbackImage.isNull())
 		{
@@ -2131,11 +2141,21 @@ void LLTextureCtrl::draw()
 
 		if (texture.isNull())
 		{
-			texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+            if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+            {
+                LLPointer<LLFetchedGLTFMaterial> material = gGLTFMaterialList.getMaterial(mImageAssetID);
+                if (material)
+                {
+                    texture = material->getUITexture();
+                }
+            }
+            else
+            {
+                texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+                texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+                texture->forceToSaveRawImage(0);
+            }
 		}
-		
-		texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
-		texture->forceToSaveRawImage(0) ;
 
 		mTexturep = texture;
 	}
-- 
cgit v1.2.3


From 0edb7cad6bdeaf02cbd89d1f2dd38c47d6078c03 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Tue, 14 Nov 2023 13:33:11 -0600
Subject: SL-20340 Fix for off-by-epsilon hack falling off when serializing
 overrides as LLSD. (#513)

---
 indra/llprimitive/llgltfmaterial.cpp | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

(limited to 'indra')

diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index c1f2a04154..9945c230a2 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -691,24 +691,44 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
     if (bc.isDefined())
     {
         mBaseColor.setValue(bc);
+        if (mBaseColor == getDefaultBaseColor())
+        {
+            // HACK -- nudge by epsilon if we receive a default value (indicates override to default)
+            mBaseColor.mV[3] -= FLT_EPSILON;
+        }
     }
 
     const LLSD& ec = data["ec"];
     if (ec.isDefined())
     {
         mEmissiveColor.setValue(ec);
+        if (mEmissiveColor == getDefaultEmissiveColor())
+        {
+            // HACK -- nudge by epsilon if we receive a default value (indicates override to default)
+            mEmissiveColor.mV[0] += FLT_EPSILON;
+        }
     }
 
     const LLSD& mf = data["mf"];
     if (mf.isReal())
     {
         mMetallicFactor = mf.asReal();
+        if (mMetallicFactor == getDefaultMetallicFactor())
+        { 
+            // HACK -- nudge by epsilon if we receive a default value (indicates override to default)
+            mMetallicFactor -= FLT_EPSILON;
+        }
     }
 
     const LLSD& rf = data["rf"];
     if (rf.isReal())
     {
         mRoughnessFactor = rf.asReal();
+        if (mRoughnessFactor == getDefaultRoughnessFactor())
+        { 
+            // HACK -- nudge by epsilon if we receive a default value (indicates override to default)
+            mRoughnessFactor -= FLT_EPSILON;
+        }
     }
 
     const LLSD& am = data["am"];
@@ -722,6 +742,11 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
     if (ac.isReal())
     {
         mAlphaCutoff = ac.asReal();
+        if (mAlphaCutoff == getDefaultAlphaCutoff())
+        {
+            // HACK -- nudge by epsilon if we receive a default value (indicates override to default)
+            mAlphaCutoff -= FLT_EPSILON;
+        }
     }
 
     const LLSD& ds = data["ds"];
-- 
cgit v1.2.3


From f98fa678205a4575ea2590994c863527c29c2ab9 Mon Sep 17 00:00:00 2001
From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com>
Date: Thu, 16 Nov 2023 10:18:42 +0100
Subject: SL-20563 Add 'No Post' option to Snapshot floater

---
 indra/newview/llfloatersnapshot.cpp                    | 18 ++++++++++++++++--
 indra/newview/llfloatersnapshot.h                      |  1 +
 .../newview/skins/default/xui/en/floater_snapshot.xml  | 12 ++++++++++--
 indra/newview/skins/default/xui/en/menu_viewer.xml     |  2 +-
 4 files changed, 28 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 6b9d4580dc..4806fe9625 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -461,8 +461,8 @@ void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data
 {
 	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
 	gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
-	
-	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;		
+
+	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;
 	if (view)
 	{
 		view->impl->checkAutoSnapshot(view->getPreviewView());
@@ -470,6 +470,17 @@ void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data
 	}
 }
 
+// static
+void LLFloaterSnapshotBase::ImplBase::onClickNoPost(LLUICtrl *ctrl, void* data)
+{
+    BOOL no_post = ((LLCheckBoxCtrl*)ctrl)->get();
+    gSavedSettings.setBOOL("RenderDisablePostProcessing", no_post);
+
+    LLFloaterSnapshotBase* view = (LLFloaterSnapshotBase*)data;
+    view->getPreviewView()->updateSnapshot(TRUE, TRUE);
+    view->impl->updateControls(view);
+}
+
 // static
 void LLFloaterSnapshotBase::ImplBase::onClickFilter(LLUICtrl *ctrl, void* data)
 {
@@ -997,6 +1008,9 @@ BOOL LLFloaterSnapshot::postBuild()
 	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
 	childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
 
+    getChild<LLUICtrl>("no_post_check")->setValue(gSavedSettings.getBOOL("RenderDisablePostProcessing"));
+    childSetCommitCallback("no_post_check", ImplBase::onClickNoPost, this);
+
     getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
     getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
 
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 7fc62a2746..89cb2bc809 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -100,6 +100,7 @@ public:
 
 	static void onClickNewSnapshot(void* data);
 	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
+	static void onClickNoPost(LLUICtrl *ctrl, void* data);
 	static void onClickFilter(LLUICtrl *ctrl, void* data);
 	static void onClickUICheck(LLUICtrl *ctrl, void* data);
 	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index fcd24d83bb..0866594625 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -115,7 +115,7 @@
 	   top_delta="0"
        width="31" />
 	<panel
-     height="159"
+     height="179"
      layout="topleft"
 	 follows="top|left"
      left="0"
@@ -193,6 +193,14 @@
          top_pad="1"
          width="180"
          name="auto_snapshot_check" />
+        <check_box
+         label="No post-processing"
+         layout="topleft"
+         height="16"
+         left="10"
+         top_pad="1"
+         width="180"
+         name="no_post_check" />
         <text
          type="string"
          length="1"
@@ -233,7 +241,7 @@
     </panel>
 	<panel_container
      follows="left|top"
-     height="230"
+     height="210"
      layout="topleft"
      left="0"
      name="panel_container"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 0bfdead6e7..2c4b03251a 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1545,7 +1545,7 @@ function="World.EnvPreset"
         <menu_item_separator/>
           
           <menu_item_check
-            label="No Post"
+            label="No Post-processing"
             name="No Post">
             <menu_item_check.on_check
              control="RenderDisablePostProcessing" />
-- 
cgit v1.2.3


From bdb53fd56d56c659941e7e63f83cefc366acef6d Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Thu, 16 Nov 2023 16:46:12 -0600
Subject: SL-20611 Make haze effect local lights -- move sky and water haze to
 their own passes and unify sky and water haze in forward rendering shaders.

---
 indra/llrender/llshadermgr.cpp                     |  20 +-
 .../shaders/class1/deferred/fullbrightF.glsl       |  16 +-
 .../shaders/class1/environment/waterFogF.glsl      |  48 ++-
 .../class1/windlight/atmosphericsHelpersV.glsl     |   1 -
 .../shaders/class1/windlight/atmosphericsV.glsl    |   1 -
 .../class1/windlight/atmosphericsVarsF.glsl        |   2 +-
 .../class1/windlight/atmosphericsVarsV.glsl        |  11 -
 .../class1/windlight/atmosphericsVarsWaterF.glsl   |  50 ---
 .../class1/windlight/atmosphericsVarsWaterV.glsl   |  81 ----
 .../shaders/class2/deferred/alphaF.glsl            |  14 +-
 .../shaders/class2/deferred/pbralphaF.glsl         |  15 +-
 .../shaders/class3/deferred/fullbrightShinyF.glsl  |   3 +
 .../shaders/class3/deferred/hazeF.glsl             | 109 +++++
 .../shaders/class3/deferred/materialF.glsl         |  16 +-
 .../shaders/class3/deferred/softenLightF.glsl      |  34 --
 .../shaders/class3/deferred/waterHazeF.glsl        |  58 +++
 .../shaders/class3/environment/underWaterF.glsl    |   4 +-
 .../shaders/class3/environment/waterF.glsl         |   3 +-
 indra/newview/lldrawpoolalpha.cpp                  |  10 +-
 indra/newview/lldrawpoolavatar.cpp                 |   9 +-
 indra/newview/lldrawpoolmaterials.cpp              |   9 +-
 indra/newview/lldrawpoolsimple.cpp                 |   8 -
 indra/newview/llsettingsvo.cpp                     |   2 +-
 indra/newview/llviewercamera.cpp                   |  59 +--
 indra/newview/llviewershadermgr.cpp                | 441 +++------------------
 indra/newview/llviewershadermgr.h                  |  11 +-
 indra/newview/pipeline.cpp                         |  66 ++-
 27 files changed, 369 insertions(+), 732 deletions(-)
 delete mode 100644 indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
 delete mode 100644 indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
 create mode 100644 indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl

(limited to 'indra')

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 0e7f9e1331..f14216f3d8 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -81,14 +81,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 	if (features->calculatesAtmospherics)
 	{
-		if (features->hasWaterFog)
-		{
-			if (!shader->attachVertexObject("windlight/atmosphericsVarsWaterV.glsl"))
-			{
-				return FALSE;
-			}
-		}
-        else if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl"))
+		if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl"))
 		{
 			return FALSE;
 		}
@@ -201,14 +194,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 
 	if(features->calculatesAtmospherics || features->hasGamma || features->isDeferred)
 	{
-		if (features->hasWaterFog)
-		{
-			if (!shader->attachFragmentObject("windlight/atmosphericsVarsWaterF.glsl"))
-			{
-				return FALSE;
-			}
-		}
-        else if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl"))
+		if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl"))
 		{
 			return FALSE;
 		}
@@ -292,7 +278,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 	}
 	
 	// NOTE order of shader object attaching is VERY IMPORTANT!!!
-	if (features->hasWaterFog)
+	if (features->hasWaterFog || features->hasAtmospherics)
 	{
         if (!shader->attachFragmentObject("environment/waterFogF.glsl"))
 		{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 5d58cc91cd..2798c59f1c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -35,9 +35,7 @@ in vec3 vary_position;
 in vec4 vertex_color;
 in vec2 vary_texcoord0;
 
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 vec3 srgb_to_linear(vec3 cs);
 vec3 linear_to_srgb(vec3 cl);
@@ -86,18 +84,14 @@ void main()
     calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
 #endif
 
-#ifdef WATER_FOG
-    
-    vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha));
-    color.rgb = fogged.rgb;
-    color.a   = fogged.a;
-#else
-    color.a   = final_alpha;
-#endif
 
 #ifndef IS_HUD
     color.rgb = srgb_to_linear(color.rgb);
     color.rgb = atmosFragLighting(color.rgb, additive, atten);
+
+    vec4 fogged = applyWaterFogViewLinear(pos, vec4(color.rgb, final_alpha));
+    color.rgb = fogged.rgb;
+    color.a   = fogged.a;
 #endif
 
     frag_color = max(color, vec4(0));
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index cfdb393b34..140e01cc2a 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -30,12 +30,12 @@ uniform vec4 waterFogColor;
 uniform float waterFogDensity;
 uniform float waterFogKS;
 
-vec3 getPositionEye();
-
 vec3 srgb_to_linear(vec3 col);
 vec3 linear_to_srgb(vec3 col);
 
-vec4 applyWaterFogView(vec3 pos, vec4 color)
+// get a water fog color that will apply the appropriate haze to a color given
+// a blend function of (ONE, SOURCE_ALPHA)
+vec4 getWaterFogViewNoClip(vec3 pos)
 {
     vec3 view = normalize(pos);
     //normalize view vector
@@ -67,38 +67,44 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
     float L = min(t1/t2*t3, 1.0);
     
     float D = pow(0.98, l*kd);
+
+    return vec4(srgb_to_linear(kc.rgb*L), D);
+}
+
+vec4 getWaterFogView(vec3 pos)
+{
+    if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
+    {
+        return vec4(0,0,0,1);
+    }
+
+    return getWaterFogViewNoClip(pos);
+}
+
+vec4 applyWaterFogView(vec3 pos, vec4 color)
+{
+    vec4 fogged = getWaterFogView(pos);
     
-    color.rgb = color.rgb * D + kc.rgb * L;
+    color.rgb = color.rgb * fogged.a + fogged.rgb;
 
     return color;
 }
 
-vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit)
+vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color)
 {
-    color.rgb = linear_to_srgb(color.rgb);
-    color = applyWaterFogView(pos, color);
-    color.rgb = srgb_to_linear(color.rgb);
+    vec4 fogged = getWaterFogViewNoClip(pos);
+    color.rgb *= fogged.a;
+    color.rgb += fogged.rgb;
     return color;
 }
 
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit)
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
 {
     if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
     {
         return color;
     }
 
-    return applyWaterFogViewLinearNoClip(pos, color, sunlit);
-}
-
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
-{
-    return applyWaterFogViewLinear(pos, color, vec3(1));
-}
-
-vec4 applyWaterFog(vec4 color)
-{
-    //normalize view vector
-    return applyWaterFogViewLinear(getPositionEye(), color);
+    return applyWaterFogViewLinearNoClip(pos, color);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index 6ecbfaecb1..4f88aed765 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -30,7 +30,6 @@ vec3 getSunlitColor();
 vec3 getAmblitColor();
 vec3 getAdditiveColor();
 vec3 getAtmosAttenuation();
-vec3 getPositionEye();
 
 uniform float scene_light_strength;
 
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
index cc3617ba61..7b59e07243 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
@@ -42,7 +42,6 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
 
 void calcAtmospherics(vec3 inPositionEye) {
     vec3 P = inPositionEye;
-    setPositionEye(P);
     vec3 tmpsunlit = vec3(1);
     vec3 tmpamblit = vec3(1);
     vec3 tmpaddlit = vec3(1);
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index 34669a6796..9d5f60b313 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -44,5 +44,5 @@ vec3 getAdditiveColor()
 
 vec3 getAtmosAttenuation()
 {
-	return vec3(vary_AtmosAttenuation);
+	return vary_AtmosAttenuation;
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 1b854d80b3..0617bc9908 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -31,7 +31,6 @@ vec3 additive_color;
 vec3 atmos_attenuation;
 vec3 sunlit_color;
 vec3 amblit_color;
-vec3 position_eye;
 
 vec3 getSunlitColor()
 {
@@ -51,16 +50,6 @@ vec3 getAtmosAttenuation()
 	return atmos_attenuation;
 }
 
-vec3 getPositionEye()
-{
-	return position_eye;
-}
-
-void setPositionEye(vec3 v)
-{
-	position_eye = v;
-}
-
 void setSunlitColor(vec3 v)
 {
 	sunlit_color  = v;
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
deleted file mode 100644
index 7a6741fe0e..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/** 
- * @file class2\wl\atmosphericVarsWaterF.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$
- */
- 
-in vec3 vary_PositionEye;
-in vec3 vary_AdditiveColor;
-in vec3 vary_AtmosAttenuation;
-
-vec3 getSunlitColor()
-{
-	return vec3(0,0,0);
-}
-vec3 getAmblitColor()
-{
-	return vec3(0,0,0);
-}
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return vary_AtmosAttenuation;
-}
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
deleted file mode 100644
index 23c3aed4d8..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ /dev/null
@@ -1,81 +0,0 @@
-/** 
- * @file class2\wl\atmosphericVarsWaterV.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 vec3 vary_PositionEye;
-out vec3 vary_AdditiveColor;
-out vec3 vary_AtmosAttenuation;
-
-vec3 atmos_attenuation;
-vec3 sunlit_color;
-vec3 amblit_color;
-
-vec3 getSunlitColor()
-{
-	return sunlit_color;
-}
-vec3 getAmblitColor()
-{
-	return amblit_color;
-}
-
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return atmos_attenuation;
-}
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-
-void setPositionEye(vec3 v)
-{
-	vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
-	sunlit_color  = v;
-}
-
-void setAmblitColor(vec3 v)
-{
-	amblit_color = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
-	vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
-	atmos_attenuation = v;
-	vary_AtmosAttenuation = v;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index b63f3b60f9..07fa5cd01c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -65,9 +65,7 @@ uniform vec3 light_diffuse[8];
 
 void waterClip(vec3 pos);
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 vec3 srgb_to_linear(vec3 c);
 vec3 linear_to_srgb(vec3 c);
@@ -270,12 +268,6 @@ void main()
 
     color.rgb *= diffuse_linear.rgb;
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-
-#ifdef WATER_FOG
-    color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear);
-#endif // WATER_FOG
-
     vec4 light = vec4(0,0,0,0);
     
    #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
@@ -291,6 +283,10 @@ void main()
     // sum local light contrib in linear colorspace
     color.rgb += light.rgb;
 
+    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+
+    color = applyWaterFogViewLinear(pos.xyz, color);
+
 #endif // #else // FOR_IMPOSTOR
 
 #ifdef IS_HUD
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index 35d752be02..80c1769b15 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -84,9 +84,7 @@ vec3 linear_to_srgb(vec3 c);
 void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
 vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten);
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
 float calcLegacyDistanceAttenuation(float distance, float falloff);
@@ -228,13 +226,6 @@ void main()
 
     color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-    
-#ifdef WATER_FOG
-    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear);
-    color = temp.rgb;
-#endif
-
     vec3 light = vec3(0);
 
     // Punctual lights
@@ -250,7 +241,11 @@ void main()
 
     color.rgb += light.rgb;
 
+    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
     
+    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0));
+    color = temp.rgb;
+
     float a = basecolor.a*vertex_color.a;
     
     frag_color = max(vec4(color.rgb,a), vec4(0));
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
index 5483a4e29c..6446015b03 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -40,6 +40,8 @@ in vec3 vary_position;
 uniform samplerCube environmentMap;
 
 vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+
 void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
 
 vec3 linear_to_srgb(vec3 c);
@@ -84,6 +86,7 @@ void main()
 
     applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
     color.rgb = atmosFragLighting(color.rgb, additive, atten);
+    color = applyWaterFogViewLinear(pos.xyz, color);
 #endif
 
 	color.a = 1.0;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
new file mode 100644
index 0000000000..7b77a2f5fb
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -0,0 +1,109 @@
+/**
+ * @file class3/deferred/hazeF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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 normalMap;
+
+// Inputs
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int  sun_up_factor;
+in vec2 vary_fragcoord;
+
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+
+float getDepth(vec2 pos_screen);
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform vec4 waterPlane;
+
+uniform int cube_snapshot;
+
+uniform float sky_hdr_scale;
+
+void main()
+{
+    vec2  tc           = vary_fragcoord.xy;
+    float depth        = getDepth(tc.xy);
+    vec4  pos          = getPositionWithDepth(tc, depth);
+    vec4  norm         = texture(normalMap, tc);
+    norm.xyz           = getNorm(tc);
+    vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir;
+
+    vec3  color = vec3(0);
+    float bloom = 0.0;
+
+    vec3 sunlit;
+    vec3 amblit;
+    vec3 additive;
+    vec3 atten;
+
+    calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+
+    vec3 sunlit_linear = srgb_to_linear(sunlit);
+    vec3 amblit_linear = amblit;
+
+    bool do_atmospherics = false;
+
+    // mask off atmospherics below water
+    if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
+    {
+        do_atmospherics = true;
+    }
+
+    vec3  irradiance = vec3(0);
+    vec3  radiance  = vec3(0);
+
+    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+    {
+    }
+    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+    {
+        //should only be true of WL sky, just port over base color value
+        discard;
+    }
+
+   float alpha = 0.0;
+
+    if (do_atmospherics)
+    {
+        alpha = atten.r;
+        color = srgb_to_linear(additive*2.0);
+        color *= sky_hdr_scale;
+    }
+    else
+    {
+        color = vec3(0,0,0);
+        alpha = 1.0;
+    }
+
+    frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
+    frag_color.a = alpha;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index acff03ec4b..1880f0c870 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -37,9 +37,7 @@
 uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise
 uniform int sun_up_factor;
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
 vec3 scaleSoftClipFragLinear(vec3 l);
@@ -386,13 +384,6 @@ void main()
         glare += cur_glare;
     }
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); 
-
-#ifdef WATER_FOG
-    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear);
-    color = temp.rgb;
-#endif
-
     vec3 npos = normalize(-pos.xyz);
     vec3 light = vec3(0, 0, 0);
 
@@ -408,6 +399,11 @@ void main()
 
     color += light;
 
+    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); 
+
+    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0));
+    color = temp.rgb;
+
     glare *= 1.0-emissive;
     glare = min(glare, 1.0);
     float al = max(diffcol.a, glare) * vertex_color.a;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 35e99c5bd2..5e8fe9301a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -83,10 +83,6 @@ uniform vec4 waterPlane;
 
 uniform int cube_snapshot;
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
-#endif
-
 uniform float sky_hdr_scale;
 
 void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
@@ -167,18 +163,6 @@ void main()
     vec3 sunlit_linear = srgb_to_linear(sunlit);
     vec3 amblit_linear = amblit;
 
-    bool do_atmospherics = false;
-
-#ifndef WATER_FOG
-    // when above water, mask off atmospherics below water
-    if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
-    {
-        do_atmospherics = true;
-    }
-#else
-    do_atmospherics = true;
-#endif
-
     vec3  irradiance = vec3(0);
     vec3  radiance  = vec3(0);
 
@@ -203,11 +187,6 @@ void main()
 
         vec3 v = -normalize(pos.xyz);
         color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
-        
-        if (do_atmospherics)
-        {
-            color = atmosFragLightingLinear(color, additive, atten);
-        }
     }
     else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
     {
@@ -273,21 +252,8 @@ void main()
         {  // add environment map
             applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
         }
-
-        
-        if (do_atmospherics)
-        {
-            color = atmosFragLightingLinear(color, additive, atten);
-        }
    }
 
-    
-
-    #ifdef WATER_FOG
-        vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
-        color       = fogged.rgb;
-    #endif
-
     frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
     frag_color.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
new file mode 100644
index 0000000000..f63d70cbd7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -0,0 +1,58 @@
+/**
+ * @file class3/deferred/waterHazeF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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;
+
+// Inputs
+in vec2 vary_fragcoord;
+
+uniform sampler2D normalMap;
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+float getDepth(vec2 pos_screen);
+
+vec4 getWaterFogView(vec3 pos);
+
+void main()
+{
+    vec2  tc           = vary_fragcoord.xy;
+    float depth        = getDepth(tc.xy);
+    vec4  pos          = getPositionWithDepth(tc, depth);
+    vec4  norm         = texture(normalMap, tc);
+
+    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+    {
+    }
+    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+    {
+        //should only be true of WL sky, just port over base color value
+        discard;
+    }
+
+    vec4 fogged = getWaterFogView(pos.xyz);
+
+    frag_color.rgb = max(fogged.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
+    frag_color.a = fogged.a;
+}
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index e99ad5b474..924f356f35 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -55,7 +55,7 @@ in vec4 littleWave;
 in vec4 view;
 in vec3 vary_position;
 
-vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit);
+vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color);
 
 void main() 
 {
@@ -77,5 +77,5 @@ void main()
     vec4 fb = vec4(waterFogColorLinear, 0.0);
 #endif
     
-	frag_color = max(applyWaterFogViewLinearNoClip(vary_position, fb, vec3(1)), vec4(0));
+	frag_color = max(applyWaterFogViewLinearNoClip(vary_position, fb), vec4(0));
 }
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index ddade462be..af0460fa8b 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -34,7 +34,7 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
 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, vec3 sunlit);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 // PBR interface
 vec2 BRDF(float NoV, float roughness);
@@ -223,7 +223,6 @@ void main()
         refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
     }
 
-    fb = applyWaterFogViewLinear(refPos, fb, sunlit);
 #else
     vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);
 #endif
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 052a1d796a..41dc95a8cb 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -178,27 +178,24 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
 
     fullbright_shader   = 
         (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
-        (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterAlphaProgram : 
         (LLPipeline::sRenderingHUDs) ? &gHUDFullbrightAlphaMaskAlphaProgram :
         &gDeferredFullbrightAlphaMaskAlphaProgram;
     prepare_alpha_shader(fullbright_shader, true, true, water_sign);
 
     simple_shader   = 
         (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
-        (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : 
         (LLPipeline::sRenderingHUDs) ? &gHUDAlphaProgram :
         &gDeferredAlphaProgram;
 
     prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
 
-    LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+    LLGLSLShader* materialShader = gDeferredMaterialProgram;
     for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
     {
         prepare_alpha_shader(&materialShader[i], false, true, water_sign);
     }
 
     pbr_shader = 
-        (LLPipeline::sUnderWaterRender) ? &gDeferredPBRAlphaWaterProgram : 
         (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram : 
         &gDeferredPBRAlphaProgram;
 
@@ -727,11 +724,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 
                         llassert(mask < LLMaterial::SHADER_COUNT);
                         target_shader = &(gDeferredMaterialProgram[mask]);
-
-                        if (LLPipeline::sUnderWaterRender)
-                        {
-                            target_shader = &(gDeferredMaterialWaterProgram[mask]);
-                        }
                     }
                     else if (!params.mFullbright)
                     {
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 342b76d93b..7f6409dbde 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -509,14 +509,7 @@ void LLDrawPoolAvatar::beginRigid()
 
 	if (gPipeline.shadersLoaded())
 	{
-		if (LLPipeline::sUnderWaterRender)
-		{
-			sVertexProgram = &gObjectAlphaMaskNoColorWaterProgram;
-		}
-		else
-		{
-			sVertexProgram = &gObjectAlphaMaskNoColorProgram;
-		}
+		sVertexProgram = &gObjectAlphaMaskNoColorProgram;
 		
 		if (sVertexProgram != NULL)
 		{	//eyeballs render with the specular shader
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 6a7e05ac74..c0e4ed38c1 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -82,14 +82,7 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
 	
     U32 idx = shader_idx[pass];
     
-    if (LLPipeline::sUnderWaterRender)
-    {
-        mShader = &(gDeferredMaterialWaterProgram[idx]);
-    }
-    else
-    {
-        mShader = &(gDeferredMaterialProgram[idx]);
-    }
+    mShader = &(gDeferredMaterialProgram[idx]);
     
     if (rigged)
     {
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index a89c9d4561..696618f75b 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -193,10 +193,6 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
     {
         shader = &gHUDFullbrightProgram;
     }
-    else if (LLPipeline::sUnderWaterRender)
-    {
-        shader = &gDeferredFullbrightWaterProgram;
-    }
     else
     {
         shader = &gDeferredFullbrightProgram;
@@ -225,10 +221,6 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
     {
         shader = &gHUDFullbrightAlphaMaskProgram;
     }
-    else if (LLPipeline::sUnderWaterRender)
-    {
-        shader = &gDeferredFullbrightAlphaMaskWaterProgram;
-    }
     else
     {
         shader = &gDeferredFullbrightAlphaMaskProgram;
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 42587658a6..2f65f3dec3 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -983,7 +983,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
 
     LLEnvironment& env = LLEnvironment::instance();
 
-    auto group = LLGLSLShader::SG_WATER;
+    auto group = LLGLSLShader::SG_ANY;
     LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group];
     
 	{
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index b37f08283d..b926631ebe 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -50,6 +50,7 @@
 #include "llquaternion.h"
 #include "llwindow.h"			// getPixelAspectRatio()
 #include "lltracerecording.h"
+#include "llenvironment.h"
 
 // System includes
 #include <iomanip> // for setprecision
@@ -96,35 +97,37 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
 	gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
 }
 
-void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
-											const LLVector3 &up_direction,
-											const LLVector3 &point_of_interest)
+void LLViewerCamera::updateCameraLocation(const LLVector3 &center, const LLVector3 &up_direction, const LLVector3 &point_of_interest)
 {
-	// do not update if avatar didn't move
-	if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate())
-	{
-		return;
-	}
-
-	LLVector3 last_position;
-	LLVector3 last_axis;
-	last_position = getOrigin();
-	last_axis = getAtAxis();
-
-	mLastPointOfInterest = point_of_interest;
-
-	LLViewerRegion * regp = gAgent.getRegion();
-	F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
-
-	LLVector3 origin = center;
-	if (origin.mV[2] > water_height)
-	{
-		origin.mV[2] = llmax(origin.mV[2], water_height+0.20f);
-	}
-	else
-	{
-		origin.mV[2] = llmin(origin.mV[2], water_height-0.20f);
-	}
+    // do not update if avatar didn't move
+    if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate())
+    {
+        return;
+    }
+
+    LLVector3 last_position;
+    LLVector3 last_axis;
+    last_position = getOrigin();
+    last_axis     = getAtAxis();
+
+    mLastPointOfInterest = point_of_interest;
+
+    LLViewerRegion *regp         = gAgent.getRegion();
+    F32             water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
+
+    LLVector3 origin = center;
+
+    if (LLEnvironment::instance().getCurrentWater()->getFogMod() != 1.f)
+    {
+        if (origin.mV[2] > water_height)
+        {
+            origin.mV[2] = llmax(origin.mV[2], water_height + 0.20f);
+        }
+        else
+        {
+            origin.mV[2] = llmin(origin.mV[2], water_height - 0.20f);
+        }
+    }
 
 	setOriginAndLookAt(origin, up_direction, point_of_interest);
 
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index cdf5e2875f..e6e80e9532 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -99,7 +99,6 @@ LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;
 LLGLSLShader		gObjectBumpProgram;
 LLGLSLShader        gSkinnedObjectBumpProgram;
 LLGLSLShader		gObjectAlphaMaskNoColorProgram;
-LLGLSLShader		gObjectAlphaMaskNoColorWaterProgram;
 
 //environment shaders
 LLGLSLShader		gWaterProgram;
@@ -138,7 +137,6 @@ LLGLSLShader			gDeferredSkinnedDiffuseProgram;
 LLGLSLShader			gDeferredSkinnedBumpProgram;
 LLGLSLShader			gDeferredBumpProgram;
 LLGLSLShader			gDeferredTerrainProgram;
-LLGLSLShader            gDeferredTerrainWaterProgram;
 LLGLSLShader			gDeferredTreeProgram;
 LLGLSLShader			gDeferredTreeShadowProgram;
 LLGLSLShader            gDeferredSkinnedTreeShadowProgram;
@@ -149,9 +147,10 @@ LLGLSLShader			gDeferredMultiLightProgram[16];
 LLGLSLShader			gDeferredSpotLightProgram;
 LLGLSLShader			gDeferredMultiSpotLightProgram;
 LLGLSLShader			gDeferredSunProgram;
+LLGLSLShader            gHazeProgram;
+LLGLSLShader            gHazeWaterProgram;
 LLGLSLShader			gDeferredBlurLightProgram;
 LLGLSLShader			gDeferredSoftenProgram;
-LLGLSLShader			gDeferredSoftenWaterProgram;
 LLGLSLShader			gDeferredShadowProgram;
 LLGLSLShader            gDeferredSkinnedShadowProgram;
 LLGLSLShader			gDeferredShadowCubeProgram;
@@ -171,8 +170,6 @@ LLGLSLShader			gHUDAlphaProgram;
 LLGLSLShader            gDeferredSkinnedAlphaProgram;
 LLGLSLShader			gDeferredAlphaImpostorProgram;
 LLGLSLShader            gDeferredSkinnedAlphaImpostorProgram;
-LLGLSLShader			gDeferredAlphaWaterProgram;
-LLGLSLShader            gDeferredSkinnedAlphaWaterProgram;
 LLGLSLShader			gDeferredAvatarEyesProgram;
 LLGLSLShader			gDeferredFullbrightProgram;
 LLGLSLShader            gHUDFullbrightProgram;
@@ -180,12 +177,6 @@ LLGLSLShader			gDeferredFullbrightAlphaMaskProgram;
 LLGLSLShader			gHUDFullbrightAlphaMaskProgram;
 LLGLSLShader			gDeferredFullbrightAlphaMaskAlphaProgram;
 LLGLSLShader			gHUDFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader			gDeferredFullbrightWaterProgram;
-LLGLSLShader            gDeferredSkinnedFullbrightWaterProgram;
-LLGLSLShader			gDeferredFullbrightWaterAlphaProgram;
-LLGLSLShader			gDeferredSkinnedFullbrightWaterAlphaProgram;
-LLGLSLShader			gDeferredFullbrightAlphaMaskWaterProgram;
-LLGLSLShader            gDeferredSkinnedFullbrightAlphaMaskWaterProgram;
 LLGLSLShader			gDeferredEmissiveProgram;
 LLGLSLShader            gDeferredSkinnedEmissiveProgram;
 LLGLSLShader			gDeferredPostProgram;
@@ -215,7 +206,6 @@ LLGLSLShader            gDeferredBufferVisualProgram;
 
 // Deferred materials shaders
 LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
 LLGLSLShader			gHUDPBROpaqueProgram;
 LLGLSLShader            gPBRGlowProgram;
 LLGLSLShader            gPBRGlowSkinnedProgram;
@@ -224,8 +214,6 @@ LLGLSLShader            gDeferredSkinnedPBROpaqueProgram;
 LLGLSLShader            gHUDPBRAlphaProgram;
 LLGLSLShader            gDeferredPBRAlphaProgram;
 LLGLSLShader            gDeferredSkinnedPBRAlphaProgram;
-LLGLSLShader            gDeferredPBRAlphaWaterProgram;
-LLGLSLShader            gDeferredSkinnedPBRAlphaWaterProgram;
 
 //helper for making a rigged variant of a given shader
 bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
@@ -258,30 +246,22 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
 	mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
-	mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram);
 	mShaderList.push_back(&gUnderWaterProgram);
 	mShaderList.push_back(&gDeferredSunProgram);
+    mShaderList.push_back(&gHazeProgram);
+    mShaderList.push_back(&gHazeWaterProgram);
 	mShaderList.push_back(&gDeferredSoftenProgram);
-	mShaderList.push_back(&gDeferredSoftenWaterProgram);
 	mShaderList.push_back(&gDeferredAlphaProgram);
     mShaderList.push_back(&gHUDAlphaProgram);
     mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
 	mShaderList.push_back(&gDeferredAlphaImpostorProgram);
     mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
-	mShaderList.push_back(&gDeferredAlphaWaterProgram);
-    mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram);
 	mShaderList.push_back(&gDeferredFullbrightProgram);
     mShaderList.push_back(&gHUDFullbrightProgram);
 	mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram);
     mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
-	mShaderList.push_back(&gDeferredFullbrightWaterProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightWaterProgram);
-    mShaderList.push_back(&gDeferredFullbrightWaterAlphaProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightWaterAlphaProgram);
-	mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
 	mShaderList.push_back(&gDeferredFullbrightShinyProgram);
     mShaderList.push_back(&gHUDFullbrightShinyProgram);
     mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
@@ -291,17 +271,14 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gDeferredEmissiveProgram);
     mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
 	mShaderList.push_back(&gDeferredAvatarEyesProgram);
-    mShaderList.push_back(&gDeferredTerrainWaterProgram);
-	mShaderList.push_back(&gDeferredAvatarAlphaProgram);
+    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(&gDeferredPBRAlphaWaterProgram);
     mShaderList.push_back(&gHUDPBRAlphaProgram);
     mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
-    mShaderList.push_back(&gDeferredSkinnedPBRAlphaWaterProgram);
     mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
     mShaderList.push_back(&gNoPostGammaCorrectProgram);
     mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
@@ -594,7 +571,6 @@ std::string LLViewerShaderMgr::loadBasicShaders()
 
 	vector< pair<string, S32> > shaders;
 	shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl",       mShaderLevel[SHADER_WINDLIGHT] ) );
-	shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl",  mShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl",    mShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "lighting/lightFuncV.glsl",               mShaderLevel[SHADER_LIGHTING] ) );
 	shaders.push_back( make_pair( "lighting/sumLightsV.glsl",               sum_lights_class ) );
@@ -674,7 +650,6 @@ std::string LLViewerShaderMgr::loadBasicShaders()
 
 	std::vector<S32> index_channels;    
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",      mShaderLevel[SHADER_WINDLIGHT] ) );
-	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl",     mShaderLevel[SHADER_WINDLIGHT] ) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl",       mShaderLevel[SHADER_WINDLIGHT] ) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/gammaF.glsl",                 mShaderLevel[SHADER_WINDLIGHT]) );
     index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl",       mShaderLevel[SHADER_WINDLIGHT] ) );
@@ -908,7 +883,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredSkinnedBumpProgram.unload();
 		gDeferredImpostorProgram.unload();
 		gDeferredTerrainProgram.unload();
-		gDeferredTerrainWaterProgram.unload();
 		gDeferredLightProgram.unload();
 		for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
 		{
@@ -919,7 +893,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredSunProgram.unload();
 		gDeferredBlurLightProgram.unload();
 		gDeferredSoftenProgram.unload();
-		gDeferredSoftenWaterProgram.unload();
 		gDeferredShadowProgram.unload();
         gDeferredSkinnedShadowProgram.unload();
 		gDeferredShadowCubeProgram.unload();
@@ -937,20 +910,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAlphaProgram.unload();
         gHUDAlphaProgram.unload();
         gDeferredSkinnedAlphaProgram.unload();
-		gDeferredAlphaWaterProgram.unload();
-        gDeferredSkinnedAlphaWaterProgram.unload();
 		gDeferredFullbrightProgram.unload();
         gHUDFullbrightProgram.unload();
 		gDeferredFullbrightAlphaMaskProgram.unload();
         gHUDFullbrightAlphaMaskProgram.unload();
         gDeferredFullbrightAlphaMaskAlphaProgram.unload();
         gHUDFullbrightAlphaMaskAlphaProgram.unload();
-		gDeferredFullbrightWaterProgram.unload();
-        gDeferredSkinnedFullbrightWaterProgram.unload();
-        gDeferredFullbrightWaterAlphaProgram.unload();
-        gDeferredSkinnedFullbrightWaterAlphaProgram.unload();
-		gDeferredFullbrightAlphaMaskWaterProgram.unload();
-        gDeferredSkinnedFullbrightAlphaMaskWaterProgram.unload();
 		gDeferredEmissiveProgram.unload();
         gDeferredSkinnedEmissiveProgram.unload();
 		gDeferredAvatarEyesProgram.unload();
@@ -984,7 +949,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
 		{
 			gDeferredMaterialProgram[i].unload();
-			gDeferredMaterialWaterProgram[i].unload();
 		}
 
         gHUDPBROpaqueProgram.unload();
@@ -993,8 +957,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredSkinnedPBROpaqueProgram.unload();
         gDeferredPBRAlphaProgram.unload();
         gDeferredSkinnedPBRAlphaProgram.unload();
-        gDeferredPBRAlphaWaterProgram.unload();
-        gDeferredSkinnedPBRAlphaWaterProgram.unload();
 
 		return TRUE;
 	}
@@ -1084,15 +1046,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
 	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
 
-	gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-
 	for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
 	{
 		if (success)
@@ -1158,77 +1111,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
             llassert(success);
 		}
-
-		if (success)
-		{
-            mShaderList.push_back(&gDeferredMaterialWaterProgram[i]);
-
-            gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
-
-            U32 alpha_mode = i & 0x3;
-
-            gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
-            gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
-            gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
-            gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-            gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
-
-            gDeferredMaterialWaterProgram[i].clearPermutations();
-
-            bool has_normal_map   = (i & 0x8) > 0;
-            bool has_specular_map = (i & 0x4) > 0;
-
-            if (has_normal_map)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
-            }
-
-            if (has_specular_map)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
-            }
-
-            gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-            if (alpha_mode != 0)
-            {
-                gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true;
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
-            }
-
-            if (use_sun_shadow)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
-            }
-
-            bool has_skin = i & 0x10;
-            if (has_skin)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1");
-            }
-            else
-            {
-                gDeferredMaterialWaterProgram[i].mRiggedVariant = &(gDeferredMaterialWaterProgram[i + 0x10]);
-            }
-            gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
-
-            gDeferredMaterialWaterProgram[i].mFeatures.hasReflectionProbes = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.calculatesAtmospherics = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true;
-
-            gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = use_sun_shadow;
-            
-            if (has_skin)
-            {
-                gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
-            }
-
-            success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
-            llassert(success);
-		}
 	}
 
 	gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
@@ -1240,15 +1122,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
 	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
 
-	gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-
     if (success)
     {
         gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
@@ -1356,62 +1229,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         shader->mRiggedVariant->mFeatures.hasLighting = true;
     }
 
-    if (success)
-    {
-        LLGLSLShader* shader = &gDeferredPBRAlphaWaterProgram;
-        shader->mName = "Deferred PBR Alpha Underwater Shader";
-                          
-        shader->mFeatures.calculatesLighting = false;
-        shader->mFeatures.hasLighting = false;
-        shader->mFeatures.isAlphaLighting = true;
-        shader->mFeatures.hasWaterFog = true;
-        shader->mFeatures.hasSrgb = true;
-        shader->mFeatures.encodesNormal = true;
-        shader->mFeatures.calculatesAtmospherics = true;
-        shader->mFeatures.hasAtmospherics = true;
-        shader->mFeatures.hasGamma = true;
-        shader->mFeatures.hasShadows = use_sun_shadow;
-        shader->mFeatures.isDeferred = true; // include deferredUtils
-        shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
-
-        shader->mShaderGroup = LLGLSLShader::SG_WATER;
-
-        shader->mShaderFiles.clear();
-        shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
-        shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
-
-        shader->clearPermutations();
-
-        U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
-        shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-        shader->addPermutation("HAS_NORMAL_MAP", "1");
-        shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
-        shader->addPermutation("HAS_EMISSIVE_MAP", "1");
-        shader->addPermutation("USE_VERTEX_COLOR", "1");
-        shader->addPermutation("WATER_FOG", "1");
-
-        if (use_sun_shadow)
-        {
-            shader->addPermutation("HAS_SUN_SHADOW", "1");
-        }
-
-        shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-        success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaWaterProgram);
-        if (success)
-        {
-            success = shader->createShader(NULL, NULL);
-        }
-        llassert(success);
-
-        // Alpha Shader Hack
-        // See: LLRender::syncMatrices()
-        shader->mFeatures.calculatesLighting = true;
-        shader->mFeatures.hasLighting = true;
-
-        shader->mRiggedVariant->mFeatures.calculatesLighting = true;
-        shader->mRiggedVariant->mFeatures.hasLighting = true;
-    }
-
     if (success)
     {
         LLGLSLShader* shader = &gHUDPBRAlphaProgram;
@@ -1737,68 +1554,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         }
     }
 
-    if (success)
-    {
-        LLGLSLShader* shader[] = {
-            &gDeferredAlphaWaterProgram,
-            &gDeferredSkinnedAlphaWaterProgram
-        };
-        
-        gDeferredAlphaWaterProgram.mRiggedVariant = &gDeferredSkinnedAlphaWaterProgram;
-		
-        gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
-        gDeferredSkinnedAlphaWaterProgram.mName = "Deferred Skinned Alpha Underwater Shader";
-
-        for (int i = 0; i < 2 && success; ++i)
-        {
-            shader[i]->mFeatures.calculatesLighting = false;
-            shader[i]->mFeatures.hasLighting = false;
-            shader[i]->mFeatures.isAlphaLighting = true;
-            shader[i]->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
-            shader[i]->mFeatures.hasWaterFog = true;
-            shader[i]->mFeatures.hasSrgb = true;
-            shader[i]->mFeatures.encodesNormal = true;
-            shader[i]->mFeatures.calculatesAtmospherics = true;
-            shader[i]->mFeatures.hasAtmospherics = true;
-            shader[i]->mFeatures.hasGamma = true;
-            shader[i]->mFeatures.hasShadows = use_sun_shadow;
-            shader[i]->mFeatures.hasReflectionProbes = true;
-            shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-            shader[i]->mShaderGroup = LLGLSLShader::SG_WATER;
-            shader[i]->mShaderFiles.clear();
-            shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
-            shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
-
-            shader[i]->clearPermutations();
-            shader[i]->addPermutation("USE_INDEXED_TEX", "1");
-            shader[i]->addPermutation("WATER_FOG", "1");
-            shader[i]->addPermutation("USE_VERTEX_COLOR", "1");
-            shader[i]->addPermutation("HAS_ALPHA_MASK", "1");
-            if (use_sun_shadow)
-            {
-                shader[i]->addPermutation("HAS_SUN_SHADOW", "1");
-            }
-
-            if (i == 1)
-            { // rigged variant
-                shader[i]->mFeatures.hasObjectSkinning = true;
-                shader[i]->addPermutation("HAS_SKIN", "1");
-            }
-            else
-            {
-                shader[i]->mRiggedVariant = shader[1];
-            }
-            shader[i]->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
-            success = shader[i]->createShader(NULL, NULL);
-            llassert(success);
-
-            // Hack
-            shader[i]->mFeatures.calculatesLighting = true;
-            shader[i]->mFeatures.hasLighting = true;
-        }
-	}
-
 	if (success)
 	{
 		gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
@@ -1825,6 +1580,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true;
 		gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
+        gDeferredFullbrightProgram.mFeatures.hasWaterFog = true;
 		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightProgram.mShaderFiles.clear();
 		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
@@ -1860,6 +1616,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;		
+        gDeferredFullbrightAlphaMaskProgram.mFeatures.hasWaterFog = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
 		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
@@ -1933,71 +1690,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         llassert(success);
     }
 
-	if (success)
-	{
-		gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader";
-		gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-		gDeferredFullbrightWaterProgram.mShaderFiles.clear();
-		gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
-		gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
-		gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
-        success = make_rigged_variant(gDeferredFullbrightWaterProgram, gDeferredSkinnedFullbrightWaterProgram);
-		success = success && gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
-		llassert(success);
-	}
-    
-    if (success)
-    {
-        gDeferredFullbrightWaterAlphaProgram.mName = "Deferred Fullbright Underwater Alpha Shader";
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.calculatesAtmospherics = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasGamma = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasAtmospherics = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasWaterFog = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasSrgb = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.isDeferred = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-        gDeferredFullbrightWaterAlphaProgram.mShaderFiles.clear();
-        gDeferredFullbrightWaterAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
-        gDeferredFullbrightWaterAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
-        gDeferredFullbrightWaterAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-        gDeferredFullbrightWaterAlphaProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-        gDeferredFullbrightWaterAlphaProgram.clearPermutations();
-        gDeferredFullbrightWaterAlphaProgram.addPermutation("WATER_FOG", "1");
-        gDeferredFullbrightWaterAlphaProgram.addPermutation("IS_ALPHA", "1");
-        success = make_rigged_variant(gDeferredFullbrightWaterAlphaProgram, gDeferredSkinnedFullbrightWaterAlphaProgram);
-        success = success && gDeferredFullbrightWaterAlphaProgram.createShader(NULL, NULL);
-        llassert(success);
-    }
-
-	if (success)
-	{
-		gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredFullbrightAlphaMaskWaterProgram.clearPermutations();
-		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
-		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
-        success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
-		success = success && gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
-		llassert(success);
-	}
-
 	if (success)
 	{
 		gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
@@ -2084,40 +1776,53 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		llassert(success);
 	}
 
-	if (success)
-	{
-		gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
-		gDeferredSoftenWaterProgram.mShaderFiles.clear();
-		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
-		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
-
-        gDeferredSoftenWaterProgram.clearPermutations();
-		gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
-		gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
-        gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;
-        gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow;
-        gDeferredSoftenWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+    if (success)
+    {
+        gHazeProgram.mName = "Haze Shader";
+        gHazeProgram.mShaderFiles.clear();
+        gHazeProgram.mFeatures.hasSrgb                = true;
+        gHazeProgram.mFeatures.calculatesAtmospherics = true;
+        gHazeProgram.mFeatures.hasAtmospherics        = true;
+        gHazeProgram.mFeatures.hasGamma               = true;
+        gHazeProgram.mFeatures.isDeferred             = true;
+        gHazeProgram.mFeatures.hasShadows             = use_sun_shadow;
+        gHazeProgram.mFeatures.hasReflectionProbes    = mShaderLevel[SHADER_DEFERRED] > 2;
+
+        gHazeProgram.clearPermutations();
+        gHazeProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+        gHazeProgram.mShaderFiles.push_back(make_pair("deferred/hazeF.glsl", GL_FRAGMENT_SHADER));
+
+        gHazeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+        success = gHazeProgram.createShader(NULL, NULL);
+        llassert(success);
+    }
 
-        if (use_sun_shadow)
-        {
-            gDeferredSoftenWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
-        }
 
-		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
-		{ //if using SSAO, take screen space light map into account as if shadows are enabled
-			gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2);
-            gDeferredSoftenWaterProgram.addPermutation("HAS_SSAO", "1");
-		}
+    if (success)
+    {
+        gHazeWaterProgram.mName = "Water Haze Shader";
+        gHazeWaterProgram.mShaderFiles.clear();
+        gHazeWaterProgram.mShaderGroup           = LLGLSLShader::SG_WATER;
+        gHazeWaterProgram.mFeatures.hasWaterFog            = true;
+        gHazeWaterProgram.mFeatures.hasSrgb                = true;
+        gHazeWaterProgram.mFeatures.calculatesAtmospherics = true;
+        gHazeWaterProgram.mFeatures.hasAtmospherics        = true;
+        gHazeWaterProgram.mFeatures.hasGamma               = true;
+        gHazeWaterProgram.mFeatures.isDeferred             = true;
+        gHazeWaterProgram.mFeatures.hasShadows             = use_sun_shadow;
+        gHazeWaterProgram.mFeatures.hasReflectionProbes    = mShaderLevel[SHADER_DEFERRED] > 2;
+
+        gHazeWaterProgram.clearPermutations();
+        gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+        gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeF.glsl", GL_FRAGMENT_SHADER));
+
+        gHazeWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+        success = gHazeWaterProgram.createShader(NULL, NULL);
+        llassert(success);
+    }
 
-		success = gDeferredSoftenWaterProgram.createShader(NULL, NULL);
-		llassert(success);
-	}
 
 	if (success)
 	{
@@ -2277,31 +1982,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		llassert(success);
 	}
 
-	if (success)
-	{
-		gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader";
-		gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true;
-		gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false;
-		gDeferredTerrainWaterProgram.mFeatures.hasLighting = false;
-		gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true;
-		gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
-		gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredTerrainWaterProgram.mFeatures.hasGamma = true;
-		
-		gDeferredTerrainWaterProgram.mShaderFiles.clear();
-		gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
-		gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
-		gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredTerrainWaterProgram.clearPermutations();
-		gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");
-		success = gDeferredTerrainWaterProgram.createShader(NULL, NULL);
-        llassert(success);
-	}
-
 	if (success)
 	{
 		gDeferredAvatarProgram.mName = "Deferred Avatar Shader";
@@ -2331,6 +2011,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
 		gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
         gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
+        gDeferredAvatarAlphaProgram.mFeatures.hasWaterFog = true;
 
 		gDeferredAvatarAlphaProgram.mShaderFiles.clear();
         gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
@@ -2660,24 +2341,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
 	}
 	
-	if (success)
-	{
-		gObjectAlphaMaskNoColorWaterProgram.mName = "No color alpha mask Water Shader";
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesLighting = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasWaterFog = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAtmospherics = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasLighting = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true;
-		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();
-		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
-		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
-		gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
-		gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
-	}
-
 	if (success)
 	{
 		gImpostorProgram.mName = "Impostor Shader";
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index b0b9719d76..04da7e48ae 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -175,7 +175,6 @@ extern LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;
 extern LLGLSLShader		gObjectBumpProgram;
 extern LLGLSLShader        gSkinnedObjectBumpProgram;
 extern LLGLSLShader		gObjectAlphaMaskNoColorProgram;
-extern LLGLSLShader		gObjectAlphaMaskNoColorWaterProgram;
 
 //environment shaders
 extern LLGLSLShader			gWaterProgram;
@@ -211,7 +210,6 @@ extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
 extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram;
 extern LLGLSLShader			gDeferredBumpProgram;
 extern LLGLSLShader			gDeferredTerrainProgram;
-extern LLGLSLShader			gDeferredTerrainWaterProgram;
 extern LLGLSLShader			gDeferredTreeProgram;
 extern LLGLSLShader			gDeferredTreeShadowProgram;
 extern LLGLSLShader			gDeferredLightProgram;
@@ -219,10 +217,11 @@ extern LLGLSLShader			gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
 extern LLGLSLShader			gDeferredSpotLightProgram;
 extern LLGLSLShader			gDeferredMultiSpotLightProgram;
 extern LLGLSLShader			gDeferredSunProgram;
+extern LLGLSLShader         gHazeProgram;
+extern LLGLSLShader         gHazeWaterProgram;
 extern LLGLSLShader			gDeferredBlurLightProgram;
 extern LLGLSLShader			gDeferredAvatarProgram;
 extern LLGLSLShader			gDeferredSoftenProgram;
-extern LLGLSLShader			gDeferredSoftenWaterProgram;
 extern LLGLSLShader			gDeferredShadowProgram;
 extern LLGLSLShader			gDeferredShadowCubeProgram;
 extern LLGLSLShader			gDeferredShadowAlphaMaskProgram;
@@ -251,10 +250,6 @@ extern LLGLSLShader			gDeferredFullbrightAlphaMaskProgram;
 extern LLGLSLShader			gHUDFullbrightAlphaMaskProgram;
 extern LLGLSLShader			gDeferredFullbrightAlphaMaskAlphaProgram;
 extern LLGLSLShader			gHUDFullbrightAlphaMaskAlphaProgram;
-extern LLGLSLShader			gDeferredAlphaWaterProgram;
-extern LLGLSLShader			gDeferredFullbrightWaterProgram;
-extern LLGLSLShader			gDeferredFullbrightWaterAlphaProgram;
-extern LLGLSLShader			gDeferredFullbrightAlphaMaskWaterProgram;
 extern LLGLSLShader			gDeferredEmissiveProgram;
 extern LLGLSLShader			gDeferredAvatarEyesProgram;
 extern LLGLSLShader			gDeferredAvatarAlphaProgram;
@@ -271,12 +266,10 @@ extern LLGLSLShader			gDeferredBufferVisualProgram;
 
 // Deferred materials shaders
 extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
 
 extern LLGLSLShader         gHUDPBROpaqueProgram;
 extern LLGLSLShader         gPBRGlowProgram;
 extern LLGLSLShader         gDeferredPBROpaqueProgram;
 extern LLGLSLShader         gDeferredPBRAlphaProgram;
-extern LLGLSLShader         gDeferredPBRAlphaWaterProgram;
 extern LLGLSLShader         gHUDPBRAlphaProgram;
 #endif
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9266c84540..52afe16799 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7875,7 +7875,7 @@ void LLPipeline::renderDeferredLighting()
 
         if (RenderDeferredAtmospheric)
         {  // apply sunlight contribution
-            LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
+            LLGLSLShader &soften_shader = gDeferredSoftenProgram;
 
             LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics");
             LL_PROFILE_GPU_ZONE("atmospherics");
@@ -7904,7 +7904,7 @@ void LLPipeline::renderDeferredLighting()
                 mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
             }
 
-            unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
+            unbindDeferredShader(gDeferredSoftenProgram);
         }
 
         static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
@@ -8056,7 +8056,7 @@ void LLPipeline::renderDeferredLighting()
 
                     LLVector4a center;
                     center.load3(drawablep->getPositionAgent().mV);
-                    const F32 *c = center.getF32ptr();
+                    const F32* c = center.getF32ptr();
                     F32        s = volume->getLightRadius() * 1.5f;
 
                     sVisibleLightCount++;
@@ -8105,8 +8105,8 @@ void LLPipeline::renderDeferredLighting()
                         U32 idx = count - 1;
                         bindDeferredShader(gDeferredMultiLightProgram[idx]);
                         gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
-                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light);
-                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col);
+                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*)light);
+                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*)col);
                         gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
                         far_z = 0.f;
                         count = 0;
@@ -8124,11 +8124,11 @@ void LLPipeline::renderDeferredLighting()
 
                 for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
                 {
-                    LLDrawable *drawablep           = *iter;
-                    LLVOVolume *volume              = drawablep->getVOVolume();
-                    LLVector3   center              = drawablep->getPositionAgent();
-                    F32 *       c                   = center.mV;
-                    F32         light_size_final    = volume->getLightRadius() * 1.5f;
+                    LLDrawable* drawablep = *iter;
+                    LLVOVolume* volume = drawablep->getVOVolume();
+                    LLVector3   center = drawablep->getPositionAgent();
+                    F32* c = center.mV;
+                    F32         light_size_final = volume->getLightRadius() * 1.5f;
                     F32         light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
 
                     sVisibleLightCount++;
@@ -8154,12 +8154,56 @@ void LLPipeline::renderDeferredLighting()
         }
 
 
+        
+        if (RenderDeferredAtmospheric)
+        {
+            LLGLEnable blend(GL_BLEND);
+            gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA);
+            gGL.setColorMask(true, false);
+
+            for (U32 i = 0; i < 2; ++i)
+            {
+                // apply haze
+                LLGLSLShader &haze_shader = i == 0 ? gHazeProgram : gHazeWaterProgram;
+
+                LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - haze");
+                LL_PROFILE_GPU_ZONE("haze");
+                bindDeferredShader(haze_shader);
+
+                static LLCachedControl<F32> ssao_scale(gSavedSettings, "RenderSSAOIrradianceScale", 0.5f);
+                static LLCachedControl<F32> ssao_max(gSavedSettings, "RenderSSAOIrradianceMax", 0.25f);
+                static LLStaticHashedString ssao_scale_str("ssao_irradiance_scale");
+                static LLStaticHashedString ssao_max_str("ssao_irradiance_max");
+
+                haze_shader.uniform1f(ssao_scale_str, ssao_scale);
+                haze_shader.uniform1f(ssao_max_str, ssao_max);
+
+                LLEnvironment &environment = LLEnvironment::instance();
+                haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+                haze_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+
+                haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
+
+                {
+                    LLGLDepthTest depth(GL_FALSE);
+
+                    // full screen blit
+                    mScreenTriangleVB->setBuffer();
+                    mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                }
+
+                unbindDeferredShader(haze_shader);
+            }
+
+            gGL.setSceneBlendType(LLRender::BT_ALPHA);
+        }
+
+
         gGL.setColorMask(true, true);
     }
 
     {  // render non-deferred geometry (alpha, fullbright, glow)
         LLGLDisable blend(GL_BLEND);
-        //LLGLDisable stencil(GL_STENCIL_TEST);
 
         pushRenderTypeMask();
         andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
-- 
cgit v1.2.3


From 964f9e74d5e97fc46fc74d6afff97dad5c6381c3 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Fri, 17 Nov 2023 10:10:58 -0600
Subject: SL-20611 followup -- remove now unused glsl files.  Fix transparent
 water.

---
 indra/llrender/llglslshader.h                      |  1 -
 indra/llrender/llshadermgr.cpp                     | 74 +++++-----------------
 .../class1/lighting/lightWaterAlphaMaskF.glsl      | 51 ---------------
 .../lighting/lightWaterAlphaMaskNonIndexedF.glsl   | 55 ----------------
 .../shaders/class1/lighting/lightWaterF.glsl       | 42 ------------
 .../class1/lighting/lightWaterNonIndexedF.glsl     | 44 -------------
 .../shaders/class1/objects/simpleWaterF.glsl       | 33 ----------
 .../shaders/class3/environment/waterF.glsl         |  2 +-
 indra/newview/llviewershadermgr.cpp                | 14 +---
 9 files changed, 18 insertions(+), 298 deletions(-)
 delete mode 100644 indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
 delete mode 100644 indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
 delete mode 100644 indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
 delete mode 100644 indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
 delete mode 100644 indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl

(limited to 'indra')

diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index b8071248e2..43d095f73a 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -41,7 +41,6 @@ public:
     bool hasLighting = false; // implies no transport (it's possible to have neither though)
     bool isAlphaLighting = false; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
     bool isSpecular = false;
-    bool hasWaterFog = false; // implies no gamma
     bool hasTransport = false; // implies no lighting (it's possible to have neither though)
     bool hasSkinning = false;
     bool hasObjectSkinning = false;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index f14216f3d8..f78be910d2 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -278,7 +278,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 	}
 	
 	// NOTE order of shader object attaching is VERY IMPORTANT!!!
-	if (features->hasWaterFog || features->hasAtmospherics)
+	if (features->hasAtmospherics)
 	{
         if (!shader->attachFragmentObject("environment/waterFogF.glsl"))
 		{
@@ -288,82 +288,40 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 	
 	if (features->hasLighting)
 	{
-		if (features->hasWaterFog)
+		if (features->disableTextureIndex)
 		{
-			if (features->disableTextureIndex)
+			if (features->hasAlphaMask)
 			{
-				if (features->hasAlphaMask)
+                if (!shader->attachFragmentObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
 				{
-                    if (!shader->attachFragmentObject("lighting/lightWaterAlphaMaskNonIndexedF.glsl"))
-					{
-						return FALSE;
-					}
-				}
-				else
-				{
-                    if (!shader->attachFragmentObject("lighting/lightWaterNonIndexedF.glsl"))
-					{
-						return FALSE;
-					}
+					return FALSE;
 				}
 			}
-			else 
+			else
 			{
-				if (features->hasAlphaMask)
+                if (!shader->attachFragmentObject("lighting/lightNonIndexedF.glsl"))
 				{
-                    if (!shader->attachFragmentObject("lighting/lightWaterAlphaMaskF.glsl"))
-					{
-						return FALSE;
-					}
-				}
-				else
-				{
-                    if (!shader->attachFragmentObject("lighting/lightWaterF.glsl"))
-					{
-						return FALSE;
-					}
+					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
-		
-		else
+		else 
 		{
-			if (features->disableTextureIndex)
+			if (features->hasAlphaMask)
 			{
-				if (features->hasAlphaMask)
-				{
-                    if (!shader->attachFragmentObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
-					{
-						return FALSE;
-					}
-				}
-				else
+                if (!shader->attachFragmentObject("lighting/lightAlphaMaskF.glsl"))
 				{
-                    if (!shader->attachFragmentObject("lighting/lightNonIndexedF.glsl"))
-					{
-						return FALSE;
-					}
+					return FALSE;
 				}
 			}
-			else 
+			else
 			{
-				if (features->hasAlphaMask)
-				{
-                    if (!shader->attachFragmentObject("lighting/lightAlphaMaskF.glsl"))
-					{
-						return FALSE;
-					}
-				}
-				else
+                if (!shader->attachFragmentObject("lighting/lightF.glsl"))
 				{
-                    if (!shader->attachFragmentObject("lighting/lightF.glsl"))
-					{
-						return FALSE;
-					}
+					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
+			shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 		}
 	}
 	
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
deleted file mode 100644
index 670b3ddaf1..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/** 
- * @file class1\lighting\lightWaterAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, 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 float minimum_alpha;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-in vec4 vertex_color;
-in vec2 vary_texcoord0;
-
-void default_lighting_water()
-{
-	vec4 color = diffuseLookup(vary_texcoord0.xy);
-
-	if (color.a < minimum_alpha)
-	{
-		discard;
-	}
-
-	color.rgb *= vertex_color.rgb;
-
-	color.rgb = atmosLighting(color.rgb);
-
-	frag_color = max(applyWaterFog(color), vec4(0));
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
deleted file mode 100644
index 2e5ed57014..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ /dev/null
@@ -1,55 +0,0 @@
-/** 
- * @file class1\lighting\lightWaterAlphaMaskNonIndexedF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, 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 float minimum_alpha;
-
-uniform sampler2D diffuseMap;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-in vec4 vertex_color;
-in vec2 vary_texcoord0;
-
-void default_lighting_water()
-{
-	vec4 color = texture(diffuseMap,vary_texcoord0.xy);
-
-	if (color.a < minimum_alpha)
-	{
-		discard;
-	}
-
-	color.rgb *= vertex_color.rgb;
-
-	color.rgb = atmosLighting(color.rgb);
-
-	color = applyWaterFog(color);
-	
-	frag_color = max(color, vec4(0));
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
deleted file mode 100644
index 09b4a6e317..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
+++ /dev/null
@@ -1,42 +0,0 @@
-/** 
- * @file class1\lighting\lightWaterF.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;
-
-in vec4 vertex_color;
-in vec2 vary_texcoord0;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void default_lighting_water()
-{
-	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
-
-	color.rgb = atmosLighting(color.rgb);
-
-	frag_color = max(applyWaterFog(color), vec4(0));
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
deleted file mode 100644
index 4888fa547c..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/** 
- * @file class1\lighting\lightWaterNonIndexedF.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;
-
-in vec4 vertex_color;
-in vec2 vary_texcoord0;
-
-uniform sampler2D diffuseMap;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void default_lighting_water()
-{
-	vec4 color = texture(diffuseMap,vary_texcoord0.xy) * vertex_color;
-
-	color.rgb = atmosLighting(color.rgb);
-
-	frag_color = max(applyWaterFog(color), vec4(0));
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
deleted file mode 100644
index 2e87ac5bbc..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-/** 
- * @file simpleWaterF.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$
- */
- 
-
-
-void default_lighting_water();
-
-void main() 
-{
-	default_lighting_water();
-}
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index af0460fa8b..8bc5f3cc50 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -224,7 +224,7 @@ void main()
     }
 
 #else
-    vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);
+    vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0));
 #endif
 
     // fudge sample on other side of water to be a tad darker
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index e6e80e9532..2c2ae022d7 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -664,12 +664,8 @@ std::string LLViewerShaderMgr::loadBasicShaders()
     index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl",             ssr ? 3 : 1) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",                    mShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl",                   mShaderLevel[SHADER_LIGHTING] ) );
-	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl",               mShaderLevel[SHADER_LIGHTING] ) );
-	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl",              mShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);    shaders.push_back( make_pair( "lighting/lightF.glsl",                  mShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);    shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl",                 mShaderLevel[SHADER_LIGHTING] ) );
-	index_channels.push_back(ch);    shaders.push_back( make_pair( "lighting/lightWaterF.glsl",             mShaderLevel[SHADER_LIGHTING] ) );
-	index_channels.push_back(ch);    shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl",    mShaderLevel[SHADER_LIGHTING] ) );
 	
 	for (U32 i = 0; i < shaders.size(); i++)
 	{
@@ -707,7 +703,6 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		gWaterProgram.mName = "Water Shader";
 		gWaterProgram.mFeatures.calculatesAtmospherics = true;
         gWaterProgram.mFeatures.hasAtmospherics = true;
-        gWaterProgram.mFeatures.hasWaterFog = true;
 		gWaterProgram.mFeatures.hasGamma = true;
 		gWaterProgram.mFeatures.hasSrgb = true;
         gWaterProgram.mFeatures.hasReflectionProbes = true;
@@ -738,7 +733,6 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		gWaterEdgeProgram.mName = "Water Edge Shader";
 		gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
         gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
-        gWaterEdgeProgram.mFeatures.hasWaterFog = true;
 		gWaterEdgeProgram.mFeatures.hasGamma = true;
 		gWaterEdgeProgram.mFeatures.hasSrgb = true;
         gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
@@ -768,7 +762,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		//load under water vertex shader
 		gUnderWaterProgram.mName = "Underwater Shader";
 		gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gUnderWaterProgram.mFeatures.hasWaterFog = true;
+		gUnderWaterProgram.mFeatures.hasAtmospherics = true;
 		gUnderWaterProgram.mShaderFiles.clear();
 		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
 		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
@@ -1457,7 +1451,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             shader->mFeatures.hasGamma = true;
             shader->mFeatures.hasShadows = use_sun_shadow;
             shader->mFeatures.hasReflectionProbes = true;
-            shader->mFeatures.hasWaterFog = true;
             shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 
             shader->mShaderFiles.clear();
@@ -1580,7 +1573,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true;
 		gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
-        gDeferredFullbrightProgram.mFeatures.hasWaterFog = true;
 		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightProgram.mShaderFiles.clear();
 		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
@@ -1616,7 +1608,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;		
-        gDeferredFullbrightAlphaMaskProgram.mFeatures.hasWaterFog = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
 		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
@@ -1804,7 +1795,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gHazeWaterProgram.mName = "Water Haze Shader";
         gHazeWaterProgram.mShaderFiles.clear();
         gHazeWaterProgram.mShaderGroup           = LLGLSLShader::SG_WATER;
-        gHazeWaterProgram.mFeatures.hasWaterFog            = true;
         gHazeWaterProgram.mFeatures.hasSrgb                = true;
         gHazeWaterProgram.mFeatures.calculatesAtmospherics = true;
         gHazeWaterProgram.mFeatures.hasAtmospherics        = true;
@@ -1969,7 +1959,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredTerrainProgram.mFeatures.hasLighting = false;
 		gDeferredTerrainProgram.mFeatures.isAlphaLighting = true;
 		gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
-		gDeferredTerrainProgram.mFeatures.hasWaterFog = true;
 		gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
 		gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
 		gDeferredTerrainProgram.mFeatures.hasGamma = true;
@@ -2011,7 +2000,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
 		gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
         gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
-        gDeferredAvatarAlphaProgram.mFeatures.hasWaterFog = true;
 
 		gDeferredAvatarAlphaProgram.mShaderFiles.clear();
         gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
-- 
cgit v1.2.3


From ba1f87b36e91668b6f87bc996b06db79f2763901 Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Fri, 17 Nov 2023 13:26:08 -0800
Subject: SL-20553: Fix crash in ~PBRPickerAgentListener

---
 indra/newview/llpanelface.cpp | 2 --
 1 file changed, 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 02c00e7f87..bf54d17111 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1915,8 +1915,6 @@ public:
     {
         gInventory.removeObserver(this);
         mChangePending = false;
-
-        LLInventoryObserver::~LLInventoryObserver();
     }
 };
 
-- 
cgit v1.2.3


From 70eda83fb08c5c4e8b0ea95868243d744c6e88e9 Mon Sep 17 00:00:00 2001
From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com>
Date: Mon, 20 Nov 2023 21:25:06 +0100
Subject: SL-20563 Add 'No Post' option to Snapshot floater

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llfloatersnapshot.cpp     |  4 ++--
 indra/newview/llsnapshotlivepreview.cpp |  2 ++
 indra/newview/llviewerdisplay.cpp       |  5 +++--
 indra/newview/llviewermenufile.cpp      |  6 ++++--
 indra/newview/llviewerwindow.cpp        |  9 ++++++---
 indra/newview/llviewerwindow.h          |  4 ++--
 indra/newview/pipeline.cpp              |  6 ++++--
 8 files changed, 34 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b9025ef7cd..00b59f9a4d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -533,6 +533,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>RenderSnapshotNoPost</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable tone mapping and exposure correction when snapshot is being rendered</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AutomaticFly</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 4806fe9625..ca2069cbfc 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -474,7 +474,7 @@ void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data
 void LLFloaterSnapshotBase::ImplBase::onClickNoPost(LLUICtrl *ctrl, void* data)
 {
     BOOL no_post = ((LLCheckBoxCtrl*)ctrl)->get();
-    gSavedSettings.setBOOL("RenderDisablePostProcessing", no_post);
+    gSavedSettings.setBOOL("RenderSnapshotNoPost", no_post);
 
     LLFloaterSnapshotBase* view = (LLFloaterSnapshotBase*)data;
     view->getPreviewView()->updateSnapshot(TRUE, TRUE);
@@ -1008,7 +1008,7 @@ BOOL LLFloaterSnapshot::postBuild()
 	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
 	childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
 
-    getChild<LLUICtrl>("no_post_check")->setValue(gSavedSettings.getBOOL("RenderDisablePostProcessing"));
+    getChild<LLUICtrl>("no_post_check")->setValue(gSavedSettings.getBOOL("RenderSnapshotNoPost"));
     childSetCommitCallback("no_post_check", ImplBase::onClickNoPost, this);
 
     getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index b7a1832b17..2ff8f50277 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -559,6 +559,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
                                          mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
                                          gSavedSettings.getBOOL("RenderHUDInSnapshot"),
                                          FALSE,
+                                         gSavedSettings.getBOOL("RenderSnapshotNoPost"),
                                          mSnapshotBufferType) )
         {
             raw = NULL ;
@@ -718,6 +719,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
                 previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
                 gSavedSettings.getBOOL("RenderHUDInSnapshot"),
                 FALSE,
+                gSavedSettings.getBOOL("RenderSnapshotNoPost"),
                 previewp->mSnapshotBufferType,
                 previewp->getMaxImageSize()))
         {
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 04ca62e0ec..a936012781 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -100,6 +100,7 @@ BOOL gResizeShadowTexture = FALSE;
 BOOL gWindowResized = FALSE;
 BOOL gSnapshot = FALSE;
 BOOL gCubeSnapshot = FALSE;
+BOOL gSnapshotNoPost = FALSE;
 BOOL gShaderProfileFrame = FALSE;
 
 // This is how long the sim will try to teleport you before giving up.
@@ -410,13 +411,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		gResizeShadowTexture = FALSE;
 	}
 
+	gSnapshot = for_snapshot;
+
 	if (LLPipeline::sRenderDeferred)
 	{ //hack to make sky show up in deferred snapshots
 		for_snapshot = FALSE;
 	}
 
-	gSnapshot = for_snapshot;
-
 	LLGLSDefault gls_default;
 	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
 	
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index e2791ba128..5461e0f362 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -863,8 +863,9 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 		S32 width = gViewerWindow->getWindowWidthRaw();
 		S32 height = gViewerWindow->getWindowHeightRaw();
 
-		bool render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
-		bool render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
+		BOOL render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
+		BOOL render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
+		BOOL render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost");
 
 		BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot");
 		if (high_res)
@@ -884,6 +885,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 									   render_ui,
 									   render_hud,
 									   FALSE,
+									   render_no_post,
 									   LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
 									   high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side
 		{
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ba2b6e1c7c..ed671fe849 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -229,6 +229,7 @@ extern BOOL gDisplaySwapBuffers;
 extern BOOL gDepthDirty;
 extern BOOL gResizeScreenTexture;
 extern BOOL gCubeSnapshot;
+extern BOOL gSnapshotNoPost;
 
 LLViewerWindow	*gViewerWindow = NULL;
 
@@ -4875,16 +4876,16 @@ void LLViewerWindow::resetSnapshotLoc() const
 	gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
 }
 
-BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
+BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type)
 {
-	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, type);
+	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, no_post, type);
 }
 
 // Saves the image from the screen to a raw image
 // Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
 // the results over to the final raw image.
 BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, 
-    BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
+    BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
 {
 	if (!raw)
 	{
@@ -4901,6 +4902,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	}
 
 	// PRE SNAPSHOT
+	gSnapshotNoPost = no_post;
 	gDisplaySwapBuffers = FALSE;
 	
     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
@@ -5131,6 +5133,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	}
 
 	gDisplaySwapBuffers = FALSE;
+	gSnapshotNoPost = FALSE;
 	gDepthDirty = TRUE;
 
 	// POST SNAPSHOT
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 6e8a5b2f4e..ccef006a07 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -362,7 +362,7 @@ public:
 
 	BOOL			saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP);
 	BOOL			rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
-		BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
+		BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, BOOL no_post = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
 
     BOOL			simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
 
@@ -380,7 +380,7 @@ public:
     // special implementation of simpleSnapshot for reflection maps
     BOOL			reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
 
-    BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
+    BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type);
 	BOOL			isSnapshotLocSet() const;
 	void			resetSnapshotLoc() const;
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9266c84540..64d247a202 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -211,6 +211,7 @@ extern S32 gBoxFrame;
 extern BOOL gDisplaySwapBuffers;
 extern BOOL gDebugGL;
 extern BOOL gCubeSnapshot;
+extern BOOL gSnapshotNoPost;
 
 bool	gAvatarBacklight = false;
 
@@ -6791,7 +6792,7 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
 	{
 		LL_PROFILE_GPU_ZONE("gamma correct");
 
-        static LLCachedControl<bool> no_post(gSavedSettings, "RenderDisablePostProcessing", false);
+        static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false);
 
 		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
@@ -6801,7 +6802,8 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
         
         LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
 
-        LLGLSLShader& shader = no_post && gFloaterTools->isAvailable() ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
+        bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable());
+        LLGLSLShader& shader = no_post ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
             psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram :
             gDeferredPostGammaCorrectProgram;
         
-- 
cgit v1.2.3


From f35127faa03b438b5348c56c9e04b7b1a2c698ea Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Mon, 20 Nov 2023 10:18:27 -0500
Subject: Fix failure to save the normalized translation data during collada
 upload

---
 indra/llprimitive/lldaeloader.cpp | 3 ++-
 indra/llprimitive/llmodel.cpp     | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 46e1cb4922..2e4b013b77 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -2584,7 +2584,8 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
 			next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
 			next->getVolumeFaces() = remainder;
 			next->mNormalizedScale = ret->mNormalizedScale;
-			
+			next->mNormalizedTranslation = ret->mNormalizedTranslation;
+
 			if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES)
 			{
 				next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end());
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index ee493968de..99a5697a84 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -52,7 +52,8 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
 
 LLModel::LLModel(LLVolumeParams& params, F32 detail)
 	: LLVolume(params, detail), 
-      mNormalizedScale(1,1,1), 
+      mNormalizedScale(1,1,1),
+      mNormalizedTranslation(0, 0, 0),
       mPelvisOffset( 0.0f ), 
       mStatus(NO_ERRORS), 
       mSubmodelID(0)
-- 
cgit v1.2.3


From 86df22a031527ffb8edbcc5bca93a2e7735dfae6 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Mon, 27 Nov 2023 15:01:01 +0200
Subject: SL-20639 increase floater width to accommodate adding new option

---
 indra/newview/skins/default/xui/en/floater_snapshot.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 0866594625..1a1131e24c 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -5,7 +5,7 @@
  can_minimize="true"
  can_resize="false"
  can_close="true"
- height="455"
+ height="475"
  layout="topleft"
  name="Snapshot"
  single_instance="true"
@@ -241,7 +241,7 @@
     </panel>
 	<panel_container
      follows="left|top"
-     height="210"
+     height="230"
      layout="topleft"
      left="0"
      name="panel_container"
@@ -399,8 +399,8 @@
     name="thumbnail_placeholder"
     top="23"
 	left="215"
-	width="400"
-	height="400"
+	width="420"
+	height="420"
     follows="top|left"/>
   <view_border 
    bevel_style="in" 
-- 
cgit v1.2.3


From f9cba58fe203ac53823ee3b5a7ded444b7106783 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Tue, 28 Nov 2023 14:31:27 +0200
Subject: SL-20645 don't show the warning when 'Select Reflection Probes' is
 enabled

---
 indra/newview/llpanelvolume.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index f58aab3080..595609b4de 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -746,6 +746,14 @@ void LLPanelVolume::sendIsLight()
 	LL_INFOS() << "update light sent" << LL_ENDL;
 }
 
+void notify_cant_select_reflection_probe()
+{
+    if (!gSavedSettings.getBOOL("SelectReflectionProbes"))
+    {
+        LLNotificationsUtil::add("CantSelectReflectionProbe");
+    }
+}
+
 void LLPanelVolume::sendIsReflectionProbe()
 {
     LLViewerObject* objectp = mObject;
@@ -766,7 +774,7 @@ void LLPanelVolume::sendIsReflectionProbe()
     {
         if (value)
         {
-            LLNotificationsUtil::add("CantSelectReflectionProbe");
+            notify_cant_select_reflection_probe();
         }
         else if (objectp->flagPhantom())
         {
@@ -794,7 +802,7 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS
         }
         LLVOVolume* volobjp = (LLVOVolume*)objectp;
 
-        LLNotificationsUtil::add("CantSelectReflectionProbe");
+        notify_cant_select_reflection_probe();
         volobjp->setIsReflectionProbe(true);
 
         { // has become a reflection probe, slam to a 10m sphere and pop up a message
-- 
cgit v1.2.3


From b96ca755b36737eb07645df7b172be002d9509f2 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Wed, 29 Nov 2023 16:46:10 +0200
Subject: SL-20647 don't allow dragging 'no mod' material into the picker of an
 attached object

---
 indra/newview/llpanelface.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index bf54d17111..e7b856f743 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1981,6 +1981,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
         if (objectp->isAttachment())
         {
             pbr_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
+            pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
         }
         else
         {
-- 
cgit v1.2.3


From e100556a59b6184bf0d89a58621c2990b90f6231 Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Wed, 29 Nov 2023 12:56:48 -0800
Subject: increment viewer version after DRTVWR-559 release

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 9fe9ff9d99..21c8c7b46b 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.0.1
+7.1.1
-- 
cgit v1.2.3


From 88aefc95eace0bb8ea21cb44514d41d98bdf74cc Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 30 Nov 2023 17:47:46 +0200
Subject: SL-20655 FIXED Texture permissions not enforced in Material floaters

---
 indra/newview/llmaterialeditor.cpp | 8 ++++----
 indra/newview/llpanelface.cpp      | 3 +--
 indra/newview/lltexturectrl.cpp    | 6 ++++++
 indra/newview/lltexturectrl.h      | 1 +
 4 files changed, 12 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 70e21cae73..292ddb765f 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -436,10 +436,10 @@ BOOL LLMaterialEditor::postBuild()
     if (!gAgent.isGodlike())
     {
         // Only allow fully permissive textures
-        mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-        mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-        mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-        mNormalTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+        mBaseColorTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
+        mMetallicTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
+        mEmissiveTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
+        mNormalTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
     }
 
     // Texture callback
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index e7b856f743..ffcc4be290 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1980,8 +1980,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
 
         if (objectp->isAttachment())
         {
-            pbr_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
-            pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
+            pbr_ctrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
         }
         else
         {
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index f302426a43..28e01c6c21 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1715,6 +1715,12 @@ void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
     }
 }
 
+void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask) 
+{
+    setImmediateFilterPermMask(mask);
+    setDnDFilterPermMask(mask);
+}
+
 void LLTextureCtrl::setVisible( BOOL visible ) 
 {
 	if( !visible )
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index c47df5accb..7a96eea60d 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -196,6 +196,7 @@ public:
 	void			setDnDFilterPermMask(PermissionMask mask)
 						{ mDnDFilterPermMask = mask; }
 	PermissionMask	getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
+    void setFilterPermissionMasks(PermissionMask mask);
 
 	void			closeDependentFloater();
 
-- 
cgit v1.2.3


From 68875523e09f9fe06fc4b3cd5225995bb13966c3 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Thu, 30 Nov 2023 12:01:45 -0600
Subject: SL-20611 Incorporate water haze into new post effect atmospherics
 goodness

---
 .../shaders/class1/deferred/fullbrightF.glsl       |   6 +-
 .../shaders/class3/deferred/hazeF.glsl             |  16 +--
 .../shaders/class3/deferred/waterHazeF.glsl        |  13 +-
 .../shaders/class3/deferred/waterHazeV.glsl        |  59 ++++++++
 .../shaders/class3/environment/underWaterF.glsl    |   4 +-
 .../shaders/class3/environment/waterF.glsl         |   3 -
 indra/newview/lldrawpool.cpp                       |   8 ++
 indra/newview/lldrawpool.h                         |   5 +-
 indra/newview/lleventpoll.cpp                      |  22 ++-
 indra/newview/llsettingsvo.cpp                     |  10 ++
 indra/newview/llviewercamera.cpp                   |  22 ++-
 indra/newview/llviewershadermgr.cpp                |   2 +-
 indra/newview/pipeline.cpp                         | 156 +++++++++++++++------
 indra/newview/pipeline.h                           |  10 ++
 14 files changed, 255 insertions(+), 81 deletions(-)
 create mode 100644 indra/newview/app_settings/shaders/class3/deferred/waterHazeV.glsl

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 2798c59f1c..1de8b25a7d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -82,12 +82,12 @@ void main()
     vec3 additive;
     vec3 atten;
     calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
-#endif
-
 
-#ifndef IS_HUD
     color.rgb = srgb_to_linear(color.rgb);
+
+#ifdef IS_ALPHA
     color.rgb = atmosFragLighting(color.rgb, additive, atten);
+#endif
 
     vec4 fogged = applyWaterFogViewLinear(pos, vec4(color.rgb, final_alpha));
     color.rgb = fogged.rgb;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
index 7b77a2f5fb..e8f7d73f1f 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -68,23 +68,21 @@ void main()
     calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
 
     vec3 sunlit_linear = srgb_to_linear(sunlit);
-    vec3 amblit_linear = amblit;
-
+    
+    // mask off atmospherics below water (when camera is under water)
     bool do_atmospherics = false;
-
-    // mask off atmospherics below water
-    if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
+        
+    if (dot(vec3(0), waterPlane.xyz) + waterPlane.w > 0.0 ||
+        dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
     {
         do_atmospherics = true;
     }
+    
 
     vec3  irradiance = vec3(0);
     vec3  radiance  = vec3(0);
 
-    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
-    {
-    }
-    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+    if (depth >= 1.0)
     {
         //should only be true of WL sky, just port over base color value
         discard;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index f63d70cbd7..025bcdaf3e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -26,7 +26,7 @@
 out vec4 frag_color;
 
 // Inputs
-in vec2 vary_fragcoord;
+in vec4 vary_fragcoord;
 
 uniform sampler2D normalMap;
 
@@ -37,20 +37,11 @@ vec4 getWaterFogView(vec3 pos);
 
 void main()
 {
-    vec2  tc           = vary_fragcoord.xy;
+    vec2  tc           = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
     float depth        = getDepth(tc.xy);
     vec4  pos          = getPositionWithDepth(tc, depth);
     vec4  norm         = texture(normalMap, tc);
 
-    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
-    {
-    }
-    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
-    {
-        //should only be true of WL sky, just port over base color value
-        discard;
-    }
-
     vec4 fogged = getWaterFogView(pos.xyz);
 
     frag_color.rgb = max(fogged.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeV.glsl
new file mode 100644
index 0000000000..16381a5d51
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeV.glsl
@@ -0,0 +1,59 @@
+/**
+ * @file class3/deferred/waterHazeV.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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$
+ */
+
+in vec3 position;
+
+uniform vec2 screen_res;
+
+out vec4 vary_fragcoord;
+
+// forwards
+void setAtmosAttenuation(vec3 c);
+void setAdditiveColor(vec3 c);
+
+uniform vec4 waterPlane;
+
+uniform int above_water;
+
+uniform mat4 modelview_projection_matrix;
+
+void main()
+{
+	//transform vertex
+	vec4 pos = vec4(position.xyz, 1.0);
+
+    if (above_water > 0)
+    {
+        pos = modelview_projection_matrix*pos;
+    }
+
+    gl_Position = pos; 
+
+    // appease OSX GLSL compiler/linker by touching all the varyings we said we would
+    setAtmosAttenuation(vec3(1));
+    setAdditiveColor(vec3(0));
+
+	vary_fragcoord = pos;
+}
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 924f356f35..ddb1b79681 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -77,5 +77,7 @@ void main()
     vec4 fb = vec4(waterFogColorLinear, 0.0);
 #endif
     
-	frag_color = max(applyWaterFogViewLinearNoClip(vary_position, fb), vec4(0));
+    fb = applyWaterFogViewLinearNoClip(vary_position, fb);
+
+    frag_color = max(fb, vec4(0));
 }
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 8bc5f3cc50..f53bc2e13e 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -32,7 +32,6 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
 #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);
 
@@ -281,8 +280,6 @@ void main()
 
     color = ((1.0 - f) * color) + fb.rgb;
 
-    color = atmosFragLightingLinear(color, additive, atten);
-
     float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
     
     frag_color = max(vec4(color, spec), vec4(0));
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index fca0f1c978..50210b06c4 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -320,6 +320,14 @@ void LLFacePool::addFaceReference(LLFace *facep)
 	}
 }
 
+void LLFacePool::pushFaceGeometry()
+{
+    for (LLFace* const& face : mDrawFace)
+    {
+        face->renderIndexed();
+    }
+}
+
 BOOL LLFacePool::verify() const
 {
 	BOOL ok = TRUE;
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 5414dba6bf..4300670445 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -118,8 +118,8 @@ public:
 	virtual LLViewerTexture* getTexture() = 0;
 	virtual BOOL isFacePool() { return FALSE; }
 	virtual void resetDrawOrders() = 0;
+    virtual void pushFaceGeometry() {}
 
-protected:
 	S32 mShaderLevel;
 	S32	mId;
 	U32 mType;				// Type of draw pool
@@ -429,6 +429,9 @@ public:
 	
 	BOOL isFacePool() { return TRUE; }
 
+    // call drawIndexed on every draw face
+    void pushFaceGeometry();
+
 	friend class LLFace;
 	friend class LLPipeline;
 public:
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 26782e53f0..670a780fdd 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -102,6 +102,7 @@ namespace Details
 
     void LLEventPollImpl::handleMessage(const LLSD& content)
     {
+        LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
         std::string	msg_name = content["message"];
         LLSD message;
         message["sender"] = mSenderIp;
@@ -149,6 +150,12 @@ namespace Details
 
         mAdapter = httpAdapter;
 
+        LL::WorkQueue::ptr_t main_queue = nullptr;
+
+#if 1
+        main_queue = LL::WorkQueue::getInstance("mainloop");
+#endif
+
         // continually poll for a server update until we've been flagged as 
         // finished 
         while (!mDone)
@@ -266,13 +273,26 @@ namespace Details
             // was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
             LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << acknowledge << ")" << LL_ENDL;
 
+
             LLSD::array_const_iterator i = events.beginArray();
             LLSD::array_const_iterator end = events.endArray();
             for (; i != end; ++i)
             {
                 if (i->has("message"))
                 {
-                    handleMessage(*i);
+                    if (main_queue)
+                    { // shuttle to a sensible spot in the main thread instead
+                        // of wherever this coroutine happens to be executing
+                        const LLSD& msg = *i;
+                        main_queue->post([this, msg]()
+                            { 
+                                handleMessage(msg); 
+                            });
+                    }
+                    else
+                    {
+                        handleMessage(*i);
+                    }
                 }
             }
         }
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 2f65f3dec3..7009fb98ab 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -63,6 +63,7 @@
 #include <boost/algorithm/string/replace.hpp>
 #include "llinventoryobserver.h"
 #include "llinventorydefines.h"
+#include "llworld.h"
 
 #include "lltrans.h"
 
@@ -989,6 +990,15 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
 	{
         F32 water_height = env.getWaterHeight();
 
+        if (LLViewerCamera::instance().cameraUnderWater())
+        { // when the camera is under water, use the water height at the camera position
+            LLViewerRegion* region = LLWorld::instance().getRegionFromPosAgent(LLViewerCamera::instance().getOrigin());
+            if (region)
+            {
+                water_height = region->getWaterHeight();
+            }
+        }
+
         //transform water plane to eye space
         glh::vec3f norm(0.f, 0.f, 1.f);
         glh::vec3f p(0.f, 0.f, water_height);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index b926631ebe..4134e35f87 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -112,12 +112,16 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center, const LLVecto
 
     mLastPointOfInterest = point_of_interest;
 
-    LLViewerRegion *regp         = gAgent.getRegion();
-    F32             water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
+    LLViewerRegion* regp = LLWorld::instance().getRegionFromPosAgent(getOrigin());
+    if (!regp)
+    {
+        regp = gAgent.getRegion();
+    }
+
+    F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
 
     LLVector3 origin = center;
 
-    if (LLEnvironment::instance().getCurrentWater()->getFogMod() != 1.f)
     {
         if (origin.mV[2] > water_height)
         {
@@ -758,11 +762,19 @@ LLVector3 LLViewerCamera::roundToPixel(const LLVector3 &pos_agent)
 
 BOOL LLViewerCamera::cameraUnderWater() const
 {
-	if(!gAgent.getRegion())
+    LLViewerRegion* regionp = LLWorld::instance().getRegionFromPosAgent(getOrigin());
+
+    if (!regionp)
+    {
+        regionp = gAgent.getRegion();
+    }
+
+	if(!regionp)
 	{
 		return FALSE ;
 	}
-	return getOrigin().mV[VZ] < gAgent.getRegion()->getWaterHeight();
+
+	return getOrigin().mV[VZ] < regionp->getWaterHeight();
 }
 
 BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 2c2ae022d7..3225299493 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1804,7 +1804,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gHazeWaterProgram.mFeatures.hasReflectionProbes    = mShaderLevel[SHADER_DEFERRED] > 2;
 
         gHazeWaterProgram.clearPermutations();
-        gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+        gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeV.glsl", GL_VERTEX_SHADER));
         gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeF.glsl", GL_FRAGMENT_SHADER));
 
         gHazeWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 52afe16799..7b1e5a55d1 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3877,6 +3877,20 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 
 	LLGLEnable cull(GL_CULL_FACE);
 
+    bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds
+    bool done_water_haze = done_atmospherics;
+
+    // do atmospheric haze just before post water alpha
+    U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER;
+
+    if (LLPipeline::sUnderWaterRender)
+    { // if under water, do atmospherics just before the water pass
+        atmospherics_pass = LLDrawPool::POOL_WATER;
+    }
+
+    // do water haze just before pre water alpha
+    U32 water_haze_pass = LLDrawPool::POOL_ALPHA_PRE_WATER;
+
 	calcNearbyLights(camera);
 	setupHWLights();
 
@@ -3896,6 +3910,18 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 		
 		cur_type = poolp->getType();
 
+        if (cur_type >= atmospherics_pass && !done_atmospherics)
+        { // do atmospherics against depth buffer before rendering alpha
+            doAtmospherics();
+            done_atmospherics = true;
+        }
+
+        if (cur_type >= water_haze_pass && !done_water_haze)
+        { // do water haze against depth buffer before rendering alpha
+            doWaterHaze();
+            done_water_haze = true;
+        }
+
 		pool_set_t::iterator iter2 = iter1;
 		if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
 		{
@@ -8153,52 +8179,6 @@ void LLPipeline::renderDeferredLighting()
             }
         }
 
-
-        
-        if (RenderDeferredAtmospheric)
-        {
-            LLGLEnable blend(GL_BLEND);
-            gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA);
-            gGL.setColorMask(true, false);
-
-            for (U32 i = 0; i < 2; ++i)
-            {
-                // apply haze
-                LLGLSLShader &haze_shader = i == 0 ? gHazeProgram : gHazeWaterProgram;
-
-                LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - haze");
-                LL_PROFILE_GPU_ZONE("haze");
-                bindDeferredShader(haze_shader);
-
-                static LLCachedControl<F32> ssao_scale(gSavedSettings, "RenderSSAOIrradianceScale", 0.5f);
-                static LLCachedControl<F32> ssao_max(gSavedSettings, "RenderSSAOIrradianceMax", 0.25f);
-                static LLStaticHashedString ssao_scale_str("ssao_irradiance_scale");
-                static LLStaticHashedString ssao_max_str("ssao_irradiance_max");
-
-                haze_shader.uniform1f(ssao_scale_str, ssao_scale);
-                haze_shader.uniform1f(ssao_max_str, ssao_max);
-
-                LLEnvironment &environment = LLEnvironment::instance();
-                haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
-                haze_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
-
-                haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
-
-                {
-                    LLGLDepthTest depth(GL_FALSE);
-
-                    // full screen blit
-                    mScreenTriangleVB->setBuffer();
-                    mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-                }
-
-                unbindDeferredShader(haze_shader);
-            }
-
-            gGL.setSceneBlendType(LLRender::BT_ALPHA);
-        }
-
-
         gGL.setColorMask(true, true);
     }
 
@@ -8254,6 +8234,90 @@ void LLPipeline::renderDeferredLighting()
     gGL.setColorMask(true, true);
 }
 
+void LLPipeline::doAtmospherics()
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
+    if (RenderDeferredAtmospheric)
+    {
+        LLGLEnable blend(GL_BLEND);
+        gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
+
+        gGL.setColorMask(true, true);
+
+        // apply haze
+        LLGLSLShader& haze_shader = gHazeProgram;
+
+        LL_PROFILE_GPU_ZONE("haze");
+        bindDeferredShader(haze_shader);
+
+        LLEnvironment& environment = LLEnvironment::instance();
+        haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+        haze_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+
+        haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
+
+        LLGLDepthTest depth(GL_FALSE);
+
+        // full screen blit
+        mScreenTriangleVB->setBuffer();
+        mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+    
+        unbindDeferredShader(haze_shader);
+
+        gGL.setSceneBlendType(LLRender::BT_ALPHA);
+    }
+}
+
+void LLPipeline::doWaterHaze()
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
+    if (RenderDeferredAtmospheric)
+    {
+        LLGLEnable blend(GL_BLEND);
+        gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
+
+        gGL.setColorMask(true, true);
+
+        // apply haze
+        LLGLSLShader& haze_shader = gHazeWaterProgram;
+
+        LL_PROFILE_GPU_ZONE("haze");
+        bindDeferredShader(haze_shader);
+
+        haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
+
+        static LLStaticHashedString above_water_str("above_water");
+        haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1);
+
+        if (LLPipeline::sUnderWaterRender)
+        {
+            LLGLDepthTest depth(GL_FALSE);
+
+            // full screen blit
+            mScreenTriangleVB->setBuffer();
+            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+        }
+        else
+        {
+            //render water patches like LLDrawPoolWater does
+            LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+            LLGLDisable   cull(GL_CULL_FACE);
+
+            gGLLastMatrix = NULL;
+            gGL.loadMatrix(gGLModelView);
+
+            mWaterPool->pushFaceGeometry();
+        }
+
+        unbindDeferredShader(haze_shader);
+
+
+        gGL.setSceneBlendType(LLRender::BT_ALPHA);
+    }
+}
+
 void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 {
 	//construct frustum
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 6e4c9c7a97..bbed7cad92 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -318,6 +318,16 @@ public:
     void unbindReflectionProbes(LLGLSLShader& shader);
 
 	void renderDeferredLighting();
+
+    // apply atmospheric haze based on contents of color and depth buffer
+    // should be called just before rendering water when camera is under water 
+    // and just before rendering alpha when camera is above water
+    void doAtmospherics();
+
+    // apply water haze based on contents of color and depth buffer
+    // should be called just before rendering pre-water alpha objects
+    void doWaterHaze();
+
 	void postDeferredGammaCorrect(LLRenderTarget* screen_target);
 
 	void generateSunShadow(LLCamera& camera);
-- 
cgit v1.2.3


From c573d27e5baf23adbc14153c4d65a581f55febb4 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Fri, 1 Dec 2023 14:49:22 -0600
Subject: SL-20611 Followup -- fix for water rendering twice.  Add comments
 around LLEventPoll hack.

---
 indra/newview/lleventpoll.cpp        |  2 ++
 indra/newview/llspatialpartition.cpp | 11 ++++++++
 indra/newview/llworld.cpp            | 52 ------------------------------------
 indra/newview/llworld.h              |  2 --
 indra/newview/pipeline.cpp           |  7 -----
 5 files changed, 13 insertions(+), 61 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 670a780fdd..6ffc8f7bdd 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -152,6 +152,8 @@ namespace Details
 
         LL::WorkQueue::ptr_t main_queue = nullptr;
 
+        // HACK -- grab the mainloop workqueue to move execution of the handler
+        // to a place that's safe in the main thread
 #if 1
         main_queue = LL::WorkQueue::getInstance("mainloop");
 #endif
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index a63d46f502..9f30d60fed 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -64,6 +64,9 @@ bool LLSpatialGroup::sNoDelete = false;
 static F32 sLastMaxTexPriority = 1.f;
 static F32 sCurMaxTexPriority = 1.f;
 
+// enable expensive sanity checks around redundant drawable and group insertion to LLCullResult
+#define LL_DEBUG_CULL_RESULT 0
+
 //static counter for frame to switch LOD on
 
 void sg_assert(BOOL expr)
@@ -4015,6 +4018,10 @@ void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
 
 void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
 {
+#if LL_DEBUG_CULL_RESULT
+    // group must NOT be in the drawble groups list already
+    llassert(std::find(&mDrawableGroups[0], mDrawableGroupsEnd, group) == mDrawableGroupsEnd);
+#endif
 	if (mDrawableGroupsSize < mDrawableGroupsAllocated)
 	{
 		mDrawableGroups[mDrawableGroupsSize] = group;
@@ -4029,6 +4036,10 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
 
 void LLCullResult::pushDrawable(LLDrawable* drawable)
 {
+#if LL_DEBUG_CULL_RESULT
+    // drawable must NOT be in the visible list already
+    llassert(std::find(&mVisibleList[0], mVisibleListEnd, drawable) == mVisibleListEnd);
+#endif
 	if (mVisibleListSize < mVisibleListAllocated)
 	{
 		mVisibleList[mVisibleListSize] = drawable;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 709a457862..9381211e9b 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -883,58 +883,6 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh
 	}
 }
 
-void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-	if (!gAgent.getRegion())
-	{
-		return;
-	}
-
-	if (mRegionList.empty())
-	{
-		LL_WARNS() << "No regions!" << LL_ENDL;
-		return;
-	}
-
-	for (region_list_t::iterator iter = mRegionList.begin();
-		 iter != mRegionList.end(); ++iter)
-	{
-		LLViewerRegion* regionp = *iter;
-		LLVOWater* waterp = regionp->getLand().getWaterObj();
-		if (waterp && waterp->mDrawable)
-		{
-			waterp->mDrawable->setVisible(camera);
-		    cull->pushDrawable(waterp->mDrawable);
-		}
-	}
-
-    if (include_void_water)
-    {
-		for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin();
-			 iter != mHoleWaterObjects.end(); ++ iter)
-		{
-			LLVOWater* waterp = (*iter).get();
-		    if (waterp && waterp->mDrawable)
-            {
-                waterp->mDrawable->setVisible(camera);
-		        cull->pushDrawable(waterp->mDrawable);
-            }
-	    }
-    }
-
-	S32 dir;
-	for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++)
-	{
-		LLVOWater* waterp = mEdgeWaterObjects[dir];
-		if (waterp && waterp->mDrawable)
-		{
-            waterp->mDrawable->setVisible(camera);
-		    cull->pushDrawable(waterp->mDrawable);
-		}
-	}
-}
-
 void LLWorld::clearHoleWaterObjects()
 {
     for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin();
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index f78cbcaa48..2878d10f5e 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -140,8 +140,6 @@ public:
 	LLViewerTexture *getDefaultWaterTexture();
     void updateWaterObjects();
 
-    void precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water);
-
 	void waterHeightRegionInfo(std::string const& sim_name, F32 water_height);
 	void shiftRegions(const LLVector3& offset);
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 76414b5e4e..50cd4adb73 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2311,13 +2311,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
         gSky.mVOWLSkyp->mDrawable->setVisible(camera);
         sCull->pushDrawable(gSky.mVOWLSkyp->mDrawable);
     }
-
-    bool render_water = !sReflectionRender && (hasRenderType(LLPipeline::RENDER_TYPE_WATER) || hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER));
-
-    if (render_water)
-    {
-        LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);
-    }
 }
 
 void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
-- 
cgit v1.2.3


From 6aeaa4024e685945f69d6af09602e9d33977a4bf Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Mon, 4 Dec 2023 23:31:37 +0200
Subject: SL-20569 Fix notification's description in preferences

---
 indra/newview/skins/default/xui/en/notifications.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6c841ac049..33979885b3 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6178,7 +6178,7 @@ Are you sure you want to delete them?
     Delete the image for this item? There is no undo.
     <tag>confirm</tag>
     <usetemplate
-     ignoretext="Don't show me this again"
+     ignoretext="Warn me that thumbnail will be permanently removed"
      name="okcancelignore"
      notext="Cancel"
      yestext="Delete"/>
@@ -7021,7 +7021,7 @@ Please try again.
     You have placed a reflection probe, but 'Select Reflection Probes' is disabled. To be able to select reflection probes, check Build &gt; Options &gt; Select Reflection Probes.
     <tag>confirm</tag>
     <usetemplate
-     ignoretext="Don't show again."
+     ignoretext="Warn if Reflection Probes selection is disabled."
      name="okignore"
      yestext="OK"/>
   </notification>
-- 
cgit v1.2.3


From 4a8a3100a978989f246b7f837e8a45968908d27b Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 5 Dec 2023 00:29:17 +0200
Subject: SL-20681 fix spelling on exit prompt

---
 indra/newview/skins/default/xui/en/notifications.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 33979885b3..d642ea162c 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1534,7 +1534,7 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
    icon="alert.tga"
    name="ProfileUnsavedChanges"
    type="alertmodal">
-    You have usaved changes.
+    You have unsaved changes.
     <tag>confirm</tag>
     <tag>save</tag>
     <usetemplate
-- 
cgit v1.2.3


From 6472b75bcd70470fe5775d1cf6eb70a75b3d76e5 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Mon, 4 Dec 2023 16:50:06 -0600
Subject: SL-20611 Followup -- fix edge cases with transparent objects around
 eye/object above/below water.

---
 .../shaders/class1/deferred/fullbrightF.glsl       | 21 +++++++------
 .../shaders/class1/environment/waterFogF.glsl      | 34 ++++++++++++++++++++++
 .../shaders/class2/deferred/alphaF.glsl            |  9 ++----
 .../shaders/class3/deferred/fullbrightShinyF.glsl  |  2 --
 .../shaders/class3/deferred/materialF.glsl         |  9 ++----
 5 files changed, 48 insertions(+), 27 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 1de8b25a7d..8b2a69b924 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -35,19 +35,19 @@ in vec3 vary_position;
 in vec4 vertex_color;
 in vec2 vary_texcoord0;
 
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
-
 vec3 srgb_to_linear(vec3 cs);
 vec3 linear_to_srgb(vec3 cl);
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
 
 #ifdef HAS_ALPHA_MASK
 uniform float minimum_alpha;
 #endif
 
 #ifdef IS_ALPHA
+uniform vec4 waterPlane;
 void waterClip(vec3 pos);
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+                         out vec3 atten);
+vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
 #endif
 
 void main() 
@@ -77,21 +77,20 @@ void main()
     vec3 pos = vary_position;
 
 #ifndef IS_HUD
+    color.rgb = srgb_to_linear(color.rgb);
+    color.a = final_alpha;
+#ifdef IS_ALPHA
+
     vec3 sunlit;
     vec3 amblit;
     vec3 additive;
     vec3 atten;
     calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
 
-    color.rgb = srgb_to_linear(color.rgb);
-
-#ifdef IS_ALPHA
-    color.rgb = atmosFragLighting(color.rgb, additive, atten);
+    color.rgb = applySkyAndWaterFog(pos, additive, atten, color).rgb;
+    
 #endif
 
-    vec4 fogged = applyWaterFogViewLinear(pos, vec4(color.rgb, final_alpha));
-    color.rgb = fogged.rgb;
-    color.a   = fogged.a;
 #endif
 
     frag_color = max(color, vec4(0));
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 140e01cc2a..f796bb5f3f 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -33,6 +33,8 @@ uniform float waterFogKS;
 vec3 srgb_to_linear(vec3 col);
 vec3 linear_to_srgb(vec3 col);
 
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+
 // get a water fog color that will apply the appropriate haze to a color given
 // a blend function of (ONE, SOURCE_ALPHA)
 vec4 getWaterFogViewNoClip(vec3 pos)
@@ -108,3 +110,35 @@ vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
     return applyWaterFogViewLinearNoClip(pos, color);
 }
 
+// for post deferred shaders, apply sky and water fog in a way that is consistent with
+// the deferred rendering haze post effects
+vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color)
+{
+    bool eye_above_water = dot(vec3(0), waterPlane.xyz) + waterPlane.w > 0.0;
+    bool obj_above_water = dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0;
+
+    if (eye_above_water)
+    {
+        if (!obj_above_water)
+        { 
+            color.rgb = applyWaterFogViewLinearNoClip(pos, color).rgb;
+        }
+        else
+        {
+            color.rgb = atmosFragLighting(color.rgb, additive, atten);
+        }
+    }
+    else
+    {
+        if (obj_above_water)
+        {
+            color.rgb = atmosFragLighting(color.rgb, additive, atten);
+        }
+        else
+        {
+            color.rgb = applyWaterFogViewLinearNoClip(pos, color).rgb;
+        }
+    }
+
+    return color;
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index 07fa5cd01c..acd32a81b3 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -65,14 +65,11 @@ uniform vec3 light_diffuse[8];
 
 void waterClip(vec3 pos);
 
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
-
 vec3 srgb_to_linear(vec3 c);
 vec3 linear_to_srgb(vec3 c);
 
 vec2 encode_normal (vec3 n);
-vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
-
+vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
 void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
 
 #ifdef HAS_SUN_SHADOW
@@ -283,9 +280,7 @@ void main()
     // sum local light contrib in linear colorspace
     color.rgb += light.rgb;
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-
-    color = applyWaterFogViewLinear(pos.xyz, color);
+    color.rgb = applySkyAndWaterFog(pos.xyz, additive, atten, color).rgb;
 
 #endif // #else // FOR_IMPOSTOR
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
index 6446015b03..8430cca325 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -85,8 +85,6 @@ void main()
     color.rgb = srgb_to_linear(color.rgb);
 
     applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
-    color.rgb = atmosFragLighting(color.rgb, additive, atten);
-    color = applyWaterFogViewLinear(pos.xyz, color);
 #endif
 
 	color.a = 1.0;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index 1880f0c870..ec1e49eeb4 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -37,9 +37,7 @@
 uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise
 uniform int sun_up_factor;
 
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
-
-vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
 vec3 scaleSoftClipFragLinear(vec3 l);
 void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
 void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
@@ -399,10 +397,7 @@ void main()
 
     color += light;
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); 
-
-    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0));
-    color = temp.rgb;
+    color.rgb = applySkyAndWaterFog(pos.xyz, additive, atten, vec4(color, 1.0)).rgb;
 
     glare *= 1.0-emissive;
     glare = min(glare, 1.0);
-- 
cgit v1.2.3


From 18f42a659b98741a9d8c05731a8137080c9094b5 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Mon, 4 Dec 2023 17:01:01 -0600
Subject: SL-20611 Followup -- fix edge cases with transparent PBR objects
 around eye/object above/below water.

---
 .../app_settings/shaders/class2/deferred/pbralphaF.glsl        | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index 80c1769b15..003dd05e6f 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -82,9 +82,7 @@ vec3 srgb_to_linear(vec3 c);
 vec3 linear_to_srgb(vec3 c);
 
 void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
-vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten);
-
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
 
 void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
 float calcLegacyDistanceAttenuation(float distance, float falloff);
@@ -241,10 +239,7 @@ void main()
 
     color.rgb += light.rgb;
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-    
-    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0));
-    color = temp.rgb;
+    color.rgb = applySkyAndWaterFog(pos.xyz, additive, atten, vec4(color, 1.0)).rgb;
 
     float a = basecolor.a*vertex_color.a;
     
@@ -300,6 +295,7 @@ void main()
     
     float a = basecolor.a*vertex_color.a;
     color += colorEmissive;
+
     color = linear_to_srgb(color);
     frag_color = max(vec4(color.rgb,a), vec4(0));
 }
-- 
cgit v1.2.3


From c28eb36a2c09f31f491676c8548dfa1c19277ce2 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Tue, 5 Dec 2023 19:50:25 -0600
Subject: SL-20654 Fix for box probes sometimes glitching out at the corners. 
 Incidental fix for crash when mWaterPool is null.

---
 .../class1/deferred/postDeferredGammaCorrect.glsl   |  2 +-
 indra/newview/llreflectionmap.cpp                   | 11 ++++++++++-
 indra/newview/llreflectionmapmanager.cpp            | 21 +++++++++++++++------
 indra/newview/pipeline.cpp                          |  5 ++++-
 4 files changed, 30 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 64e6bc9da2..3443785e1a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -106,7 +106,7 @@ vec3 toneMap(vec3 color)
     color *= exposure * exp_scale;
 
     // mix ACES and Linear here as a compromise to avoid over-darkening legacy content
-    color = mix(toneMapACES_Hill(color), color, 0.333);
+    color = mix(toneMapACES_Hill(color), color, 0.3);
 #endif
 
     return color;
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index ec54fa1165..a26445b4bc 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -167,7 +167,16 @@ void LLReflectionMap::autoAdjustOrigin()
     {
         mPriority = 1;
         mOrigin.load3(mViewerObject->getPositionAgent().mV);
-        mRadius = mViewerObject->getScale().mV[0]*0.5f;
+
+        if (mViewerObject->getVolume() && ((LLVOVolume*)mViewerObject)->getReflectionProbeIsBox())
+        {
+            LLVector3 s = mViewerObject->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+            mRadius = s.magVec();
+        }
+        else
+        {
+            mRadius = mViewerObject->getScale().mV[0] * 0.5f;
+        }
     }
 }
 
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 72f7e23b0c..69674417c1 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -252,14 +252,12 @@ void LLReflectionMapManager::update()
             continue;
         }
         
-        if (probe != mDefaultProbe && 
+        if (probe != mDefaultProbe &&
             (!probe->isRelevant() || mPaused))
         { // skip irrelevant probes (or all non-default probes if paused)
             continue;
         }
 
-        
-
         LLVector4a d;
 
         if (probe != mDefaultProbe)
@@ -999,10 +997,21 @@ void LLReflectionMapManager::updateUniforms()
         llassert(refmap->mCubeIndex >= 0); // should always be  true, if not, getReflectionMaps is bugged
 
         {
-            if (refmap->mViewerObject)
+            if (refmap->mViewerObject && refmap->mViewerObject->getVolume())
             { // have active manual probes live-track the object they're associated with
-                refmap->mOrigin.load3(refmap->mViewerObject->getPositionAgent().mV);
-                refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
+                LLVOVolume* vobj = (LLVOVolume*)refmap->mViewerObject;
+
+                refmap->mOrigin.load3(vobj->getPositionAgent().mV);
+
+                if (vobj->getReflectionProbeIsBox())
+                {
+                    LLVector3 s = vobj->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+                    refmap->mRadius = s.magVec();
+                }
+                else
+                {
+                    refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
+                }
 
             }
             modelview.affineTransform(refmap->mOrigin, oa);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 50cd4adb73..bf4f0083ff 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8303,7 +8303,10 @@ void LLPipeline::doWaterHaze()
             gGLLastMatrix = NULL;
             gGL.loadMatrix(gGLModelView);
 
-            mWaterPool->pushFaceGeometry();
+            if (mWaterPool)
+            {
+                mWaterPool->pushFaceGeometry();
+            }
         }
 
         unbindDeferredShader(haze_shader);
-- 
cgit v1.2.3


From a27740bbb2da04b14016de1398178df4fb970bcd Mon Sep 17 00:00:00 2001
From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com>
Date: Mon, 27 Nov 2023 17:59:16 +0100
Subject: SL-19655 BugSplat Crash: LLGLState::checkStates (2427)

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

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bf4f0083ff..f8812d9750 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3821,10 +3821,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
 					poolp->endDeferredPass(i);
 					LLVertexBuffer::unbind();
 
-					if (gDebugGL || gDebugPipeline)
-					{
-						LLGLState::checkStates();
-					}
+					LLGLState::checkStates();
 				}
 			}
 			else
-- 
cgit v1.2.3


From d05b80817b4c7ada2b3934f0d8c814fc67c50c8e Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 6 Dec 2023 10:33:32 -0600
Subject: SL-20611 Followup -- fix banding in water fog (thanks, Rye!)

---
 indra/newview/pipeline.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bf4f0083ff..8c3cf09098 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -789,7 +789,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 
     if (LLPipeline::sRenderTransparentWater)
     { //water reflection texture
-        mWaterDis.allocate(resX, resY, GL_RGBA, true);
+        mWaterDis.allocate(resX, resY, GL_RGBA16F, true);
     }
 
 	if (RenderUIBuffer)
-- 
cgit v1.2.3


From 18919ef585082becd984eb4d90310cd317babfc9 Mon Sep 17 00:00:00 2001
From: Ansariel Hiller <Ansariel@users.noreply.github.com>
Date: Wed, 6 Dec 2023 18:04:29 +0100
Subject: BUG-234706 Fix unstable performance on nvidia systems by always
 enabling Threaded Optimization via driver application profile (#564)

---
 indra/newview/llappviewerwin32.cpp | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 8cf80f388b..41101e79a6 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -369,6 +369,35 @@ void ll_nvapi_init(NvDRSSessionHandle hSession)
 		nvapi_error(status);
 		return;
 	}
+
+	// enable Threaded Optimization instead of letting the driver decide
+	status = NvAPI_DRS_GetSetting(hSession, hProfile, OGL_THREAD_CONTROL_ID, &drsSetting);
+	if (status == NVAPI_SETTING_NOT_FOUND || (status == NVAPI_OK && drsSetting.u32CurrentValue != OGL_THREAD_CONTROL_ENABLE))
+	{
+		drsSetting.version = NVDRS_SETTING_VER;
+		drsSetting.settingId = OGL_THREAD_CONTROL_ID;
+		drsSetting.settingType = NVDRS_DWORD_TYPE;
+		drsSetting.u32CurrentValue = OGL_THREAD_CONTROL_ENABLE;
+		status = NvAPI_DRS_SetSetting(hSession, hProfile, &drsSetting);
+		if (status != NVAPI_OK)
+		{
+			nvapi_error(status);
+			return;
+		}
+
+		// Now we apply (or save) our changes to the system
+		status = NvAPI_DRS_SaveSettings(hSession);
+		if (status != NVAPI_OK)
+		{
+			nvapi_error(status);
+			return;
+		}
+	}
+	else if (status != NVAPI_OK)
+	{
+		nvapi_error(status);
+		return;
+	}
 }
 
 //#define DEBUGGING_SEH_FILTER 1
-- 
cgit v1.2.3


From 300d7629d8bbd02844a5380cc97aae2d229fdf0a Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 6 Dec 2023 11:58:45 -0600
Subject: SL-20664 Potential fix for crash on startup in switchContext

---
 indra/llwindow/llwindowwin32.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 42ec4ee29d..057d7a700e 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -1929,7 +1929,7 @@ void LLWindowWin32::toggleVSync(bool enable_vsync)
         LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL;
         wglSwapIntervalEXT(0);
     }
-    else
+    else if (wglSwapIntervalEXT)
     {
         LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL;
         wglSwapIntervalEXT(1);
-- 
cgit v1.2.3


From 7398efb1f4ccf36f9c107e920f38c3096cca2f2f Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Fri, 8 Dec 2023 20:15:47 +0200
Subject: SL-20701 FIXED Build tool texture tab shows incorrect material
 parameters in some cases

---
 indra/newview/llpanelface.cpp | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index ffcc4be290..f0f66831cb 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1094,7 +1094,21 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
                 prev_obj_id = objectp->getID();
             }
         }
-
+        else 
+        {
+            if (prev_obj_id != objectp->getID())
+            {
+                if (has_pbr_material && (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL)) 
+                {
+                    mComboMatMedia->selectNthItem(MATMEDIA_PBR);
+                }
+                else if (!has_pbr_material && (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR))
+                {
+                    mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+                }
+                prev_obj_id = objectp->getID();
+            }
+        }
         mComboMatMedia->setEnabled(editable);
 
         LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
-- 
cgit v1.2.3


From 2c2d60bbc36c58314d36770349c2f904c848e582 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Fri, 8 Dec 2023 12:36:55 -0600
Subject: SL-20674 Fix for textures ignoring texture scale when determining
 what resolution to be.

---
 indra/newview/llviewertexture.cpp     | 3 ---
 indra/newview/llviewertexturelist.cpp | 8 +++++++-
 2 files changed, 7 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ec6f2c848f..56bba51692 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -2124,9 +2124,6 @@ bool LLViewerFetchedTexture::updateFetch()
 		}
 	}
 	
-	llassert(mRawImage.notNull() || !mIsRawImageValid);
-	llassert(mRawImage.notNull() || !mNeedsCreateTexture);
-	
 	return mIsFetching ? true : false;
 }
 
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index f898fb7142..9a6d40ab0a 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -899,6 +899,13 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
                 {
                     F32 vsize = face->getPixelArea();
 
+                    // scale desired texture resolution higher or lower depending on texture scale
+                    const LLTextureEntry* te = face->getTextureEntry();
+                    F32 min_scale = te ? llmin(fabsf(te->getScaleS()), fabsf(te->getScaleT())) : 1.f;
+                    min_scale = llmax(min_scale*min_scale, 0.1f);
+
+                    vsize /= min_scale;
+
 #if LL_DARWIN
                     vsize /= 1.f + LLViewerTexture::sDesiredDiscardBias*(1.f+face->getDrawable()->mDistanceWRTCamera*bias_distance_scale);
 #else
@@ -916,7 +923,6 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
                     // if a GLTF material is present, ignore that face
                     // as far as this texture stats go, but update the GLTF material 
                     // stats
-                    const LLTextureEntry* te = face->getTextureEntry();
                     LLFetchedGLTFMaterial* mat = te ? (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial() : nullptr;
                     llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr);
                     if (mat)
-- 
cgit v1.2.3


From f3b87145775d3803306036d1e31fa39177f2600e Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 11 Dec 2023 15:28:25 -0600
Subject: SL-20611 Followup -- fix for artifacts on water surface from GPUs
 that don't like to read from a depth buffer that is bound for writing

---
 .../shaders/class3/deferred/waterHazeF.glsl        | 16 ++++++++
 .../shaders/class3/environment/underWaterF.glsl    |  1 -
 .../shaders/class3/environment/waterF.glsl         |  6 +--
 indra/newview/lldrawpoolwater.cpp                  |  9 +----
 indra/newview/pipeline.cpp                         | 45 +++++++++++++++++++---
 indra/newview/pipeline.h                           |  2 +-
 6 files changed, 60 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 025bcdaf3e..13619a82d3 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -35,10 +35,26 @@ float getDepth(vec2 pos_screen);
 
 vec4 getWaterFogView(vec3 pos);
 
+uniform int above_water;
+
 void main()
 {
     vec2  tc           = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
     float depth        = getDepth(tc.xy);
+
+    if (above_water > 0)
+    { 
+        // we want to depth test when the camera is above water, but some GPUs have a hard time
+        // with depth testing against render targets that are bound for sampling in the same shader
+        // so we do it manually here
+
+        float cur_depth = vary_fragcoord.z/vary_fragcoord.w*0.5+0.5;
+        if (cur_depth > depth)
+        {
+            discard;
+        }
+    }
+
     vec4  pos          = getPositionWithDepth(tc, depth);
     vec4  norm         = texture(normalMap, tc);
 
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index ddb1b79681..223e55eb69 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -30,7 +30,6 @@ uniform sampler2D bumpMap;
 
 #ifdef TRANSPARENT_WATER
 uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
 #endif
 
 uniform vec4 fogCol;
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index f53bc2e13e..b364e454e8 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -76,7 +76,7 @@ uniform sampler2D bumpMap2;
 uniform float     blend_factor;
 #ifdef TRANSPARENT_WATER
 uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
+uniform sampler2D depthMap;
 #endif
 
 uniform sampler2D refTex;
@@ -210,7 +210,7 @@ void main()
 
 #ifdef TRANSPARENT_WATER
     vec4 fb = texture(screenTex, distort2);
-    float depth = texture(screenDepth, distort2).r;
+    float depth = texture(depthMap, distort2).r;
     vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
 
     if (refPos.z > pos.z-0.05)
@@ -218,7 +218,7 @@ void main()
         //we sampled an above water sample, don't distort
         distort2 = distort;
         fb = texture(screenTex, distort2);
-        depth = texture(screenDepth, distort2).r;
+        depth = texture(depthMap, distort2).r;
         refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
     }
 
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 14f3142e1b..ca93815de7 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -206,7 +206,7 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
             }
         }
 
-        gPipeline.bindDeferredShader(*shader);
+        gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
 
         //bind normal map
         S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
@@ -238,7 +238,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
 
         // bind reflection texture from RenderTarget
         S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
-        S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
 
         F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
 
@@ -255,11 +254,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
             gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
         }
 
-        if (screenDepth > -1)
-        {
-            gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
-        }
-
         if (mShaderLevel == 1)
         {
             fog_color.mV[VW] = log(fog_density) / log(2);
@@ -342,7 +336,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
         shader->disableTexture(LLShaderMgr::BUMP_MAP);
         shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
         shader->disableTexture(LLShaderMgr::WATER_REFTEX);
-        shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
 
         // clean up
         gPipeline.unbindDeferredShader(*shader);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2e55b65c82..b24a8106cc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7476,7 +7476,7 @@ void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
     }
 }
 
-void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
+void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target, LLRenderTarget* depth_target)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
     LLRenderTarget* deferred_target       = &mRT->deferredScreen;
@@ -7515,7 +7515,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
     channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
     if (channel > -1)
     {
-        gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+        if (depth_target)
+        {
+            gGL.getTexUnit(channel)->bind(depth_target, TRUE);
+        }
+        else
+        {
+            gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+        }
         stop_glerror();
     }
 
@@ -8232,16 +8239,42 @@ void LLPipeline::doAtmospherics()
 
     if (RenderDeferredAtmospheric)
     {
+        if (!sUnderWaterRender)
+        {
+            // copy depth buffer for use in haze shader (use water displacement map as temp storage)
+            LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+            LLRenderTarget& src = gPipeline.mRT->screen;
+            LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+            LLRenderTarget& dst = gPipeline.mWaterDis;
+
+            mRT->screen.flush();
+            dst.bindTarget();
+            gCopyDepthProgram.bind();
+
+            S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+            S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+            gGL.getTexUnit(diff_map)->bind(&src);
+            gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+            gGL.setColorMask(false, false);
+            gPipeline.mScreenTriangleVB->setBuffer();
+            gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+            dst.flush();
+            mRT->screen.bindTarget();
+        }
+
         LLGLEnable blend(GL_BLEND);
         gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
-
         gGL.setColorMask(true, true);
 
         // apply haze
         LLGLSLShader& haze_shader = gHazeProgram;
 
         LL_PROFILE_GPU_ZONE("haze");
-        bindDeferredShader(haze_shader);
+        bindDeferredShader(haze_shader, nullptr, sUnderWaterRender ? nullptr : &mWaterDis);
 
         LLEnvironment& environment = LLEnvironment::instance();
         haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -8294,7 +8327,7 @@ void LLPipeline::doWaterHaze()
         else
         {
             //render water patches like LLDrawPoolWater does
-            LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+            /*LLGLDepthTest depth(GL_FALSE);
             LLGLDisable   cull(GL_CULL_FACE);
 
             gGLLastMatrix = NULL;
@@ -8303,7 +8336,7 @@ void LLPipeline::doWaterHaze()
             if (mWaterPool)
             {
                 mWaterPool->pushFaceGeometry();
-            }
+            }*/
         }
 
         unbindDeferredShader(haze_shader);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index bbed7cad92..88a7eab813 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -306,7 +306,7 @@ public:
     // if setup is true, wil lset texture compare mode function and filtering options
     void bindShadowMaps(LLGLSLShader& shader);
     void bindDeferredShaderFast(LLGLSLShader& shader);
-	void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
+	void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr);
 	void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
 
 	void unbindDeferredShader(LLGLSLShader& shader);
-- 
cgit v1.2.3


From 4ca23735d906c69742f4bf362eb97b87831c2ece Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 11 Dec 2023 15:40:33 -0600
Subject: SL-20611 Followup -- reenable water haze

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

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b24a8106cc..f448983ac2 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8327,7 +8327,7 @@ void LLPipeline::doWaterHaze()
         else
         {
             //render water patches like LLDrawPoolWater does
-            /*LLGLDepthTest depth(GL_FALSE);
+            LLGLDepthTest depth(GL_FALSE);
             LLGLDisable   cull(GL_CULL_FACE);
 
             gGLLastMatrix = NULL;
@@ -8336,7 +8336,7 @@ void LLPipeline::doWaterHaze()
             if (mWaterPool)
             {
                 mWaterPool->pushFaceGeometry();
-            }*/
+            }
         }
 
         unbindDeferredShader(haze_shader);
-- 
cgit v1.2.3


From 1f7f30aea4bb67bc9de9a6354085b7f0b0849617 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 11 Dec 2023 15:49:51 -0600
Subject: SL-20611 Brute force fix for water haze -- paid for by cycles saved
 by not drawing water twice, but needs a better long term solution.

---
 indra/newview/pipeline.cpp | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f448983ac2..adad22d0a8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -787,10 +787,8 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 		resY /= res_mod;
 	}
 
-    if (LLPipeline::sRenderTransparentWater)
-    { //water reflection texture
-        mWaterDis.allocate(resX, resY, GL_RGBA16F, true);
-    }
+    //water reflection texture (always needed as scratch space whether or not transparent water is enabled)
+    mWaterDis.allocate(resX, resY, GL_RGBA16F, true);
 
 	if (RenderUIBuffer)
 	{
@@ -8239,7 +8237,6 @@ void LLPipeline::doAtmospherics()
 
     if (RenderDeferredAtmospheric)
     {
-        if (!sUnderWaterRender)
         {
             // copy depth buffer for use in haze shader (use water displacement map as temp storage)
             LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
@@ -8274,7 +8271,7 @@ void LLPipeline::doAtmospherics()
         LLGLSLShader& haze_shader = gHazeProgram;
 
         LL_PROFILE_GPU_ZONE("haze");
-        bindDeferredShader(haze_shader, nullptr, sUnderWaterRender ? nullptr : &mWaterDis);
+        bindDeferredShader(haze_shader, nullptr, &mWaterDis);
 
         LLEnvironment& environment = LLEnvironment::instance();
         haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -8300,6 +8297,32 @@ void LLPipeline::doWaterHaze()
 
     if (RenderDeferredAtmospheric)
     {
+        // copy depth buffer for use in haze shader (use water displacement map as temp storage)
+        {
+            LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+            LLRenderTarget& src = gPipeline.mRT->screen;
+            LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+            LLRenderTarget& dst = gPipeline.mWaterDis;
+
+            mRT->screen.flush();
+            dst.bindTarget();
+            gCopyDepthProgram.bind();
+
+            S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+            S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+            gGL.getTexUnit(diff_map)->bind(&src);
+            gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+            gGL.setColorMask(false, false);
+            gPipeline.mScreenTriangleVB->setBuffer();
+            gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+            dst.flush();
+            mRT->screen.bindTarget();
+        }
+
         LLGLEnable blend(GL_BLEND);
         gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
 
@@ -8309,7 +8332,7 @@ void LLPipeline::doWaterHaze()
         LLGLSLShader& haze_shader = gHazeWaterProgram;
 
         LL_PROFILE_GPU_ZONE("haze");
-        bindDeferredShader(haze_shader);
+        bindDeferredShader(haze_shader, nullptr, &mWaterDis);
 
         haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
 
-- 
cgit v1.2.3


From e62a4dc8b4cdac5038c1fb8e5428248a3e195509 Mon Sep 17 00:00:00 2001
From: Henri Beauchamp <sldev@free.fr>
Date: Tue, 12 Dec 2023 01:41:42 +0100
Subject: Fix for semi-transparent HUDs rendering opaque

This commit fixes a bug introduced with commit 6472b75bcd70470fe5775d1cf6eb70a75b3d76e5
where the fullbrightF.glsl shader fails to set color.a to final_alpha for HUDs.
---
 indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 8b2a69b924..a6fab10791 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -76,9 +76,9 @@ void main()
 
     vec3 pos = vary_position;
 
+    color.a = final_alpha;
 #ifndef IS_HUD
     color.rgb = srgb_to_linear(color.rgb);
-    color.a = final_alpha;
 #ifdef IS_ALPHA
 
     vec3 sunlit;
-- 
cgit v1.2.3


From 2d3b52d02ee72d94c6299220c05e5f5343979da3 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Wed, 13 Dec 2023 00:48:05 +0200
Subject: SL-20715 Mapping mode and specular color not copied correctly

and fixed diffuse alpha
---
 indra/newview/llpanelface.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index f0f66831cb..91cc177fd5 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -4290,6 +4290,7 @@ void LLPanelFace::onCopyTexture()
                 te_data["te"]["bumpmap"] = tep->getBumpmap();
                 te_data["te"]["bumpshiny"] = tep->getBumpShiny();
                 te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright();
+                te_data["te"]["texgen"] = tep->getTexGen();
                 te_data["te"]["pbr"] = objectp->getRenderMaterialID(te);
                 if (tep->getGLTFMaterialOverride() != nullptr)
                 {
@@ -4685,6 +4686,11 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
             {
                 objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger());
             }
+            if (te_data["te"].has("texgen"))
+            {
+                objectp->setTETexGen(te, (U8)te_data["te"]["texgen"].asInteger());
+            }
+
             // PBR/GLTF
             if (te_data["te"].has("pbr"))
             {
@@ -4796,11 +4802,11 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
             LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id);
             LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id);
             LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id);
-            LLColor4 spec_color(te_data["material"]["SpecColor"]);
+            LLColor4U spec_color(te_data["material"]["SpecColor"]);
             LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te);
             LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
             LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id);
-            LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+            LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["DiffuseAlphaMode"].asInteger(), te, object_id);
             if (te_data.has("te") && te_data["te"].has("shiny"))
             {
                 objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger());
-- 
cgit v1.2.3


From 60196f6ab3697c5b6cff6b2c856449d94d56ddee Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 13 Dec 2023 12:47:04 -0600
Subject: SL-20611 Followup -- fix for impostors being invisible.

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

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index adad22d0a8..3a1edb0d00 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8235,6 +8235,11 @@ void LLPipeline::doAtmospherics()
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
 
+    if (sImpostorRender)
+    { // do not attempt atmospherics on impostors
+        return;
+    }
+
     if (RenderDeferredAtmospheric)
     {
         {
@@ -8294,6 +8299,10 @@ void LLPipeline::doAtmospherics()
 void LLPipeline::doWaterHaze()
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+    if (sImpostorRender)
+    { // do not attempt water haze on impostors
+        return;
+    }
 
     if (RenderDeferredAtmospheric)
     {
-- 
cgit v1.2.3


From fefdd5aef92e0ba7f37147d7ba057b3b0459c4bf Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 13 Dec 2023 14:47:40 -0600
Subject: SL-20730 Scrub nans from haze alpha

---
 indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl      | 4 ++--
 indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
index e8f7d73f1f..229f332b36 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -102,6 +102,6 @@ void main()
         alpha = 1.0;
     }
 
-    frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
-    frag_color.a = alpha;
+    frag_color = max(vec4(color.rgb, alpha), vec4(0)); //output linear since local lights will be added to this shader's results
+    
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 13619a82d3..f6b8299f91 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -60,6 +60,6 @@ void main()
 
     vec4 fogged = getWaterFogView(pos.xyz);
 
-    frag_color.rgb = max(fogged.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
-    frag_color.a = fogged.a;
+    frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results
+    
 }
-- 
cgit v1.2.3


From feece92f2bb7525a7b2a99170ed60a40fac7777e Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 14 Dec 2023 14:58:20 +0200
Subject: SL-20717 Add PBR to Advanced > Rendering Types

---
 indra/newview/llviewermenu.cpp                     |  4 ++++
 indra/newview/skins/default/xui/en/menu_viewer.xml | 10 ++++++++++
 2 files changed, 14 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 553eaaf9b2..9db9d97ddc 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -787,6 +787,10 @@ U32 render_type_from_string(std::string render_type)
 	{
 		return LLPipeline::RENDER_TYPE_BUMP;
 	}
+    else if ("pbr" == render_type) 
+    {
+        return LLPipeline::RENDER_TYPE_GLTF_PBR;
+    }
 	else
 	{
 		return 0;
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 2c4b03251a..660f4b62c7 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2162,6 +2162,16 @@ function="World.EnvPreset"
                  function="Advanced.ToggleRenderType"
                  parameter="bump" />
             </menu_item_check>
+            <menu_item_check
+             label="PBR"
+             name="Rendering Type PBR">
+                <menu_item_check.on_check
+                 function="Advanced.CheckRenderType"
+                 parameter="pbr" />
+                <menu_item_check.on_click
+                 function="Advanced.ToggleRenderType"
+                 parameter="pbr" />
+            </menu_item_check>
         </menu>
         <menu
          create_jump_keys="true"
-- 
cgit v1.2.3


From 1b1457154d644ce1da448445aef773666eca4a0f Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 14 Dec 2023 17:41:57 +0200
Subject: SL-20715 Mask cutoff not copied corretly in build tools

---
 indra/newview/llpanelface.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 91cc177fd5..5f8071d3eb 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -4759,8 +4759,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
         {
             LLUUID object_id = objectp->getID();
 
-            LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
-
             // Normal
             // Replace placeholders with target's
             if (te_data["material"].has("NormMapNoCopy"))
@@ -4807,6 +4805,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
             LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
             LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id);
             LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["DiffuseAlphaMode"].asInteger(), te, object_id);
+            LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["AlphaMaskCutoff"].asInteger(), te, object_id);
             if (te_data.has("te") && te_data["te"].has("shiny"))
             {
                 objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger());
-- 
cgit v1.2.3


From 9212e0944203fdbdefbaae01a89600a0050b3a36 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Thu, 14 Dec 2023 10:22:31 -0600
Subject: SL-20730 Patch another potential source of NaNs

---
 indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index 9e61b6b894..c95f791dbf 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -34,6 +34,6 @@ void main()
 {
     // NOTE: when this shader is used, only alpha is being written to
 	float a = diffuseLookup(vary_texcoord0.xy).a*vertex_color.a;
-	frag_color = vec4(0, 0, 0, a);
+	frag_color = max(vec4(0, 0, 0, a), vec4(0));
 }
 
-- 
cgit v1.2.3


From 8b86e2ad1b1326cb3e98acd857dc93f4f1455b8c Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Thu, 14 Dec 2023 14:11:46 -0600
Subject: SL-20611 Followup -- fix for depth based atmospheric mask making
 atmospherics effect sun/moon/clouds

---
 indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl | 3 +--
 indra/newview/lldrawpool.h                                    | 6 +++---
 indra/newview/lldrawpoolwlsky.cpp                             | 3 +++
 3 files changed, 7 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
index 229f332b36..0b154e82ad 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -78,13 +78,12 @@ void main()
         do_atmospherics = true;
     }
     
-
     vec3  irradiance = vec3(0);
     vec3  radiance  = vec3(0);
 
     if (depth >= 1.0)
     {
-        //should only be true of WL sky, just port over base color value
+        //should only be true of sky, clouds, sun/moon, and stars
         discard;
     }
 
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 4300670445..0925a01439 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -53,7 +53,9 @@ public:
         // before grass, so grass should be the first alpha masked pool.  Other ordering should be done
         // based on fill rate and likelihood to occlude future passes (faster, large occluders first).
         //  
-		POOL_SIMPLE = 1,
+        POOL_SKY = 1,
+        POOL_WL_SKY,
+		POOL_SIMPLE,
 		POOL_FULLBRIGHT,
 		POOL_BUMP,
 		POOL_TERRAIN,
@@ -64,8 +66,6 @@ public:
 		POOL_TREE,
 		POOL_ALPHA_MASK,
 		POOL_FULLBRIGHT_ALPHA_MASK,
-        POOL_SKY,
-        POOL_WL_SKY,
 		POOL_AVATAR,
 		POOL_CONTROL_AV, // Animesh
 		POOL_GLOW,
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 05ee328e43..b14235f25c 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -87,6 +87,9 @@ void LLDrawPoolWLSky::endDeferredPass(S32 pass)
     cloud_shader = nullptr;
     sun_shader   = nullptr;
     moon_shader  = nullptr;
+
+    // clear the depth buffer so haze shaders can use unwritten depth as a mask
+    glClear(GL_DEPTH_BUFFER_BIT);
 }
 
 void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
-- 
cgit v1.2.3


From 77395eddc911e0801e50fd693f7bbaee8046aa95 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 8 Jan 2024 14:22:05 -0500
Subject: Increment viewer version to 7.1.3 following promotion of DRTVWR-596

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 0e7b60da8a..1996c50447 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.1.2
\ No newline at end of file
+7.1.3
-- 
cgit v1.2.3