diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-05-30 13:46:22 +0300 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-06-03 10:08:35 +0300 |
commit | 08c483c2693153f49cfacb8cf517cf6067f53205 (patch) | |
tree | 934205ec0bf0b835b1303aa5665efe237e78875d /indra/llwindow | |
parent | 7e645bd42d6e9cf403c4b4b7d7eb070c5bb1ebf3 (diff) |
viewer#1583 [Win] Viewer fails to detect more than 4Gb of video memory
Diffstat (limited to 'indra/llwindow')
-rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 163 |
1 files changed, 40 insertions, 123 deletions
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 7ea53816cf..92702b3ffa 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -361,14 +361,8 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool mGLReady = true; } - // initialzie DXGI adapter (for querying available VRAM) - void initDX(); - - // initialize D3D (if DXGI cannot be used) - void initD3D(); - - //clean up DXGI/D3D resources - void cleanupDX(); + // Use DXGI to check memory (because WMI doesn't report more than 4Gb) + void checkDXMem(); /// called by main thread to post work to this window thread template <typename CALLABLE> @@ -417,12 +411,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool // *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; + bool mGotGLBuffer = false; U32 mMaxVRAM = 0; // maximum amount of vram to allow in the "budget", or 0 for no maximum (see updateVRAMUsage) - - IDXGIAdapter3* mDXGIAdapter = nullptr; - LPDIRECT3D9 mD3D = nullptr; - LPDIRECT3DDEVICE9 mD3DDevice = nullptr; }; @@ -4631,39 +4622,55 @@ private: std::string mPrev; }; -// Print hardware debug info about available graphics adapters in ordinal order -void debugEnumerateGraphicsAdapters() +void LLWindowWin32::LLWindowWin32Thread::checkDXMem() { - LL_INFOS("Window") << "Enumerating graphics adapters..." << LL_ENDL; + if (!mGLReady || mGotGLBuffer) { return; } + + IDXGIFactory4* p_factory = nullptr; + + HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&p_factory); - IDXGIFactory1* factory; - HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory); - if (FAILED(res) || !factory) + if (FAILED(res)) { LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL; } else { + IDXGIAdapter3* p_dxgi_adapter = nullptr; UINT graphics_adapter_index = 0; - IDXGIAdapter3* dxgi_adapter; while (true) { - res = factory->EnumAdapters(graphics_adapter_index, reinterpret_cast<IDXGIAdapter**>(&dxgi_adapter)); + res = p_factory->EnumAdapters(graphics_adapter_index, reinterpret_cast<IDXGIAdapter**>(&p_dxgi_adapter)); if (FAILED(res)) { if (graphics_adapter_index == 0) { LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; } - else - { - LL_INFOS("Window") << "Done enumerating graphics adapters" << LL_ENDL; - } } else { + if (graphics_adapter_index == 0) // Should it check largest one isntead of first? + { + DXGI_QUERY_VIDEO_MEMORY_INFO info; + p_dxgi_adapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); + + // Alternatively use GetDesc from below to get adapter's memory + UINT64 budget_mb = info.Budget / (1024 * 1024); + if (gGLManager.mVRAM < (S32)budget_mb) + { + gGLManager.mVRAM = (S32)budget_mb; + LL_INFOS("RenderInit") << "New VRAM Budget (DX9): " << gGLManager.mVRAM << " MB" << LL_ENDL; + } + else + { + LL_INFOS("RenderInit") << "VRAM Budget (DX9): " << budget_mb + << " MB, current (WMI): " << gGLManager.mVRAM << " MB" << LL_ENDL; + } + } + DXGI_ADAPTER_DESC desc; - dxgi_adapter->GetDesc(&desc); + p_dxgi_adapter->GetDesc(&desc); std::wstring description_w((wchar_t*)desc.Description); std::string description(description_w.begin(), description_w.end()); LL_INFOS("Window") << "Graphics adapter index: " << graphics_adapter_index << ", " @@ -4676,10 +4683,10 @@ void debugEnumerateGraphicsAdapters() << "SharedSystemMemory: " << desc.SharedSystemMemory / 1024 / 1024 << LL_ENDL; } - if (dxgi_adapter) + if (p_dxgi_adapter) { - dxgi_adapter->Release(); - dxgi_adapter = NULL; + p_dxgi_adapter->Release(); + p_dxgi_adapter = NULL; } else { @@ -4690,95 +4697,12 @@ void debugEnumerateGraphicsAdapters() } } - if (factory) + if (p_factory) { - factory->Release(); + p_factory->Release(); } -} - -void LLWindowWin32::LLWindowWin32Thread::initDX() -{ - if (!mGLReady) { return; } - - if (mDXGIAdapter == NULL) - { - debugEnumerateGraphicsAdapters(); - IDXGIFactory4* pFactory = nullptr; - - HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&pFactory); - - if (FAILED(res)) - { - LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL; - } - else - { - res = pFactory->EnumAdapters(0, reinterpret_cast<IDXGIAdapter**>(&mDXGIAdapter)); - if (FAILED(res)) - { - LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; - } - else - { - LL_INFOS() << "EnumAdapters success" << LL_ENDL; - } - } - - if (pFactory) - { - pFactory->Release(); - } - } -} - -void LLWindowWin32::LLWindowWin32Thread::initD3D() -{ - if (!mGLReady) { return; } - - if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandleThrd != 0) - { - mD3D = Direct3DCreate9(D3D_SDK_VERSION); - - D3DPRESENT_PARAMETERS d3dpp; - - ZeroMemory(&d3dpp, sizeof(d3dpp)); - d3dpp.Windowed = TRUE; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - - HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandleThrd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); - - if (FAILED(res)) - { - LL_WARNS() << "(fallback) CreateDevice failed: 0x" << std::hex << res << LL_ENDL; - } - else - { - LL_INFOS() << "(fallback) CreateDevice success" << LL_ENDL; - } - } -} - -void LLWindowWin32::LLWindowWin32Thread::cleanupDX() -{ - //clean up DXGI/D3D resources - if (mDXGIAdapter) - { - mDXGIAdapter->Release(); - mDXGIAdapter = nullptr; - } - - if (mD3DDevice) - { - mD3DDevice->Release(); - mD3DDevice = nullptr; - } - - if (mD3D) - { - mD3D->Release(); - mD3D = nullptr; - } + mGotGLBuffer = true; } void LLWindowWin32::LLWindowWin32Thread::run() @@ -4798,15 +4722,11 @@ 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(); + // Check memory budget using DirectX + checkDXMem(); if (mWindowHandleThrd != 0) { - // 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(); - MSG msg; BOOL status; if (mhDCThrd == 0) @@ -4847,8 +4767,6 @@ void LLWindowWin32::LLWindowWin32Thread::run() } #endif } - - cleanupDX(); } void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() @@ -4948,7 +4866,6 @@ void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() // very unsafe TerminateThread(pair.second.native_handle(), 0); pair.second.detach(); - cleanupDX(); } } LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL; |