Skip to content

Commit

Permalink
DisableDevWatermark: method to disable DLSS FrameGen watermark
Browse files Browse the repository at this point in the history
currently only supported on 3.1.10 / 1.10.0 FrameGen DLL
  • Loading branch information
emoose committed Mar 28, 2023
1 parent 98a8de3 commit 0b56a6e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 5 deletions.
9 changes: 5 additions & 4 deletions dlsstweaks.ini
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ OverrideAutoExposure = 0
OverrideDlssHud = 0

; DisableDevWatermark: removes watermark shown when using dev DLL
; Only useful if you're using special dev version of DLSS, most won't need this
; Can also remove watermark on certain versions of DLSSG/FrameGeneration
; Only useful if you're using a dev version of DLSS, most won't need this
DisableDevWatermark = false

; WatchIniUpdates: watches the dlsstweaks.ini file for updates & tries applying changes during runtime
Expand All @@ -64,16 +65,16 @@ WatchIniUpdates = false
; (eg. RGL launcher which always overwrites DLSS with an older version)
; Can also be useful if you use a global injector setup & want every game to use a single DLSS DLL
;
; Format of this section is the following
; Format of this section is the following:
; (note that ";" indicates the line is a comment, remove it for DLSSTweaks to use that line)
;[DLL name] = [path to load from]
; For example:
;nvngx_dlss = nvngx_dlss_new.dll
;
; Full paths can also be specified too, including spaces (no need to use double-quotes around it)
; Full paths can also be specified too, including spaces (no need to use double-quotes around it):
;nvngx_dlss = C:\Users\Username\Desktop\DLSS Releases\3.1.11\rel\nvngx_dlss.dll
;
; Other DLLs can also be overridden using this too (it's only recommended to use this on DLSS related files however), eg:
; Other DLLs such as DLSS FrameGen (nvngx_dlssg) can also be overridden using this too (it's only recommended to use this on DLSS related files however):
;nvngx_dlssg = C:\Users\Username\Desktop\DLSS Releases\DLSS FrameGen\3.1.10\nvngx_dlssg.dll

[DLSSQualityLevels]
Expand Down
4 changes: 4 additions & 0 deletions src/DLSSTweaks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ namespace nvngx_dlss
{
void init(HMODULE ngx_module);
};
namespace nvngx_dlssg
{
void init(HMODULE ngx_module);
};

// wrapper struct on top of SafetyHookInline
// can either call the hook trampoline via SafetyHookInline, or call a specified function if dest_proc is set
Expand Down
11 changes: 10 additions & 1 deletion src/DllMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
const wchar_t* NgxFileName = L"_nvngx.dll";
const wchar_t* DlssFileName = L"nvngx_dlss.dll";
const char* DlssFileNameA = "nvngx_dlss.dll";
const wchar_t* DlssgFileName = L"nvngx_dlssg.dll";
const char* DlssgFileNameA = "nvngx_dlssg.dll";

const wchar_t* LogFileName = L"dlsstweaks.log";
const wchar_t* IniFileName = L"dlsstweaks.ini";
Expand Down Expand Up @@ -121,11 +123,14 @@ void __stdcall LoaderNotificationCallback(unsigned long notification_reason, con
{
if (notification_reason == LDR_DLL_NOTIFICATION_REASON_LOADED)
{
// If user has overridden the nvngx_dlss path, use the filename they specified in our comparisons below
std::wstring dlssName = DlssFileName;
std::wstring dlssgName = DlssgFileName;

// If user has overridden the nvngx_dlss path, use the filename they specified in our comparisons below
if (settings.dllPathOverrides.count(DlssFileNameA))
dlssName = settings.dllPathOverrides[DlssFileNameA].filename().wstring();
if (settings.dllPathOverrides.count(DlssgFileNameA))
dlssgName = settings.dllPathOverrides[DlssgFileNameA].filename().wstring();

// A module was loaded in, check if NGX/DLSS and apply hooks if so
std::wstring dllName(notification_data->Loaded.BaseDllName->Buffer, notification_data->Loaded.BaseDllName->Length / sizeof(WCHAR));
Expand All @@ -137,6 +142,10 @@ void __stdcall LoaderNotificationCallback(unsigned long notification_reason, con
{
nvngx_dlss::init((HMODULE)notification_data->Loaded.DllBase);
}
else if (!_wcsicmp(dllName.c_str(), dlssgName.c_str()))
{
nvngx_dlssg::init((HMODULE)notification_data->Loaded.DllBase);
}
}
}

Expand Down
49 changes: 49 additions & 0 deletions src/HooksNvngxDlss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,52 @@ void init(HMODULE ngx_module)
dllmain = safetyhook::create_inline(utility::ModuleEntryPoint(ngx_module), hooked_dllmain);
}
};

namespace nvngx_dlssg
{
// Currently only patches out watermark text on select builds
void init(HMODULE ngx_module)
{
if (settings.disableAllTweaks)
return;
if (!settings.disableDevWatermark)
return;

// Check if we support this dlssg build, currently only 3.1.10 / 1.10.0 dev supported
// (unfortunately haven't found a safe way to genericise this patch atm...)
uint8_t* base = (uint8_t*)ngx_module;
IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)base;
IMAGE_NT_HEADERS* nt_headers = (IMAGE_NT_HEADERS*)(base + dos_header->e_lfanew);
if (nt_headers->FileHeader.TimeDateStamp != 1678805300)
{
spdlog::warn("DisableDevWatermark: dlssg patch not applied as version is unknown");
return;
}

uint8_t expectedBytes[] = {
0x40, 0x55,
0x56,
0x57,
0x41, 0x54,
0x41, 0x55,
0x41, 0x56,
0x41, 0x57,
0x48, 0x8D, 0xAC, 0x24, 0x30, 0xFF, 0xFF, 0xFF,
0x48, 0x81, 0xEC, 0xD0, 0x01, 0x00, 0x00,
0x48, 0xC7, 0x45, 0x60, 0xFE, 0xFF, 0xFF, 0xFF
};
uint8_t* patchAddress = base + 0xB5E30;
if (memcmp(patchAddress, expectedBytes, sizeof(expectedBytes)) != 0)
{
spdlog::warn("DisableDevWatermark: dlssg patch not applied as expected bytes weren't found");
return;
}

{
UnprotectMemory unprotect{ (uintptr_t)patchAddress, 1 };
*patchAddress = 0xC3; // ret
}

spdlog::info("DisableDevWatermark: dlssg patch applied");
}
};

0 comments on commit 0b56a6e

Please sign in to comment.