diff --git a/Code/immersive_launcher/Launcher.cpp b/Code/immersive_launcher/Launcher.cpp index 0547a00de..50334d198 100644 --- a/Code/immersive_launcher/Launcher.cpp +++ b/Code/immersive_launcher/Launcher.cpp @@ -7,6 +7,7 @@ #include "loader/PathRerouting.h" #include "Utils/Error.h" +#include "Utils/NvidiaUtil.h" #include "Utils/FileVersion.inl" #include "oobe/PathSelection.h" @@ -16,6 +17,7 @@ #include "base/dialogues/win/TaskDialog.h" #include +#include // These symbols are defined within the client code skyrimtogetherclient extern void InstallStartHook(); @@ -101,6 +103,13 @@ int StartUp(int argc, char** argv) if (!oobe::SelectInstall(askSelect)) DIE_NOW(L"Failed to select game install."); + if (IsNvidiaOverlayLoaded()) + { + HRESULT hr = CreateEarlyDxSwapChain(); + if (FAILED(hr)) + spdlog::error("D3D11CreateDeviceAndSwapChain failed! (Detected an NVIDIA GPU, error code={})", hr); + } + // Bind path environment. loader::InstallPathRouting(LC->gamePath); steam::Load(LC->gamePath); diff --git a/Code/immersive_launcher/Main.cpp b/Code/immersive_launcher/Main.cpp index a83c6a9aa..712dd8b30 100644 --- a/Code/immersive_launcher/Main.cpp +++ b/Code/immersive_launcher/Main.cpp @@ -20,9 +20,10 @@ extern "C" } auto kSystemPreloadDlls = { - L"\\dinput8.dll", // < Skyrim early init hook - L"\\dsound.dll", // < breaks DSound init in game code - // < X360CE v3 is buggy with COM hooks + L"\\dinput8.dll", // < Skyrim early init hook + L"\\dsound.dll", // < breaks DSound init in game code + // < X360CE v3 is buggy with COM hooks + L"\\nvspcap64.dll", // < Nvidia overlay, needs to be loaded before the swap chain creation L"\\xinput9_1_0.dll", L"\\xinput1_1.dll", L"\\xinput1_2.dll", L"\\xinput1_3.dll", L"\\xinput1_4.dll", L"\\version.dll"}; static void PreloadSystemDlls() diff --git a/Code/immersive_launcher/utils/NvidiaUtil.cpp b/Code/immersive_launcher/utils/NvidiaUtil.cpp new file mode 100644 index 000000000..283f9fe67 --- /dev/null +++ b/Code/immersive_launcher/utils/NvidiaUtil.cpp @@ -0,0 +1,17 @@ +#include +#include + +bool IsNvidiaOverlayLoaded() +{ + return GetModuleHandleW(L"nvspcap64.dll"); +} + +// This makes the Nvidia overlay happy. +// The call to D3D11CreateDeviceAndSwapChain probably causes some of their +// internal hooks to be called and do the required init work before the game window opens. +HRESULT CreateEarlyDxSwapChain() +{ + ID3D11Device* device; + return D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, + nullptr, nullptr, &device, nullptr, nullptr); +} diff --git a/Code/immersive_launcher/utils/NvidiaUtil.h b/Code/immersive_launcher/utils/NvidiaUtil.h new file mode 100644 index 000000000..cdba83513 --- /dev/null +++ b/Code/immersive_launcher/utils/NvidiaUtil.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +bool IsNvidiaOverlayLoaded(); + +HRESULT CreateEarlyDxSwapChain();