Skip to content

DLSS-NR: dynamic chained model passes with per-pass overrides, plus an optional Chinese language pack - #26

Open
Moeblack wants to merge 4 commits into
Dagherbou:dlss-neural-renderingfrom
Moeblack:dlssnr-dynamic-multipass
Open

DLSS-NR: dynamic chained model passes with per-pass overrides, plus an optional Chinese language pack#26
Moeblack wants to merge 4 commits into
Dagherbou:dlss-neural-renderingfrom
Moeblack:dlssnr-dynamic-multipass

Conversation

@Moeblack

@Moeblack Moeblack commented Sep 5, 2026

Copy link
Copy Markdown

Runs the DLSS neural-rendering model more than once over the same frame on D3D12. Each extra pass is a separate NGX feature with its own frame history, fed the previous pass's answer, so later passes see one frame per frame instead of re-feeding one instance's own output. The pass count is not capped at a product number: 2-3 is the sensible range, the UI suggests 1-6, and a direct numeric input accepts any positive uint32_t. Off by default: [DlssNr] Passes=1 and IndividualPassSettings=false take the same path the code takes today (one evaluate with identical arguments; no scratch, no extra features, no chain).

This is an independent implementation on the same base as #23 (and alongside the draft in #1). The machinery is necessarily close family — separate per-pass features built a frame ahead so nothing is created and evaluated on one command list, a two-texture work set, modelInput left untouched so the resolve's edit = model - proxy stays the whole chain's. Where it differs: no fixed upper bound (extra features are created one per Dispatch, one at a time, and every build frame returns before evaluation); sparse per-layer overrides with live master inheritance; and the menu shows the count that actually completed (DlssNr::ActivePassCount()), not the requested one. If you would rather keep one multipass implementation in the tree I am happy to reconcile or rebase this onto whichever you pick.

Per-pass sparse configuration

[DlssNr] IndividualPassSettings=false by default: every layer uses the master model controls and nothing is copied or materialised. Setting it true does not snapshot the master values — each [DlssNr.PassN] section stores only the fields actually overridden; everything else keeps inheriting the master settings live. Sections are 1-based, may skip numbers, and lowering Passes never deletes higher overrides. On save the owned sections are rebuilt from the in-memory map so cleared fields and alternate spellings (Pass01) cannot resurrect stale keys. Override-map reads/writes are guarded by a dedicated mutex (the render side only looks up, never inserts).

Pipeline notes

  • Extra features live in a dynamic vector; [0] is pass 2 by the renderer's counting (config uses 1-based pass numbers; the conversion is explicit at the single integration point).
  • Work textures: the existing output plus outputPingPong, allocated only when Passes > 1; passes alternate UAV/SRV ownership as they read the previous answer and write the next. finalOutput is tracked by pointer, never re-derived from parity at resolve time.
  • A pass whose settings changed is rebuilt; changing the upstream count or resolution resets the chain's history rather than recreating every downstream instance blindly.
  • A failed extra pass stops the chain at the last good surface, latches a reason shown in the menu (with Retry); lowering the count clears the latch — no per-frame reallocation/retry storm.
  • Native Vulkan keeps today's single-pass master behaviour; the menu says so instead of showing controls that would not apply. The DlssNrUseProxy path does not participate in the chain or per-pass overrides and is refused with an explanation.

Localization (self-contained; drop the last commit to remove entirely)

Optional, non-invasive Chinese language pack. English source text remains the key; Localization::Tr() looks up a UTF-8 dictionary (OptiScaler_zh.ini / zh_CN.ini next to the DLL, then beside the game exe) loaded once per DLL lifetime; missing files or keys fall back to the original English text, and translations that do not preserve every printf directive or that alter ImGui ##/### identity suffixes are rejected at load. When the pack is in use, the menu font atlas merges %WINDIR%\Fonts\msyh.ttc (resolved via GetWindowsDirectoryW) so CJK glyphs render instead of boxes. Without the pack nothing changes: no dictionary, no font merge, no behavioural delta.

All C++/H follows CONTRIBUTING.md PCH rules (new Localization.cpp includes pch.h first; no header includes it).

What I did not do

No HLSL/cbuffer or precompiled-shader changes; no NGX forwarder ABI change; no Vulkan multi-pass; no new model DLL; no new GPU queues. No VRAM formula is claimed beyond the host side (one extra work texture; each feature's internal state still grows with the count).

Test plan

  • Release x64 MSBuild builds clean
  • D3D12: Passes=1 picture is unchanged from today's build (default-identical path)
  • D3D12: 1->2->3 live switching; even/odd final-output parity verified in GTA V Enhanced
  • D3D12: per-pass overrides inherit master when IndividualPassSettings=false
  • D3D12: menu shows the actually-completed layer count
  • zh pack: with OptiScaler_zh.ini present the menu renders Chinese (incl. glyphs); without it the menu is byte-identical English

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant