Skip to content

Commit

Permalink
Repair Nvidia black-screen fix to reenable ENB mod loading.
Browse files Browse the repository at this point in the history
The ENB mod places a proxy DLL in the SkyrimSE.exe directory to hook the D3D11 functions it needs. But SkyrimTogether.exe launches from a different directory, so the default DLL search path doesn't find it. Check for existence of the DLL and load it if found.

Also fixes a minor invocation bug.
  • Loading branch information
rfortier committed Oct 30, 2024
1 parent b84f9e8 commit 5c120d1
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
19 changes: 16 additions & 3 deletions Code/client/NvidiaUtil.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "NvidiaUtil.h"
#include "immersive_launcher/launcher.h"
#include <d3d11.h>

bool IsNvidiaOverlayLoaded()
Expand All @@ -9,8 +10,20 @@ bool IsNvidiaOverlayLoaded()
// This makes the Nvidia overlay happy.
// The call to D3D11CreateDevice probably causes some of their
// internal hooks to be called and do the required init work before the game window opens.
HRESULT CreateEarlyDxDevice(ID3D11Device* apOutDevice, D3D_FEATURE_LEVEL* apOutFeatureLevel)
HRESULT CreateEarlyDxDevice(ID3D11Device** appOutDevice, D3D_FEATURE_LEVEL* apOutFeatureLevel)
{
return D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &apOutDevice,
apOutFeatureLevel, nullptr);
// ENB (https://enbdev.org) works by injecting a proxy d3d11.dll into the SkyrimSE.exe
// directory. It won't be loaded if SkyrimTogether.exe compile-time links to d3d11.dll,
// as it is in a different directory. To fix, launch ENB version if it is there, otherwise
// launch via the standard search path.
auto LC = launcher::GetLaunchContext();
auto d3d11Path = LC->gamePath / "d3d11.dll";
auto pModule = LoadLibraryExW(d3d11Path.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);

// If that failed, standard lookup.
if (!pModule)
pModule = LoadLibraryExW(d3d11Path.filename().c_str(), nullptr, 0);
const auto pD3D11CreateDevice = reinterpret_cast<decltype(&D3D11CreateDevice)>(GetProcAddress(pModule, "D3D11CreateDevice"));

return pD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, appOutDevice, apOutFeatureLevel, nullptr);
}
2 changes: 1 addition & 1 deletion Code/client/NvidiaUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@

bool IsNvidiaOverlayLoaded();

HRESULT CreateEarlyDxDevice(ID3D11Device* apOutDevice, D3D_FEATURE_LEVEL* apOutFeatureLevel);
HRESULT CreateEarlyDxDevice(ID3D11Device** appOutDevice, D3D_FEATURE_LEVEL* apOutFeatureLevel);
6 changes: 3 additions & 3 deletions Code/client/TiltedOnlineApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ void TiltedOnlineApp::UninstallHooks()

void TiltedOnlineApp::ApplyNvidiaFix() noexcept
{
auto d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0;
HRESULT hr = CreateEarlyDxDevice(m_pDevice, &d3dFeatureLevel);
D3D_FEATURE_LEVEL d3dFeatureLevelOut;
HRESULT hr = CreateEarlyDxDevice(&m_pDevice, &d3dFeatureLevelOut);
if (FAILED(hr))
spdlog::error("D3D11CreateDevice failed. Detected an NVIDIA GPU, error code={0:x}", hr);

if (d3dFeatureLevel < D3D_FEATURE_LEVEL_11_0)
if (d3dFeatureLevelOut < D3D_FEATURE_LEVEL_11_0)
spdlog::warn("Unexpected D3D11 feature level detected (< 11.0), may cause issues");
}

0 comments on commit 5c120d1

Please sign in to comment.