- [Interop] MarkerPollUs = auto is the new default: the input-marker wait learns when
each feature's inputs become ready, sleeps in <=200 us chunks, yields near the
prediction and backs off when late (d4r_input_wait.h); a number keeps fixed pacing
(0 yields). d4r_config.py no longer exports 200 when the key is unset
- D4R_SHIM_GPU_INPUT_WAIT=1 (experimental, split VRAM, age 0): NGX's null stream
waits on a coherent Vulkan word imported into HIP (d4rStreamWaitValue32Eq) instead
of CPU polling. The original readback marker stays the authority; a CPU watchdog
releases discarded lists and timeouts. Denoiser, verify, capture and dilation
frames keep the CPU wait
- D4R_SHIM_GPU_COMPLETION=1 (needs GPU_INPUT_WAIT): the bridge writes a completion
word right after the native output kernel (d4rNgxWriteValue32), and the game's queue
polls it with a bounded compute wait (kernels/support/vulkan_wait.comp), replacing
the split list's CPU timeline signal. frame_retired writes the same word on every
failure path
- D4R_SHIM_NATIVE_COMPLETION=1: a null-stream callback in the bridge signals the
split timeline (d4rNgxTimeline*); D4rFrameCompletion::can_signal only releases the
oldest outstanding frame
- RGBA8 output: tex_common.h adds an 'R4' redirect tag, so K's native output kernel
stores packed RGBA8 directly (D4R_SHIM_OUTPUT_RGBA8=1, checked against the kernel
manifest by d4rOutputKernelRgba8). Host packing handles RGBA8 too.
patches/vkd3d-proton/0004 (VKD3D_D4R_LINEAR_RGBA8=WxH) makes such outputs linear and
exportable so the result can be written in place
- D4R_SHIM_FUSE_RGBA8_INPUT=1: one Vulkan pass converts and copies RGBA8 color input
(vulkan_read.comp mode 5 matches the blit's toward-zero halves, plus a row stride)
- profiling: thread CPU time from the Unix bridge (Wine's GetThreadTimes ticks at
10 ms); game-queue D3D12 timestamps (vk_input/vk_dlss_wait/vk_output/vk_total);
gpu_eval split into input_gpu_wait and dlss_gpu; D4R_PROFILE_GPU_EVENTS,
_TIMESTAMPS, _LOG and _CPU_TIME=0 switch off individual parts for bisection
- bridge: D4R_NGX_STREAM_PRIORITY=high|normal runs NGX on a priority stream
(off by default; no gain measured)
- release_feature: a feature already marked retiring by a failed drain can still
be released normally
- harness: RGBA8 with motion and jitter scenes (re-quantized each frame),
D4R_HARNESS_RGBA8_RAMP, D4R_HARNESS_THRASH_MB to evict L2/Infinity Cache before
each evaluation
- kernels/native: in_hoist.py and split_output_paths.py (opt-in scheduling
experiments); scripts/build_k_ldr_output.sh builds K's LDR output with an
optional D4R_LDR_OUTPUT_MAX_VGPR cap
- tests: test_input_wait.py and test_latency_optimizations.py; MarkerPollUs and
frame-completion tests updated
- engine/compile_rr2.py, runtime_rr2.inc, engine/rr/rr2_m.comp, exposure_f.comp,
gen_rr2_enc0.py, rr2_pack.py, rr2_ref.py: the rr2_* model (nvngx_dlssd.dll 310.9's
third network) as d4r's own shaders - exposure, enc0 gather/block split, enc1-5 and
dec4-0 through one matrix shader, translated output passes; weights packed from the
DLL, argument blocks from the capture
- ptx2rr: match the driver's fused roundings - opaque-zero OR around cvt.rn.f16.f32
against v_fma_mix, half-away-from-zero formatted stores, UNORM 10:10:10:2 as RGBA32F
of q/1023, OCML tanhF with the AMDGPU exp lowering, binary16 fma and fetch roundings;
--probe for register bisection against ZLUDA
- dec0_m/swin_m/enc0_*: RR_MIX build option (D4R_RR_MIX=1), one v_fma_mix rounding per
32-deep step, ~5% faster, not bit-exact; default build stays exact
- runtime_rr.inc: RModel/REngine dispatch to the D4RR0002 model; replay_rr: RGBA32F and
A2B10G10R1010 texel sizes, roughnessPacked bit, larger debug staging
- shim: engine\rr-f model slot, 310.9 version probe so preset F is only claimed when the
CUDA path has it; d4r.ini / d4r_config.py Model = F; run_rr_engine_compare.sh D4R_RR_DLL
- kernels/rr/swin_native.h + rr_swin_native_test.cpp: HIP port of encoder 1 for the
FP8-product and rounding cost measurements
- engine/rr/README: preset F's block, options, capture-by-capture results, timings and
the open camera-matrix difference
- GameFrameR/RFrameImages: DLSSD.ScreenSpaceSubsurfaceScatteringGuide (arg 264)
and DLSSD.ColorBeforeParticles (output stage, texture 416 with its own history
pair 384/392, zero-initialised on first use); guides array 6 -> 8
- DLSS.Use.HW.Depth: byte 980 and output byte 443 bit 24 (Cyberpunk passes the
nonlinear depth buffer); replay's 'inverted' field becomes a bitmask
- shim: bind the two new resources, read the HW-depth flag, and accept every
preset hint except E's 5 by mapping it to D's diamond_wallaby kernels
(harness captures show 0x80000002/0x80000005 run preset D)
- harness: D4R_HARNESS_RR_EXTRA=particles,sss and D4R_HARNESS_RR_HW_DEPTH=1
- ptx2rr: out-of-range integer fetches return zero, matching ZLUDA's behaviour
(the reference the stages are checked against)
- engine/rr/README: the capture findings behind the offsets
- engine/rr: d4r's own shaders for the denoiser frame (exposure, six encoders,
five decoders, hkpn output stage) at NGX layouts, plus PTX->GLSL/HIP packing
scripts, reference implementations and weight extraction
- runtime.h/runtime_rr.inc, game_rr.{h,cpp}: GameDenoiser wired into the engine
build (d4r-rr replay binary) and the D3D12 shim's feature-13 path
- shim: answer GetFeatureRequirements from d4r's own state only (the old
cross-binary CUDA handoff crashed OptiScaler's scan); drop the core's
CUDA GetFeatureRequirements import
- shim/harness: exact guide capture/replay of a frame's RR inputs
- kernels/rr: expanded enc0/engine prototypes; kernels/tools: ptxsim rewrite
plus rrsim and an engine test; vulkan: ptx2glsl FP8/cooperative-matrix
support, kvk inout buffers and KVK_DISABLE_OPTIMIZATION
- bridge: report the surface array in cuSurfObjectCreate traces
- packaging: RR settings and the ICU launch overrides in D4R_README
A replay only means something if the denoiser gets the bytes the game gave it.
The capture now records, for every bound guide, the caller's own DXGI format and
texel size next to the plane (they differ from the CUDA array's for every
converted format, and B8G8R8A8_UNORM is four bytes to D3D12 and sixteen to the
float array), the names the caller registered each surface under as well as the
names the denoiser reads it as, the exposure texture's own geometry, and the
feature's creation state - dimensions, quality, create flags, output-subrect
setting and the effective render preset. A frame whose staging is not readable
aborts its whole capture instead of writing a descriptor without its plane.
The harness reads all of it back: it sizes and creates the feature from the
capture, creates each guide in the recorded format at the recorded size, uploads
the recorded bytes, applies the recorded scalars, subrect origins, inversion
flags and camera matrices, binds the exact source names and clears the ones the
frame stopped registering. A missing guide descriptor, a missing or mis-sized
plane, a truncated parameter line, a claimed exposure with no geometry, or a
capture taken before the creation state was recorded is refused rather than
filled in with a default, because a replay that invents any of it still renders
a plausible image that matches nothing the game produced.
Run the signed CUDA-capable denoiser through feature 13 with independent D/E presets, pre-Init discovery, per-frame guide and camera snapshots, normalized integer guide staging, paired alpha output, and recorded-resource retirement.
Add the required ZLUDA/LLVM patch, behavioral configuration tests, GPU harness coverage, optional denoiser installation and packaging, and tested support limitations. Preserve upstream attribution and distinguish LLVM licensing from the ZLUDA portions of the patch.
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]>
- Tag redirected surfaces as R10G10B10A2 ('R3') as well as RGBA16F ('R2'), and
let the native output kernel store the game's R10G10B10A2 texels itself.
- Import linear, exportable game textures (vkd3d-proton patch 0003) into HIP
so the output kernel writes the game's output texture with no game-side copy.
- Add ID3D12DXVKInteropDeviceD4R3 with GetVulkanLinearImageInfo.
- Gate both paths behind D4R_SHIM_OUTPUT_PACKED and D4R_SHIM_INPLACE, and use
them only for split frames of preset M whose output kernel honours the redirect.
- Convert on the host when a recorded packed frame finds the wrong kernel.
- Give the harness an R10G10B10A2 output, and add D4R_SHIM_SPIN_POLL so
frame timing is not quantised to the poll sleep.
- Document the measured removal of the output copies in performance.md.
- Reprepare enc3 weights each launch to avoid stale caches after feature recreation
- Require per-slot input markers before evaluating recorded frames
- Advance split-frame timelines only through completed frames
- Add cancellation and readiness tests plus recreation consistency checks
- Update architecture and native kernel documentation
ref #8
- Shim: reuse VRAM interop buffers across features instead of freeing them;
ROCm 7.2.x's hipExternalMemoryGetMappedBuffer retains its view twice, so
freed buffers never released their memory (~130 MB per quality change)
- Bridge: close the exported fd after hipImportExternalMemory
- Shim: accept R16G16B16A16_TYPELESS motion vectors and convert 4-channel
motion vectors to RG16F on the GPU, keeping VRAM interop (Dying Light:
The Beast rendered black)
- Harness: D4R_HARNESS_RECREATE=N quality-change cycles,
D4R_HARNESS_MV_RGBA16=1 motion vector format
- Supported games: TLOU, Control, Cyberpunk 2077, Rift Apart, HZD Remastered,
Subnautica 2, Alan Wake 2, Silent Hill 2, Dying Light: The Beast; general notes
- README: GPU support section (native kernels only for gfx1101); ignore videos/