diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index 7d3a92237b4a0fd69e9746f625835a674b1cb06d..1debd33953a22258b1373af387dbd24c95c7a4af 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -110,6 +110,8 @@ LLCubeMapArray::~LLCubeMapArray()
 void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL use_mips)
 {
     U32 texname = 0;
+    mWidth = resolution;
+    mCount = count;
 
     LLImageGL::generateTextures(1, &texname);
 
diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h
index 19c86278a137277ba1da5f541a24d4ff79a07bb9..6c3f7dc8907af8504205da91a9cf40b178de0cb6 100644
--- a/indra/llrender/llcubemaparray.h
+++ b/indra/llrender/llcubemaparray.h
@@ -60,9 +60,17 @@ class LLCubeMapArray : public LLRefCount
 
 	void destroyGL();
 
+    // get width of cubemaps in array (they're cubes, so this is also the height)
+    U32 getWidth() const { return mWidth; }
+
+    // get number of cubemaps in the array
+    U32 getCount() const { return mCount; }
+
 protected:
 	friend class LLTexUnit;
 	~LLCubeMapArray();
 	LLPointer<LLImageGL> mImage;
+    U32 mWidth = 0;
+    U32 mCount = 0;
 	S32 mTextureStage;
 };
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 283c97ff0a18cf5e64b2623c4b877827fd954fd5..72f7e23b0cd0463f73a5af33778d2fc7823a3951 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -1258,13 +1258,18 @@ void LLReflectionMapManager::initReflectionMaps()
         mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512));
         mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1
 
-        mTexture = new LLCubeMapArray();
+        if (mTexture.isNull() ||
+            mTexture->getWidth() != mProbeResolution ||
+            mReflectionProbeCount + 2 != mTexture->getCount())
+        {
+            mTexture = new LLCubeMapArray();
 
-        // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
-        mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+            // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
+            mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
 
-        mIrradianceMaps = new LLCubeMapArray();
-        mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE);
+            mIrradianceMaps = new LLCubeMapArray();
+            mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE);
+        }
 
         // reset probe state
         mUpdatingFace = 0;
@@ -1272,6 +1277,9 @@ void LLReflectionMapManager::initReflectionMaps()
         mRadiancePass = false;
         mRealtimeRadiancePass = false;
 
+        // if default probe already exists, remember whether or not it's complete (SL-20498)
+        bool default_complete = mDefaultProbe.isNull() ? false : mDefaultProbe->mComplete;
+
         for (auto& probe : mProbes)
         {
             probe->mLastUpdateTime = 0.f;
@@ -1299,6 +1307,8 @@ void LLReflectionMapManager::initReflectionMaps()
         mDefaultProbe->mDistance = 64.f;
         mDefaultProbe->mRadius = 4096.f;
         mDefaultProbe->mProbeIndex = 0;
+        mDefaultProbe->mComplete = default_complete;
+
         touch_default_probe(mDefaultProbe);
 
     }