diff --git a/indra/cmake/GLM.cmake b/indra/cmake/GLM.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..66ddea30b9526bddc70d13116c76542560fc1da3
--- /dev/null
+++ b/indra/cmake/GLM.cmake
@@ -0,0 +1,7 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+add_library( ll::glm INTERFACE IMPORTED )
+
+use_system_binary(glm)
+use_prebuilt_binary(glm)
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f5672ee5d8f8f6ac6b71ff5316fca61aff007093..8c910bd4d73443bf9b47e397b062db7dbe442faf 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9785,17 +9785,6 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-  <key>RenderMirrorsAvailable</key>
-  <map>
-    <key>Comment</key>
-    <string>Renders realtime mirrors.</string>
-    <key>Persist</key>
-    <integer>0</integer>
-    <key>Type</key>
-    <string>Boolean</string>
-    <key>Value</key>
-    <integer>0</integer>
-  </map>
   <key>RenderScreenSpaceReflections</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index cd7dc154b02a63ec0de2b217ee3e01e93f88c9f3..9de57f5df380b56146dea482b1f9ea7aea933fb6 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -73,6 +73,7 @@ RenderGLMultiThreadedTextures      1   0
 RenderGLMultiThreadedMedia         1   1
 RenderReflectionProbeResolution 1 128
 RenderScreenSpaceReflections 1  1
+RenderMirrors				1	1
 RenderToneMapType 1 1
 RenderVSyncEnable 1 0
 
@@ -246,8 +247,8 @@ RenderReflectionsEnabled    1   1
 RenderReflectionProbeDetail	1	1
 RenderScreenSpaceReflections 1  0
 RenderReflectionProbeLevel  1   3
-RenderMirrors				1	0
-RenderHeroProbeResolution	1	1024
+RenderMirrors				1	1
+RenderHeroProbeResolution	1	512
 RenderHeroProbeDistance		1	8
 RenderHeroProbeUpdateRate	1	2
 RenderHeroProbeConservativeUpdateMultiplier 1 8
@@ -281,7 +282,7 @@ RenderReflectionsEnabled    1   1
 RenderReflectionProbeDetail	1	1
 RenderScreenSpaceReflections 1  0
 RenderReflectionProbeLevel  1   3
-RenderMirrors				1	0
+RenderMirrors				1	1
 RenderHeroProbeResolution	1	1024
 RenderHeroProbeDistance		1	16
 RenderHeroProbeUpdateRate	1	1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 858f83892d8ef2ce7a2ab7143b287873f3a2bdd8..c13898980a8b71fee38551f1c31960397a83c782 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -72,6 +72,7 @@ RenderReflectionsEnabled    1   1
 RenderReflectionProbeDetail	1	2
 RenderScreenSpaceReflections 1  1
 RenderReflectionProbeLevel  1   3
+RenderMirrors				1	1
 RenderToneMapType 1 1
 RenderVSyncEnable 1 0
 
@@ -244,8 +245,8 @@ RenderReflectionsEnabled    1   1
 RenderReflectionProbeDetail	1	1
 RenderScreenSpaceReflections 1  0
 RenderReflectionProbeLevel  1   1
-RenderMirrors				1	0
-RenderHeroProbeResolution	1	1024
+RenderMirrors				1	1
+RenderHeroProbeResolution	1	512
 RenderHeroProbeDistance		1	8
 RenderHeroProbeUpdateRate	1	2
 RenderHeroProbeConservativeUpdateMultiplier 1 8
@@ -279,8 +280,8 @@ RenderReflectionsEnabled    1   1
 RenderReflectionProbeDetail	1	1
 RenderScreenSpaceReflections 1  0
 RenderReflectionProbeLevel  1   2
-RenderMirrors				1	0
-RenderHeroProbeResolution	1	1024
+RenderMirrors				1	1
+RenderHeroProbeResolution	1	512
 RenderHeroProbeDistance		1	16
 RenderHeroProbeUpdateRate	1	1
 RenderHeroProbeConservativeUpdateMultiplier 1 4
@@ -315,7 +316,7 @@ RenderReflectionProbeDetail	1	1
 RenderScreenSpaceReflections 1  0
 RenderReflectionProbeLevel  1   3
 RenderMirrors				1	1
-RenderHeroProbeResolution	1	2048
+RenderHeroProbeResolution	1	1024
 RenderHeroProbeDistance		1	16
 RenderHeroProbeUpdateRate	1	1
 RenderHeroProbeConservativeUpdateMultiplier 1 4
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
index a0c6d1da984974e111989c2ae413796cf55a4a82..a340dc4b0240277e7d5e1eb7ee32450967d82c57 100644
--- a/indra/newview/llheroprobemanager.cpp
+++ b/indra/newview/llheroprobemanager.cpp
@@ -75,7 +75,7 @@ LLHeroProbeManager::~LLHeroProbeManager()
 // helper class to seed octree with probes
 void LLHeroProbeManager::update()
 {
-    if (!LLPipeline::RenderMirrorsAvailable || !LLPipeline::RenderMirrors || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE)
+    if (!LLPipeline::RenderMirrors || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE)
     {
         return;
     }
@@ -175,7 +175,6 @@ void LLHeroProbeManager::update()
             mCurrentClipPlane.setVec(hero_pos, face_normal);
             mMirrorPosition = hero_pos;
             mMirrorNormal   = face_normal;
-        
 
             probe_pos.load3(point.mV);
 
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 8908103732fb1fa31c970767b169a59b7916960c..8df70353100b5322e7eda9b1a8d2d86e371b3fe5 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -422,10 +422,6 @@ void LLPanelVolume::getState( )
 
     bool probe_enabled = is_probe && editable && single_volume;
 
-    bool mirrors_enabled = LLPipeline::RenderMirrorsAvailable;
-
-	getChildView("Probe Mirror")->setVisible(mirrors_enabled);
-
     getChildView("Probe Dynamic")->setEnabled(probe_enabled);
     getChildView("Probe Mirror")->setEnabled(probe_enabled);
     getChildView("Probe Volume Type")->setEnabled(probe_enabled);
@@ -452,6 +448,22 @@ void LLPanelVolume::getState( )
             volume_type = "Sphere";
         }
 
+//		std::string update_type = "Static";
+//
+//        if (volobjp->getReflectionProbeIsDynamic() && !volobjp->getReflectionProbeIsMirror())
+//        {
+//            update_type = "Dynamic";
+//        }
+//        else if (volobjp->getReflectionProbeIsMirror() && !volobjp->getReflectionProbeIsDynamic())
+//        {
+//            update_type = "Mirror";
+//
+//        }
+//        else if (volobjp->getReflectionProbeIsDynamic() && volobjp->getReflectionProbeIsMirror())
+//		{
+//			update_type = "Dynamic Mirror";
+//		}
+//		
         bool is_mirror = volobjp->getReflectionProbeIsMirror();
 
         getChildView("Probe Ambiance")->setEnabled(!is_mirror);
@@ -1202,6 +1214,7 @@ void LLPanelVolume::onCopyLight()
         clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance();
         clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip();
         clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic();
+        clipboard["reflection_probe"]["mirror"]    = volobjp->getReflectionProbeIsMirror();
     }
 
     mClipboardParams["light"] = clipboard;
@@ -1261,6 +1274,7 @@ void LLPanelVolume::onPasteLight()
             volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal());
             volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal());
             volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean());
+            volobjp->setReflectionProbeIsMirror(clipboard["reflection_probe"]["mirror"].asBoolean());
         }
         else
         {
@@ -1382,7 +1396,7 @@ void LLPanelVolume::onLightSelect(bool success, LLViewerObject* obj, const LLTex
 
             if (hit_volobjp->isReflectionProbe())
             {
-                volobjp->setIsReflectionProbe(TRUE);
+                volobjp->setIsReflectionProbe(true);
                 volobjp->setReflectionProbeIsBox(hit_volobjp->getReflectionProbeIsBox());
                 volobjp->setReflectionProbeAmbiance(hit_volobjp->getReflectionProbeAmbiance());
                 volobjp->setReflectionProbeNearClip(hit_volobjp->getReflectionProbeNearClip());
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index dfb35e8c81f791d26dd9ede99ac0169befe120b2..806cdb0a5be48bcda63c066899d63ae2a41c0ab7 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -2660,17 +2660,6 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
                 gSavedSettings.setS32("max_texture_dimension_Y", 1024);
             }
 
-            bool mirrors_enabled = false;
-            if (features.has("MirrorsEnabled"))
-            {
-                mirrors_enabled = features["MirrorsEnabled"].asBoolean();
-            }
-
-			if (LLPipeline::RenderMirrorsAvailable != mirrors_enabled)
-			{
-				gSavedSettings.setBOOL("RenderMirrorsAvailable", mirrors_enabled);
-			}
-
             if (features.has("PBRTerrainEnabled"))
             {
                 bool enabled = features["PBRTerrainEnabled"];
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index d0cf5fdb83a387afc736e98588ba6d07cf899a1f..5f1caf6e192b47092abca4018adc2a0fba83238e 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3439,8 +3439,15 @@ bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
     {
         if (param_block->getIsMirror() != is_mirror)
         {
+            LL_INFOS() << "Setting reflection probe mirror to " << is_mirror << LL_ENDL;
             param_block->setIsMirror(is_mirror);
             parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+
+			if (!is_mirror)
+				gPipeline.mHeroProbeManager.unregisterViewerObject(this);
+			else
+				gPipeline.mHeroProbeManager.registerViewerObject(this);
+
             return true;
         }
     }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1a609534881d5006d8620f67392bd7a952c11dbb..589a8a1a385853f822d8f6c03b4f714e46286e4b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -216,7 +216,6 @@ F32 LLPipeline::RenderScreenSpaceReflectionAdaptiveStepMultiplier;
 S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples;
 S32 LLPipeline::RenderBufferVisualization;
 bool LLPipeline::RenderMirrors;
-bool LLPipeline::RenderMirrorsAvailable;
 S32 LLPipeline::RenderHeroProbeUpdateRate;
 S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier;
 F32 LLPipeline::RenderNormalMapScale;
@@ -590,7 +589,6 @@ void LLPipeline::init()
     connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionGlossySamples");
 	connectRefreshCachedSettingsSafe("RenderBufferVisualization");
     connectRefreshCachedSettingsSafe("RenderMirrors");
-	connectRefreshCachedSettingsSafe("RenderMirrorsAvailable");
     connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate");
     connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier");
 	connectRefreshCachedSettingsSafe("RenderNormalMapScale");
@@ -1148,7 +1146,6 @@ void LLPipeline::refreshCachedSettings()
     RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier");
     RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples");
 	RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization");
-	RenderMirrorsAvailable = gSavedSettings.getBOOL("RenderMirrorsAvailable");
     if (gSavedSettings.getBOOL("RenderMirrors") != (BOOL)RenderMirrors)
     {
         RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c2168967b722f3ee815433e5cde010a9a4e476fd..d27d1dc93ef1dc0e81fb6020f2abdf92d05b9d1b 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -1052,7 +1052,6 @@ class LLPipeline
 	static S32 RenderScreenSpaceReflectionGlossySamples;
 	static S32 RenderBufferVisualization;
 	static bool RenderMirrors;
-	static bool RenderMirrorsAvailable;
 	static S32 RenderHeroProbeUpdateRate;
     static S32 RenderHeroProbeConservativeUpdateMultiplier;
 	static F32 RenderNormalMapScale;