diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index f814458cdb6fb895ccfc58287f53dc58789848cb..7947587800197971df4d71a06fb26899ab1409f1 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -313,6 +313,11 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
 
     void run() override;
 
+    void glReady()
+    {
+        mGLReady = true;
+    }
+
     // initialzie DXGI adapter (for querying available VRAM)
     void initDX();
     
@@ -371,6 +376,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
     HWND mWindowHandle = NULL;
     HDC mhDC = 0;
 
+    // *HACK: Attempt to prevent startup crashes by deferring memory accounting
+    // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
+    bool mGLReady = false;
     // best guess at available video memory in MB
     std::atomic<U32> mAvailableVRAM;
 
@@ -1829,6 +1837,13 @@ const	S32   max_format  = (S32)num_formats - 1;
 	// ok to post quit messages now
 	mPostQuit = TRUE;
 
+    // *HACK: Attempt to prevent startup crashes by deferring memory accounting
+    // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
+    mWindowThread->post([=]()
+    {
+        mWindowThread->glReady();
+    });
+
 	if (auto_show)
 	{
 		show();
@@ -4749,6 +4764,8 @@ void debugEnumerateGraphicsAdapters()
 
 void LLWindowWin32::LLWindowWin32Thread::initDX()
 {
+    if (!mGLReady) { return; }
+
     if (mDXGIAdapter == NULL)
     {
         debugEnumerateGraphicsAdapters();
@@ -4783,6 +4800,8 @@ void LLWindowWin32::LLWindowWin32Thread::initDX()
 
 void LLWindowWin32::LLWindowWin32Thread::initD3D()
 {
+    if (!mGLReady) { return; }
+
     if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0)
     {
         mD3D = Direct3DCreate9(D3D_SDK_VERSION);
@@ -4809,6 +4828,8 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
 void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
 {
     LL_PROFILE_ZONE_SCOPED;
+    if (!mGLReady) { return; }
+
     if (mDXGIAdapter != nullptr)
     {
         // NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware
@@ -4882,8 +4903,6 @@ void LLWindowWin32::LLWindowWin32Thread::run()
     sWindowThreadId = std::this_thread::get_id();
     LogChange logger("Window");
 
-    initDX();
-
     //as good a place as any to up the MM timer resolution (see ms_sleep)
     //attempt to set timer resolution to 1ms
     TIMECAPS tc;
@@ -4896,9 +4915,12 @@ void LLWindowWin32::LLWindowWin32Thread::run()
     {
         LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;
 
+        // lazily call initD3D inside this loop to catch when mGLReady has been set to true
+        initDX();
+
         if (mWindowHandle != 0)
         {
-            // lazily call initD3D inside this loop to catch when mWindowHandle has been set
+            // lazily call initD3D inside this loop to catch when mWindowHandle has been set, and mGLReady has been set to true
             // *TODO: Shutdown if this fails when mWindowHandle exists
             initD3D();
 
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 5a086e588dce320194eeb2bdb8d4cd5f407983c7..a6341d9c9a5895ae8b5a1209f889e816ceadc343 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -5127,7 +5127,7 @@ void LLControlAVBridge::updateSpatialExtents()
 	// disappear when root goes off-screen"
 	//
 	// Expand extents to include Control Avatar placed outside of the bounds
-	if (controlAvatar && (rootWasDirty || controlAvatar->mPlaying))
+	if (controlAvatar && controlAvatar->mDrawable && (rootWasDirty || controlAvatar->mPlaying))
 	{
 		root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform());
 	}