Engine: native presets K and M in the D3D12 shim, wider game coverage

A standalone Vulkan inference engine (engine/) for DLSS presets K and M that
runs from weights extracted from the user's own nvngx_dlss.dll, with d4r's
own input, network and reconstruction shaders or the native HIP network
layers, recorded into the game's command list by the shim. Opt-in
([Engine] Enabled / D4R_ENGINE=1); anything uncovered falls back to the
CUDA/ZLUDA path with the reason logged.

Byte-identical to NGX's CUDA backend under the phase-capable reference
(1706x960 -> 2560x1440, native HIP network, eleven frames, RX 9070 XT):
- K render- and display-resolution motion vectors, HDR and LDR
- K game-supplied exposure and automatic exposure with any pre-exposure
  and exposure scale (one residual: effective exposure exactly 2 or 4)
- K and M with the DLSS indicator's inverted-axis parameters
- M with any exposure settings (NGX ignores them for M)
K packages need the current compile_k.py (marker D4RO0003).

Also: HIP shared buffers are pooled across feature recreation (ROCm leaks
destroyed imports), hipnet.bin must match the preset, M-only games do not
load the K model, install_d4r_runtime.sh stages k, k-ldr, m, m-ldr with
hip/, the activation table has a generator (gen_activation_m.py), and
package_release.sh can bundle the engine's shaders (never its weights).

Signed-off-by: woutermans <[email protected]>
This commit is contained in:
woutermans committed 2026-10-10 20:54:01 +02:00
1 parent 16cfc1f063
commit e0d1549a21
82 files changed
+13335 -96

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
"""Compare full native frame results, including the engine's own temporal feedback.
test_frame.py CASE_DIR RESULT_DIR [--min-psnr 50]
Exits nonzero for missing data, nonfinite output, or a PSNR regression.
"""
import argparse
import json
from pathlib import Path
import numpy as np
def compare(reference, output):
a = np.fromfile(reference, np.float16).astype(np.float64)
b = np.fromfile(output, np.float16).astype(np.float64)
if a.shape != b.shape or not a.size:
raise ValueError(f'{output}: size differs from reference')
if not np.isfinite(a).all() or not np.isfinite(b).all():
raise ValueError(f'{output}: nonfinite reference or result')
error = np.abs(a - b)
peak = max(np.abs(a).max(), 1e-9)
psnr = 10 * np.log10(peak**2 / max((error**2).mean(), 1e-30))
return psnr, error.max(), error.mean()
def main():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument('case', type=Path)
p.add_argument('results', type=Path)
p.add_argument('--min-psnr', type=float, default=50)
a = p.parse_args()
references = json.loads((a.case / 'references.json').read_text())
if not references: raise ValueError('no reference frames')
failed = False
names = {'288': 'history color', '296': 'hi-res luma', '304': 'token feature', '312': 'final RGB'}
for i, refs in enumerate(references):
for off, reference in refs.items():
psnr, maximum, mean = compare(reference, a.results / f'frame-{i}.{off}.bin')
print(f'frame {i} {names[off]:14s}: {psnr:6.1f} dB PSNR; max error {maximum:.5g}; mean {mean:.5g}')
failed |= psnr < a.min_psnr
if failed: raise SystemExit(f'frame validation failed: PSNR below {a.min_psnr:g} dB')
if __name__ == '__main__': main()