diff --git a/src/Globals.cpp b/src/Globals.cpp index 21f117fe0f..6f604d1b01 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -106,6 +106,7 @@ namespace globals RE::BSUtilityShader* utilityShader = nullptr; RE::Sky* sky = nullptr; RE::UI* ui = nullptr; + RE::Main* main = nullptr; RE::BSGraphics::PixelShader** currentPixelShader = nullptr; RE::BSGraphics::VertexShader** currentVertexShader = nullptr; @@ -197,6 +198,7 @@ namespace globals void OnDataLoaded() { using namespace game; + main = RE::Main::GetSingleton(); sky = RE::Sky::GetSingleton(); utilityShader = RE::BSUtilityShader::GetSingleton(); @@ -206,6 +208,13 @@ namespace globals shadowMaskQuarter = RE::GetINISetting("iShadowMaskQuarter:Display"); } + void OnGameWindowClose() + { + if (shaderCache) { + shaderCache->StopCompilation(); + } + } + /** * @brief Caches the current frame buffer data and clears the mapped pointer. * diff --git a/src/Globals.h b/src/Globals.h index 188b0ccdde..7459877c25 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -219,6 +219,7 @@ namespace globals extern RE::BSUtilityShader* utilityShader; extern RE::Sky* sky; extern RE::UI* ui; + extern RE::Main* main; extern RE::BSGraphics::PixelShader** currentPixelShader; extern RE::BSGraphics::VertexShader** currentVertexShader; @@ -255,5 +256,6 @@ namespace globals void OnInit(); void ReInit(); void OnDataLoaded(); + void OnGameWindowClose(); void InstallD3DHooks(ID3D11DeviceContext* a_context); } \ No newline at end of file diff --git a/src/Hooks.cpp b/src/Hooks.cpp index d29a3f04ad..3328083290 100644 --- a/src/Hooks.cpp +++ b/src/Hooks.cpp @@ -465,6 +465,9 @@ namespace Hooks if ((a_msg == WM_KILLFOCUS || a_msg == WM_SETFOCUS) && menu->initialized) { menu->focusChanged = true; } + if (a_msg == WM_CLOSE) { + globals::OnGameWindowClose(); + } return func(a_hwnd, a_msg, a_wParam, a_lParam); } static inline REL::Relocation func; diff --git a/src/ShaderCache.cpp b/src/ShaderCache.cpp index 0c6e48450f..38bbe586ab 100644 --- a/src/ShaderCache.cpp +++ b/src/ShaderCache.cpp @@ -2206,6 +2206,15 @@ namespace SIE return compilationSet.totalTasks && compilationSet.completedTasks + compilationSet.failedTasks < compilationSet.totalTasks; } + void ShaderCache::StopCompilation() + { + if (IsCompiling()) { + logger::info("Stopping {} remaining shader compilation tasks", compilationSet.totalTasks - compilationSet.completedTasks - compilationSet.failedTasks); + } + ssource.request_stop(); + compilationSet.Clear(); + } + bool ShaderCache::IsEnabled() const { return isEnabled; diff --git a/src/ShaderCache.h b/src/ShaderCache.h index 4a60279c84..e73ccb7ac1 100644 --- a/src/ShaderCache.h +++ b/src/ShaderCache.h @@ -332,6 +332,7 @@ namespace SIE void SetAsync(bool value); bool IsDump() const; void SetDump(bool value); + void StopCompilation(); bool IsDiskCache() const; void SetDiskCache(bool value); diff --git a/src/XSEPlugin.cpp b/src/XSEPlugin.cpp index 4dde1fab6f..eaa13bdd48 100644 --- a/src/XSEPlugin.cpp +++ b/src/XSEPlugin.cpp @@ -113,10 +113,18 @@ void MessageHandler(SKSE::MessagingInterface::Message* message) auto shaderCache = globals::shaderCache; shaderCache->menuLoaded = true; - while (shaderCache->IsCompiling() && !shaderCache->backgroundCompilation) { + + auto* main = globals::game::main; + + while (shaderCache->IsCompiling() && !shaderCache->backgroundCompilation && !(main && main->quitGame)) { std::this_thread::sleep_for(100ms); } + if (main && main->quitGame) { + logger::info("Game was closed, skipping feature DataLoaded methods"); + break; + } + if (shaderCache->IsDiskCache()) { shaderCache->WriteDiskCacheInfo(); }