Capture pre-NGX command signatures through early OptiScaler device discovery

This commit is contained in:
Codex committed 2026-10-01 16:48:12 +03:00
1 parent e4c1c87b66
commit 19d859e43d
9 files changed
+124 -13

No files matched your search

+1 -1
View File
@@ -146,7 +146,7 @@ if(MINGW)
endif()
install(TARGETS d4r_nvapi_compat RUNTIME DESTINATION nvapi-compat)
target_link_libraries(d4r_d3d12_hip_interop_probe PRIVATE d3d12 dxgi dxguid)
target_link_libraries(d4r_d3d12_dlss_probe PRIVATE d3d12 dxgi dxguid)
target_link_libraries(d4r_d3d12_dlss_probe PRIVATE d3d12 dxgi dxguid d3dcompiler)
add_executable(d4r_debug_launcher tools/windows/debug_launcher.cpp)
target_include_directories(d4r_debug_launcher PRIVATE tools/windows)
target_link_libraries(d4r_debug_launcher PRIVATE version dbghelp)
+11
View File
@@ -8,6 +8,17 @@ An actual game session remains unverified.
## Milestone and gates
Startup coverage (2026-10-01): OptiScaler patch `0002` installs d4r at device
discovery, before NGX initialization. `optiscaler-k-preinit-signature.zip` and
`optiscaler-m-preinit-signature.zip` create a dispatch-only command signature
before NGX Init, execute it in the evaluation list, and run four full frames.
Both use all native transformer layers (44 K / 40 M launches), with bit-exact
RGB against their control frames. K uses inherited legacy states; M uses
inherited enhanced layouts. The full build and all 16 CTest gates pass. Reproduce
with `-EarlyIndirectProbe` in the standalone OptiScaler runner. This avoids
the previously documented unknown-signature rejection for observed startup
objects; signatures created before the frontend is loaded remain untracked.
Current milestone: M1/M2/M4/M5 passed; native NGX Create/Evaluate on the simple
requested E path passes with the user's DLLs. All 11 K layers now pass synthetic
and real-weight NumPy/PTX replay checks; native K Evaluate produces four finite
@@ -0,0 +1,45 @@
From 7ed1f1d66b430ba35a197fbd9880cd6a76af8f06 Mon Sep 17 00:00:00 2001
From: Codex <codex@localhost>
Date: Thu, 1 Oct 2026 16:45:01 +0300
Subject: [PATCH] Install the external d4r command backend before NGX
initialization
---
OptiScaler/hooks/D3D12_Hooks.cpp | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/OptiScaler/hooks/D3D12_Hooks.cpp b/OptiScaler/hooks/D3D12_Hooks.cpp
index 29c0bec..3b757be 100644
--- a/OptiScaler/hooks/D3D12_Hooks.cpp
+++ b/OptiScaler/hooks/D3D12_Hooks.cpp
@@ -14,6 +14,7 @@
#include <proxies/IGDExt_Proxy.h>
#include <proxies/Streamline_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
+#include <proxies/NVNGX_Proxy.h>
#include <detours/detours.h>
@@ -2230,6 +2231,19 @@ static void HookToDevice(ID3D12Device* InDevice)
if (Util::CheckForRealObject(__FUNCTION__, InDevice, (IUnknown**) &realDevice))
pVTable = *(PVOID**) realDevice;
+ if (State::Instance().dlssExternalBackend)
+ {
+ // Capture command signatures/resources created before the game's NGX
+ // Init. Install before adding OptiScaler's own method trampolines.
+ using InstallCommandBackend = unsigned (*)(ID3D12Device*);
+ auto install = reinterpret_cast<InstallCommandBackend>(KernelBaseProxy::GetProcAddress_()(
+ NVNGXProxy::NVNGXModule(), "d4r_D3D12_InstallCommandBackend"));
+ auto result = install ? install(realDevice ? realDevice : InDevice) : 0;
+ LOG_INFO("External d4r command backend installed at device discovery: result={:X}", result);
+ if (result != 1)
+ LOG_ERROR("External d4r early command tracking failed; DLSS initialization must be checked");
+ }
+
// hudless
o_D3D12DeviceRelease = (PFN_Release) pVTable[2];
o_CreateSampler = (PFN_CreateSampler) pVTable[22];
--
2.55.0.windows.5
+5
View File
@@ -16,6 +16,11 @@ selected external DLSS backend reports initialization/load errors instead of
silently switching to FSR. The patch fixes the upstream loader's filesystem
exception by making IsSubpath a lexical check, and retains a PDB for diagnosis.
`0002` installs the command backend at D3D12 device discovery, before NGX Init
and before OptiScaler's own method hooks. Command signatures created during
game startup therefore retain their public argument descriptions for replay.
The standalone runner's `-EarlyIndirectProbe` exercises this startup order.
Build with Microsoft Build Tools 2022, v143 and Windows SDK 10.0.26100:
```powershell
+15 -12
View File
@@ -12,7 +12,8 @@ if (!$InstallRoot) { $InstallRoot = Join-Path $repo 'dist/optiscaler-windows-d4r
$SourceRoot = [IO.Path]::GetFullPath($SourceRoot)
$InstallRoot = [IO.Path]::GetFullPath($InstallRoot)
$base = '45a2001303ddff632e279f77aef85ceede5832cb'
$patch = Join-Path $repo 'patches/optiscaler/0001-windows-external-d4r-backend.patch'
$patches = @(Get-ChildItem -LiteralPath (Join-Path $repo 'patches/optiscaler') -Filter '*.patch' | Sort-Object Name)
if (!$patches.Count) { throw 'OptiScaler source patches are missing.' }
$previousPath = $env:PATH
try {
# Git for Windows' submodule helper needs its POSIX utility directory.
@@ -28,15 +29,17 @@ try {
}
& git -C $SourceRoot merge-base --is-ancestor $base HEAD
if ($LASTEXITCODE) { throw "OptiScaler must be based on audited commit $base" }
$ErrorActionPreference = 'Continue'
& git -C $SourceRoot apply --reverse --check $patch 2>$null
$alreadyApplied = $LASTEXITCODE -eq 0
$ErrorActionPreference = 'Stop'
if (!$alreadyApplied) {
& git -C $SourceRoot apply --check $patch
if ($LASTEXITCODE) { throw 'External backend patch conflicts with the existing source; no files changed.' }
& git -C $SourceRoot apply $patch
if ($LASTEXITCODE) { throw 'External backend patch failed.' }
foreach ($patch in $patches) {
$ErrorActionPreference = 'Continue'
& git -C $SourceRoot apply --reverse --check $patch.FullName 2>$null
$alreadyApplied = $LASTEXITCODE -eq 0
$ErrorActionPreference = 'Stop'
if (!$alreadyApplied) {
& git -C $SourceRoot apply --check $patch.FullName
if ($LASTEXITCODE) { throw "Source patch conflicts: $($patch.Name); existing changes retained." }
& git -C $SourceRoot apply $patch.FullName
if ($LASTEXITCODE) { throw "Source patch failed: $($patch.Name)" }
}
}
& git -C $SourceRoot submodule update --init --depth 1
if ($LASTEXITCODE) { throw 'Pinned OptiScaler submodules failed.' }
@@ -63,11 +66,11 @@ try {
Copy-Item -LiteralPath (Join-Path $SourceRoot "x64/Release/$file") -Destination $InstallRoot -Force
}
Copy-Item -LiteralPath (Join-Path $SourceRoot 'LICENSE') -Destination (Join-Path $InstallRoot 'GPL-3.0.txt') -Force
Copy-Item -LiteralPath $patch -Destination $InstallRoot -Force
foreach ($patch in $patches) { Copy-Item -LiteralPath $patch.FullName -Destination $InstallRoot -Force }
$metadata = @{base=$base; sourceCommit=(& git -C $SourceRoot rev-parse HEAD).Trim();
sourceDirty=[bool](& git -C $SourceRoot status --porcelain); backendAbi=1;
buildTools=$BuildToolsRoot; msbuildVersion=(& $msbuild -version -nologo | Select-Object -Last 1);
patchSha256=(Get-FileHash -LiteralPath $patch -Algorithm SHA256).Hash;
patches=@($patches | ForEach-Object { @{name=$_.Name; sha256=(Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash} });
dllSha256=(Get-FileHash -LiteralPath (Join-Path $InstallRoot 'OptiScaler.dll') -Algorithm SHA256).Hash;
submodules=@(& git -C $SourceRoot submodule status)}
$metadata | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $InstallRoot 'build-info.json') -Encoding UTF8
+5
View File
@@ -16,6 +16,7 @@ param(
[switch]$RequireNativeNetwork,
[switch]$CommandListBackend,
[switch]$CaptureExceptions,
[switch]$EarlyIndirectProbe,
[ValidateSet('baseline','packed','unorm')][string]$PixelProfile = 'baseline',
[ValidateSet('legacy','enhanced','inherited-legacy','inherited-enhanced')][string]$BarrierMode = 'legacy',
[int]$Iterations = 32,
@@ -311,6 +312,10 @@ DisableSplash=true
$ngxArguments += @('--ngx-frontend', 'optiscaler')
}
$ngxArguments += @('--module', $localShim, '--pixel-profile', $PixelProfile, '--barrier-mode', $BarrierMode)
if ($EarlyIndirectProbe) {
if (!$CommandListBackend) { throw '-EarlyIndirectProbe requires -CommandListBackend' }
$ngxArguments += @('--early-indirect', '1')
}
if ($CommandListBackend) { $ngxArguments += @('--interop-mode', 'command-list') }
}
$ngxName = if ($NgxMode -eq 'evaluate') { "ngx-evaluate-preset-$Preset" } elseif ($NgxMode -eq 'd3d12') { "d3d12-evaluate-preset-$Preset" } else { 'ngx-init' }
+1
View File
@@ -144,6 +144,7 @@ HRESULT STDMETHODCALLTYPE hook_signature(ID3D12Device* device, const D3D12_COMMA
std::memcpy(value.data() + sizeof(UINT), desc->pArgumentDescs, value.size() - sizeof(UINT));
const auto tagged = signature->SetPrivateData(signature_description_tag, UINT(value.size()), value.data());
if (FAILED(tagged)) std::fprintf(stderr, "D4R_SIGNATURE_TRACK_FAILURE result=0x%08x\n", unsigned(tagged));
else std::fprintf(stderr, "D4R_COMMAND_SIGNATURE arguments=%u tracked=1\n", desc->NumArgumentDescs);
}
} catch (const std::exception& failure) {
// Preserve the successful public API call. An untracked signature is
+39
View File
@@ -5,6 +5,7 @@
#include <dxgi1_6.h>
#include <memory>
#include <array>
#include <d3dcompiler.h>
int main(int argc, char** argv) {
using namespace d4r::diag;
@@ -168,6 +169,40 @@ int main(int argc, char** argv) {
return 0;
}
Library shim(wide(args.module));
ComPtr<ID3D12CommandSignature> earlySignature;
ComPtr<ID3D12RootSignature> earlyRoot;
ComPtr<ID3D12PipelineState> earlyPso;
ComPtr<ID3D12Resource> earlyArguments;
if (args.early_indirect) {
if (!commandBackend) throw std::runtime_error("Early indirect diagnostic requires command-list backend");
// Discover a device through the frontend before NGX Init. This is
// the startup order used by games which create signatures early.
ComPtr<ID3D12Device> discovered;
dx(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(discovered.GetAddressOf())), "Early frontend device discovery");
D3D12_ROOT_SIGNATURE_DESC rootDesc{};
ComPtr<ID3DBlob> rootCode, errors, code;
dx(D3D12SerializeRootSignature(&rootDesc, D3D_ROOT_SIGNATURE_VERSION_1, rootCode.GetAddressOf(), errors.GetAddressOf()), "Early empty root signature");
dx(device->CreateRootSignature(0, rootCode->GetBufferPointer(), rootCode->GetBufferSize(), IID_PPV_ARGS(earlyRoot.GetAddressOf())), "Early root signature");
constexpr char shader[] = "[numthreads(1,1,1)] void main() {}";
dx(D3DCompile(shader, sizeof(shader) - 1, "early-indirect", nullptr, nullptr, "main", "cs_5_0", 0, 0, code.GetAddressOf(), errors.ReleaseAndGetAddressOf()), "Early noop shader");
D3D12_COMPUTE_PIPELINE_STATE_DESC pipeline{};
pipeline.pRootSignature = earlyRoot.Get(); pipeline.CS = {code->GetBufferPointer(), code->GetBufferSize()};
dx(device->CreateComputePipelineState(&pipeline, IID_PPV_ARGS(earlyPso.GetAddressOf())), "Early noop PSO");
D3D12_INDIRECT_ARGUMENT_DESC argument{}; argument.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;
D3D12_COMMAND_SIGNATURE_DESC signature{}; signature.ByteStride = 12; signature.NumArgumentDescs = 1; signature.pArgumentDescs = &argument;
dx(device->CreateCommandSignature(&signature, nullptr, IID_PPV_ARGS(earlySignature.GetAddressOf())), "Pre-NGX command signature");
earlyArguments = make_buffer(device.Get(), 12, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
auto upload = make_buffer(device.Get(), 12, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE, D3D12_RESOURCE_STATE_GENERIC_READ);
void* mapped = nullptr; D3D12_RANGE noRead{}; dx(upload->Map(0, &noRead, &mapped), "Early indirect upload");
const uint32_t dimensions[] = {0, 1, 1}; std::memcpy(mapped, dimensions, sizeof(dimensions)); upload->Unmap(0, nullptr);
ComPtr<ID3D12CommandAllocator> copyAllocator; ComPtr<ID3D12GraphicsCommandList> copy;
dx(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(copyAllocator.GetAddressOf())), "Early copy allocator");
dx(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, copyAllocator.Get(), nullptr, IID_PPV_ARGS(copy.GetAddressOf())), "Early copy list");
copy->CopyResource(earlyArguments.Get(), upload.Get());
transition(copy.Get(), earlyArguments.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
dx(copy->Close(), "Early copy close"); ID3D12CommandList* batch[] = {copy.Get()}; queue->ExecuteCommandLists(1, batch); drain();
std::printf("D3D12_EARLY_INDIRECT signature_created_before_ngx_init=1\n");
}
using Init = unsigned(*)(unsigned long long, const wchar_t*, ID3D12Device*, unsigned, const void*);
using Allocate = unsigned(*)(void**); using Destroy = unsigned(*)(void*);
using Create = unsigned(*)(ID3D12GraphicsCommandList*, unsigned, void*, void**);
@@ -243,6 +278,10 @@ int main(int argc, char** argv) {
d4r_ngx_set_int(parameters, "Reset", frame == 0 ? 1 : 0);
if (commandBackend) {
dx(allocator->Reset(), "Reset(game-style allocator)"); dx(list->Reset(allocator.Get(), nullptr), "Reset(game-style list)");
if (earlySignature) {
list->SetComputeRootSignature(earlyRoot.Get()); list->SetPipelineState(earlyPso.Get());
list->ExecuteIndirect(earlySignature.Get(), 1, earlyArguments.Get(), 0, nullptr, 0);
}
if (enhanced && !inherited) for (unsigned i = 0; i < 5; ++i) enhancedBarrier(list.Get(), textures[i].image.Get(), i, false);
using RecordedEvaluate = unsigned(*)(ID3D12GraphicsCommandList*, void*, void*, void*);
check(shim.symbol<RecordedEvaluate>("NVSDK_NGX_D3D12_EvaluateFeature")(list.Get(), handle, parameters, nullptr), "D3D12 recorded same-frame Evaluate");
+2
View File
@@ -118,6 +118,7 @@ struct Args {
std::string interop_mode = "roundtrip";
std::string pixel_profile = "baseline";
std::string barrier_mode = "legacy";
bool early_indirect = false;
std::string ngx_core, dlss_dll;
std::string nvapi_dll;
std::string ngx_abi = "driver";
@@ -148,6 +149,7 @@ struct Args {
if (value != "legacy" && value != "enhanced" && value != "inherited-legacy" && value != "inherited-enhanced") throw std::runtime_error("Invalid barrier-mode");
barrier_mode = value;
}
else if (key == "--early-indirect") early_indirect = value == "1";
else if (key == "--ngx-core") ngx_core = value;
else if (key == "--dlss-dll") dlss_dll = value;
else if (key == "--nvapi-dll") nvapi_dll = value;