- [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
Shim
- Adaptive output-event wait: sleep to ~120 us before the predicted
completion (smoothed per wait site), spin near it, back off when late.
D4R_SHIM_OUTPUT_POLL_US restores a fixed interval.
- Defer the input-marker wait into the worker thread with VRAM interop
(D4R_SHIM_DEFER_MARKER, default on), taking the host setup off the
critical path.
MicroCUDA
- Experimental ZLUDA-free backend in wine_nvcuda_bridge, plus
tools/microcuda and scripts/build_microcuda.sh. Serves accuracy, fast
and native kernels; unregistered modules fall back to the reference
path. Unclassified writes invalidate prepared weights.
M kernels
- SWIN_PREP_IDENTITY_AT: key weight prep by allocation identity
(MicroCUDA); enc3 tube uses it with 8 slots. ZLUDA ignores it.
- dec2 (gfx1101): SWIN_PACKED_RESIDUAL, byte-identical, ~1.6% faster.
- Opt-in gfx12 hardware fp8 conversion (SWIN_FP8_HWCVT), unverified
on hardware.
Native K translators
- ctile: handle variants that re-materialize the parameter base (mvlo).
- rewrite_output: check live-in registers, not just outputs.
- build.sh: native input covers all 8 flag variants, output the 4 HDR
"max" variants; depth-tile skip stays mvhi-only.
Tools
- dump_runner and bench_dlss_kernel harness additions.
Preset K, byte-identical to the previous output in all captured buffers
and the harness image, measured on an RX 7700 XT:
- LDS row padding so WMMA operand loads hit distinct banks
- WGP mode for enc1/enc2/dec1/dec2, ds_bpermute half-wave exchange for
enc0/dec0/dec3, more waves per window in enc4/dec4/dec5
- cheaper operand plumbing in common/wmma_layout.h (packed f16
conversions, no dynamic vector indexing), raw buffer weight loads,
accumulator-init vectors prepared once
- enc1 as a single-buffer recompute layer, dec1 Q/K/V chains split
- dec5 as four dependent phase kernels