Say what upscaler_idle_wait = 1 brings back and what it does not.

The review of 9071dfc3 found that nx2navi.ini.example, cfg.c's metas comment, the commit message and docs/architecture.md
said the rollback switch works "as up to 0.10.1", which it does not exactly. With 1, every place that lets something go
waits for the device again, C-5's queue-lock hazard with it, but what was let go of still goes through vk_dlaa.c's list
and vk_memory.c's deferred destruction, the motion vectors and the HUD-less picture keep their 8-present gate,
vk_upscaler_settle leaves what the submission being recorded names, stale_sizes waits once per call, and a refused DLSS
creation with features let go of still listed waits and tries again, where 0.10.1 turned DLAA off. Each difference is
the safer side. The ini line now says that the game waits at each change as up to 0.10.1 while what was let go of
still goes once the card is past it; cfg.c, vk_dlaa.c's "what the upscalers let go of" and docs/architecture.md say
the same. Comments and docs only.

Checks that passed: cfg_rows_check (0 problems), upscaler_idle_check, cfg.c and vk_dlaa.c compile with -Wall -Wextra
and no warning, tools/check_content.py --staged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
chrg6
2026-11-13 19:38:20 -05:00
parent 75b06b0a30
commit cde143c5d9
4 changed files with 11 additions and 6 deletions

View File

@@ -380,8 +380,8 @@ keeps per-core data without locks and relies on that, so the host models it (`ru
while (`vk_dlaa.c` `idle_release`, `vk_fsr.c` `idle_note`, `vk_aa.c` `work_idle`). What DLSS or FSR lets go of at
a change of size or mode (a network, an FSR context, a work image) goes once the GPU is past the last submission that
used it, and an image frame generation reads at a present some presents later, without a wait for the device on the
replaying thread (`vk_dlaa.c` "what the upscalers let go of", `vk_up_defer.h`; `upscaler_idle_wait = 1` waits as
before).
replaying thread (`vk_dlaa.c` "what the upscalers let go of", `vk_up_defer.h`; `upscaler_idle_wait = 1` waits for
the device at each such change as before, and the freeing keeps these gates).
- Translated shaders at rest: the shader memory cache keeps every shader for the whole session, but a shader's SPIR-V
is read only while modules are made of it. A background thread compresses (zstd, checked by decoding it) the SPIR-V
of each shader no reader used for `shader_compress_idle_s` seconds (30) and frees the plain copy; a reader pins it

View File

@@ -717,8 +717,9 @@
# dlss_idle_free = 1
# When DLSS or FSR lets go of a network, an FSR context or a picture (a new picture size, the pause screen, a mode
# change). 0: it is freed once the graphics card has finished the frames that used it, and the game does not wait.
# 1: the game waits for the graphics card to finish all its work first, as up to 0.10.1: a hitch of a frame or more
# at each such change. For comparison, or if 0 shows a fault. Read at start.
# 1: the game waits for the graphics card to finish all its work at each such change, as up to 0.10.1 (what was let
# go of still goes once the card is past it): a hitch of a frame or more at each change. For comparison, or if 0 shows
# a fault. Read at start.
# upscaler_idle_wait = 0
# One DLSS network for the render sizes of a DLSS mode. 1: the network made for the mode's own render size also takes
# the smaller render sizes DLSS allows on it (dynamic resolution's steps with dyn_res = 1, a screen that renders

View File

@@ -217,7 +217,8 @@ static const CfgMeta metas[] = {
{"SCENE_SHARE", "0.75", "0..1", LIVE},
{"DLAA", "0", "0|1", LIVE}, {"DLSS", "dlaa", "dlaa|quality|balanced|performance|ultra_performance", LIVE},
{"DLSS_PRESET", "default", "default|k|j", LIVE}, {"DLSS_IDLE_FREE", "1", "0|1|2", RESTART}, {"TAA", "dlss", "dlss|fsr3", LIVE}, // vk_dlaa.c fsr3
// vk_dlaa.c vk_upscaler_idle_wait: 1 waits for the device to be idle before an upscaler frees anything, as up to 0.10.1
// vk_dlaa.c vk_upscaler_idle_wait: 1 waits for the device to be idle wherever an upscaler lets go of something, as up
// to 0.10.1 (what was let go of still goes once the GPU is past it, behind its present gate)
{"UPSCALER_IDLE_WAIT", "0", "0|1", RESTART},
{"DLSS_RANGE", "0", "0|1", RESTART}, // vk_dlaa.c range_on: one DLSS feature for the render sizes of a mode
{"DLSS_PREBLOOM", "0", "0|1", LIVE}, // vk_dlaa.c prebloom_run: DLSS or FSR 3.1 before the bloom, not after the tonemap

View File

@@ -764,7 +764,10 @@ static void feat_release(NgxHandle *f) {
// The lists are taken at every evaluation (evaluate), at every pass while none runs (retire_idle), and where something
// is let go of (vk_upscaler_let_go). What still waits: a feature or context creation refused while ones let go of are
// in flight waits for the GPU to pass those (vk_upscaler_gpu_wait), and a full list for the device (vk_upscaler_settle).
// NX2NAVI_UPSCALER_IDLE_WAIT=1 waits for the device wherever something is let go of, as up to 0.10.1.
// NX2NAVI_UPSCALER_IDLE_WAIT=1 waits for the device wherever something is let go of, as up to 0.10.1, but does not
// bring 0.10.1 back exactly: what was let go of still goes through these lists and the deferred destruction, an image a
// present reads keeps its present gate, what the submission being recorded names stays until it is done, and a refused
// DLSS creation with features let go of still listed waits and tries again, where 0.10.1 turned DLAA off.
enum { UPD_FEAT = 1, UPD_IMG, UPD_VIEW }; // dead's kinds: a DLSS feature, an image with its allocation (aux), a view
static UpdList dead; // DLAA's hook thread only (vk_dlaa_pass and what it runs), as evaluate's state
// A vk_dlaa.c image frame generation can read at a present goes this many presents after it was let go of. present_image