diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index 0d8aae6e3000e019abfeba66bdccb1bb52739e7c..818faed59190cb14bc9e2c4af45bdeb18962c6ce 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -113,6 +113,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 e49cdc8ada4451bfbd16cab5751ef5983fddf005..9134e08d31a367e1c3a8e5416abe65a247bcbce1 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -1240,13 +1240,18 @@ void LLReflectionMapManager::initReflectionMaps()
         mProbeResolution = probe_resolution;
         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;
@@ -1254,6 +1259,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;
@@ -1281,6 +1289,8 @@ void LLReflectionMapManager::initReflectionMaps()
         mDefaultProbe->mDistance = 64.f;
         mDefaultProbe->mRadius = 4096.f;
         mDefaultProbe->mProbeIndex = 0;
+        mDefaultProbe->mComplete = default_complete;
+
         touch_default_probe(mDefaultProbe);
     }