feat(vk): add experimental DLSS 5 Neural Rendering #1590
Open
HypeZ85 wants to merge 5 commits from
HypeZ85/codex/dlss5-neural-rendering into main
pull from: HypeZ85/codex/dlss5-neural-rendering
merge into: MagicBeanDev:main
MagicBeanDev:main
MagicBeanDev:github/pr/2893
MagicBeanDev:github/pr/2890
MagicBeanDev:github/pr/2887
MagicBeanDev:github/pr/2878
MagicBeanDev:github/pr/2875
MagicBeanDev:github/pr/2874
MagicBeanDev:github/pr/2873
MagicBeanDev:github/pr/2871
MagicBeanDev:github/pr/2756
MagicBeanDev:github/pr/2897
MagicBeanDev:github/pr/2896
MagicBeanDev:github/pr/2718
MagicBeanDev:github/pr/2842
MagicBeanDev:github/pr/2691
MagicBeanDev:github/pr/2895
MagicBeanDev:github/pr/2743
MagicBeanDev:github/pr/2765
MagicBeanDev:github/pr/2708
MagicBeanDev:github/pr/2732
MagicBeanDev:github/pr/2755
MagicBeanDev:github/pr/2817
MagicBeanDev:github/pr/2876
MagicBeanDev:release-please--branches--main
MagicBeanDev:release-please--branches--main--release-notes
MagicBeanDev:github/pr/2778
MagicBeanDev:github/pr/2888
MagicBeanDev:github/pr/2866
MagicBeanDev:github/pr/2877
MagicBeanDev:github/pr/2800
MagicBeanDev:github/pr/2829
MagicBeanDev:github/pr/2850
MagicBeanDev:github/pr/2889
MagicBeanDev:github/pr/2882
MagicBeanDev:github/pr/2860
MagicBeanDev:github/pr/2849
MagicBeanDev:github/pr/2886
MagicBeanDev:github/pr/2794
MagicBeanDev:github/pr/2840
MagicBeanDev:github/pr/2830
MagicBeanDev:github/pr/2834
MagicBeanDev:github/pr/2719
MagicBeanDev:github/pr/2742
MagicBeanDev:github/pr/2741
MagicBeanDev:github/pr/2820
MagicBeanDev:github/pr/2771
MagicBeanDev:github/pr/2859
MagicBeanDev:github/pr/2858
MagicBeanDev:github/pr/2823
MagicBeanDev:github/pr/2757
MagicBeanDev:github/pr/2769
MagicBeanDev:github/pr/2844
MagicBeanDev:github/pr/2843
MagicBeanDev:github/pr/2673
MagicBeanDev:github/pr/2855
MagicBeanDev:github/pr/2739
MagicBeanDev:github/pr/2807
MagicBeanDev:github/pr/2851
MagicBeanDev:github/pr/2789
MagicBeanDev:github/pr/2814
MagicBeanDev:github/pr/2818
MagicBeanDev:github/pr/2774
MagicBeanDev:github/pr/2772
MagicBeanDev:github/pr/2750
MagicBeanDev:github/pr/2786
MagicBeanDev:github/pr/2785
MagicBeanDev:github/pr/2782
MagicBeanDev:github/pr/2779
MagicBeanDev:github/pr/2775
MagicBeanDev:github/pr/2706
MagicBeanDev:github/pr/2766
MagicBeanDev:github/pr/2747
MagicBeanDev:github/pr/2759
MagicBeanDev:github/pr/2745
MagicBeanDev:github/pr/2740
MagicBeanDev:github/pr/2733
MagicBeanDev:github/pr/2725
MagicBeanDev:github/pr/2727
MagicBeanDev:github/pr/2728
MagicBeanDev:github/pr/2729
MagicBeanDev:github/pr/2721
MagicBeanDev:github/pr/2722
MagicBeanDev:github/pr/2715
MagicBeanDev:github/pr/2714
MagicBeanDev:github/pr/2707
MagicBeanDev:github/pr/2703
MagicBeanDev:github/pr/2705
MagicBeanDev:github/pr/2697
MagicBeanDev:github/pr/2679
MagicBeanDev:github/pr/2676
MagicBeanDev:github/pr/2669
MagicBeanDev:docs/what-hookshot-connects-to
MagicBeanDev:fix/hdr-encode-test
MagicBeanDev:fix/main-tests
MagicBeanDev:fix/play-cache-files
MagicBeanDev:perf/game-barrier-order
MagicBeanDev:feat/heap-lazy
MagicBeanDev:feat/texture-detail
MagicBeanDev:perf/astc-opaque-bc1
MagicBeanDev:fix/fs-dir-lock
MagicBeanDev:fix/framegen-native-kept
MagicBeanDev:fix/update-no-downgrade
MagicBeanDev:port/k10-gcn-f16-mirrors
MagicBeanDev:fix/framegen-mult-cap
MagicBeanDev:chore/release-as-2.1.1
MagicBeanDev:perf/pcache-load-switch
MagicBeanDev:fix/prepare-progress-log
MagicBeanDev:fix/update-closes-stale-game
MagicBeanDev:fix/hdr-scaled-sampled
MagicBeanDev:perf/first-start-preset
MagicBeanDev:perf/zero-upload
MagicBeanDev:fix/vcore-escape-2s
MagicBeanDev:test/fake-gh-atomic
MagicBeanDev:perf/batch-idle-flush
MagicBeanDev:test/finish-stub-a
MagicBeanDev:chore/record-2.1.0
MagicBeanDev:fix/main-red-tests
MagicBeanDev:fix/test-display-startup-driver-cache
MagicBeanDev:feat/mesh-shader-mode
MagicBeanDev:fix/menu-probes-at-startup
MagicBeanDev:fix/fps-counter-classic
MagicBeanDev:fix/test-log-batch-flake
MagicBeanDev:fix/narrow-screen-hud
MagicBeanDev:ci/prereleases
MagicBeanDev:release/v2.0.15
MagicBeanDev:hotfix/v2.0.15
MagicBeanDev:fix/present-ahead-replay
MagicBeanDev:release/v2.0.13
MagicBeanDev:fix/bracket-paths-2013
MagicBeanDev:fix/hdr-overlays-2013
MagicBeanDev:fix/fps-counter-scale-2013
MagicBeanDev:fix/stick-seen-at-rest
MagicBeanDev:hotfix/menu-fits-screen
MagicBeanDev:fix/f1-always-opens-menu
MagicBeanDev:fix/ini-keep-lines
MagicBeanDev:claude/cranky-pike-7cf247
MagicBeanDev:perf/texture-answer-flat
MagicBeanDev:fix/stamp-test-modules
MagicBeanDev:fix/appimage-fonts
MagicBeanDev:fix/display-awake
MagicBeanDev:release/v2.0.12
MagicBeanDev:fix/discord-windows
MagicBeanDev:rc/v2.0.12-tests
MagicBeanDev:fix/dlss-keep-feature
MagicBeanDev:rc/v2.0.12
MagicBeanDev:button-icons
No reviewers
Labels
Clear labels
accessibility
Barrier affecting people with disabilities
autorelease: pending
autorelease: tagged
bug
Something isn't working
dependencies
Pull requests that update a dependency file
documentation
Improvements or additions to documentation
duplicate
This issue or pull request already exists
enhancement
New feature or request
github_actions
Pull requests that update GitHub Actions code
good first issue
Good for newcomers
help wanted
Extra attention is needed
invalid
This doesn't seem right
question
Further information is requested
testing wanted
wontfix
This will not be worked on
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
Milestone
Clear milestone
No items
No milestone
Assignees
Clear assignees
No assignees
2 participants
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1590
Loading…
Reference in a new issue
No description provided.
Delete branch "HypeZ85/codex/dlss5-neural-rendering"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds optional DLSS 5 Neural Rendering to the existing Vulkan NGX path, with persistent controls and in-game A/B comparison. Missing or incompatible NR runtimes fall back to ordinary rendering and report the reason only inside the NR submenu.
ba005ca4, retaining its menu localization, keyboard prompts, DLSS SR/FG recovery, Graphics sections and compact tuning bar, direct NGX Frame Generation, native HDR tone mapper, reactive SR mask, FOV and secondary controller bindings.This uses NGX feature 18 (Reserved18 in the public SDK) and community-documented DLSSNR.* keys with a user-supplied nvngx_dlssnr.dll. It is not a public NVIDIA NR SDK contract and may change with driver/runtime updates. NR defaults Off; an additional environment shipping gate remains a maintainer policy decision. Linux has no known compatible native NR runtime and offers experimental opt-in probing/fallback only. No Streamline or other intermediate layer is introduced.
No verified NR jitter-offset keys exist in the inspected contract/runtime. Jittered input therefore resets NR history each frame while SR retains its real jitter/history. This conservative fallback is not a claim of temporally stable NR.
Validation:
See implementation and contract, Linux limitations and detailed validation. No proprietary runtime, SDK, game data, binary, save or cache is included.
Contributor screenshots of the updated menu. The subsequent descriptive label and placement were approved in the running game before publication. No screenshots or generated previews were captured by the agent.
i'll leave a couple screenshot of the result:

with "intense" profile:
with "balanced" and using the in-game preview mode:

the new tab DLSS 5 into the options:

another couple screenshots of the "intense" profile:

Can we have DLSS 5 / neural rendering as a sub-menu within graphics instead of it's own tab?
Thanks for this, it's a lot of careful work: the candidate/rollback around feature creation, the deferred release through
later(), the coalesced edits and the non-blocking timestamps all look right to me. I'm leaving COMMENT because a few things in the render path change how DLSS SR behaves even for people who never get NR running.What "Neural Rendering" means here should be spelled out for maintainers. This is NGX feature 18, which the public SDK still calls
Reserved18. TheDLSSNR.*parameter names come from community documentation, not from NVIDIA headers, and it needs a user-suppliednvngx_dlssnr.dll. On Linux there's no known native runtime, so that path only probes. The code gates all of this properly at runtime, and the no-SDK stubs look complete. Still, it's an undocumented contract that a driver update can change under us, so whether to ship it outside an env opt-in is a maintainer call.+1 to the earlier comment about making this a sub-menu under Graphics. Two more data points:
HOOKSHOT_NGXand on AMD/Intel.row_shown()has nodlss_built()check forTAB_DLSS5, while the Upscaler row does hide viaur::upscaler_shown(dlss_built(), ...). So most users get a tab of ~19 rows that can only say "not built".TAB_MOTION). A "DLSS 5" row under the Upscaler, shown only when DLSS is built, could open the same way. That would also drop theTAB_COUNTchurn in test_audio_output_menu / test_framegen_preset / test_rumble_menu / test_stick_dead_zone.Other points:
test_dlss_nr_*.pydefault to--cxx g++but aren't inARGSin tests/run_all.py. run_all only checks for the compiler when it's named there, so a runner without g++ fails these instead of skipping them. Please add them like the other--cxxtests.dlss_nr_composite_comp_spv.hisn't covered by the shader-to-header check in tests/test_dlss_actor.py, which covers the other dlss_*.comp files. Worth adding it to that list.dlss5_debugis saved to the ini. If someone leaves "Device depth" or "Motion vectors" selected, the next launch starts with SR bypassed and the debug buffer on screen. I'd keep the debug view session-only.dlss_mode()only returns 1/2, so FSR values on thedlsskey don't collide with the NR gate, and thedlss5*ini keys are separate. Both PRs edit vk_dlss.cpp/vk_menu.cpp heavily, though, so whichever lands second needs a careful rebase. main has also moved in vk_dlss.cpp, vk_menu.cpp and vk_main.cpp since your base.@ -105,0 +325,4 @@full_barrier(cmd);}if (NVSDK_NGX_FAILED(r) || !candidate) {temporal_later([candidate, candidate_params] {This rebuilds the NR feature, and reallocates
nr_output/nr_composed, whenever the render size changes. That bypasses the 32-frame / 2 s rate limit thatrebuildhas. With Resolution Auto,rw/rh(in->width/height) move with the game's dynamic resolution, so this can be a CreateFeature plus twofull_barriers on every size step. If any one of those creations fails,refused()setsnr_failedand NR stays off until Retry.SR avoids this with a size range:
make_featurekeeps the feature whilemin_rw <= rw <= feature_rw, sizess.coloratfeature_rw/rh, and passes the real size as a subrect. You already set theDLSSNR.*Subrect*keys, so creating NR atfeature_rw/feature_rh(and the images at that size) and passingrw/rhas the subrect should give the same behaviour, assuming the runtime honours subrects.While NR is requested and HDR is Native, this branch runs every frame and sets
reset = trueevery frame. That reachesep.InResetfor DLSS SR, so SR's temporal history is wiped on every frame: no accumulation, worse AA, more shimmer. Someone who saved NR On and later switches to Native HDR silently gets a degraded DLSS. Only reset on the transition into this state, e.g. whens.nr_runningwas true, then clear it.Same pattern at a lower rate. While NR is requested but blocked (missing DLL, Linux not opted in, no DLSS runtime, ...), this check fails once a second and sets
reset = true, so SR's history is reset every second: a visible pulse once a second for anyone with NR saved On but unusable.drop_nr()is also re-run each time. Reset only when NR was actually running (s.nr_running) or the issue changed.When NR is switched off (and saved Off), the NR feature, its params and
nr_output/nr_composedstay allocated for as long as DLSS SR is in use.dlss_idleonly frees them after SR itself goes unused for 120 frames. That's fine for Compare A/B, but outside Compare it means the NR model's VRAM is held until restart. Could you release it after a short time off when!menu_comparing()?Question about the inputs.
s.coloris the jittered render (SR getsep.InJitterOffsetX/Y), but NR gets no jitter, exposure or camera data here, and the motion has the jitter removed. If NR keeps temporal history (DLSSNR.Resetsuggests it does), feeding it sub-pixel-jittered frames without the offsets is a likely source of the flicker the history help text mentions. Does the community contract have jitter keys? If not, it may be worth trying NR on an unjittered input.Nit: a fault-injection env var on the production render path. I'd keep this out of the shipped build (e.g. behind a debug define), or at least note it in the docs.
Heads-up for #1473 (recorder thread). NGX records into
cmdthrough its own function pointers, so that PR addsrec::boundary(rec::B_DIRECT)before every NGX create/evaluate in this file. ThisCreateFeature(18)and theEvaluateFeaturebelow (line 526) will need the same, or whatever is queued on the recorder lands after NGX's commands. Whichever PR lands second should add them.@hckrman101 i merged with the new main and fixed what you requested. I also saw the mention in the #1833 and the fact that claude prefers that PR to this, feel free to choose what is better!
Heads-up: this conflicts with main now. Could you rebase onto main and resolve the conflicts? Thanks!
@hckrman101 done! i removed the my fps stats addition since it was extended by other PRs
Thanks for the quick turnaround. I went through the new head against my last review (
3c7b713) patch by patch.Fixed from last time
TAB_DLSS5, like Motion), hidden when!dlss_built(). TheTAB_COUNTchurn in the four menu tests is gone.feature_rw/feature_rhand the real size goes in as the subrect, so a resolution step no longer recreates the feature. The subrect probe in the description is a good check of that.reset |= s.nr_running). No more reset every frame or once a second.rec::boundary(B_DIRECT)comes before NR's CreateFeature/EvaluateFeature, and test_recorder_sync now covers both calls.HOOKSHOT_NR_TESTING. The debug view is session-only (not saved or loaded).test_dlss_nr_*.pytests declareRUN_ALL_ARGS, anddlss_nr_composite.compis in test_dlss_actor's shader list. I regenerated the header with glslang and it matches the source.New
RX_VK_DLSS_START(setting the Upscaler to DLSS) is a new switch that isn't related to NR.RX_VK_DLSS_NR,_NR_DEFAULTand_NR_INTENSITYaren't documented either. I'd drop the first and add the others to docs/dlss5-neural-rendering.md.prepare/evaluatenow holdState::mufor the whole DLSS pass, including NR's CreateFeature. The menu's once-a-seconddlss_nr_check()takes the same lock on the present thread, so a rebuild can stall the menu for a frame. Atry_lockin that periodic check would avoid it. Lock order with #2118's frame generation (g.mu->st().muviangx_init) is fine: nothing takesg.muunderst().mu.Composite pass: the sync and memory look right to me. The new images go UNDEFINED -> GENERAL once in the same command buffer, there are full barriers around the dispatch and NGX calls, destruction goes through
temporal_later, the storage format matches the RGBA16F outputs, and the push constant block is 24 bytes on both sides. No new settings option ids, novk_api.hchange. The touched menu tests' stubs match the new source. It merges cleanly with current main, which already includes #2118.CI: the build and test workflows on this head are waiting for maintainer approval ("action_required"). Only the title check has run.
On the bigger picture, this now avoids the SR-history and VRAM issues I raised when comparing it with #1833, so the two are closer than when I suggested #1833 as the base. Which of them to take, and whether an undocumented feature-18 path ships without an env gate, is still @NotRexed's call. I'm leaving this as a comment for that reason and for the mojibake fix.
This was an en dash (
%d–%d of %d) on main. The merge turned it into mojibake, so the Inventory page now shows–between the numbers. Same thing at the teleport·below, and in the"Café"comment in vk_dlss.cpp (around line 454). Restoring those three lines from main fixes it. Your editor or merge tool probably re-read the UTF-8 file as Windows-1252, so it's worth checking it's set to UTF-8.@ -2523,3 +2787,3 @@ui::text_mid(c, c.f.heading, 23 * s, x + 28 * s, ty, shown ? ui::kInkBright : ui::kBannerInk, tab_titles[i]);ui::text_mid(c, c.f.heading, 23 * ts, x + 28 * ts, ty, shown ? ui::kInkBright : ui::kBannerInk, tab_titles[i]);hits.add(x, 0, x + tw[i], hh, menu_hit::kTab, i);x += tw[i];Same mojibake: this was
"%s · %s"on main. The teleport list now shows·.Nit: this sets the Upscaler to DLSS from a new
RX_VK_DLSS_STARTswitch, which doesn't seem related to NR (a test helper?). I'd drop it, or document it with the otherRX_VK_DLSS_NR*switches above.Can you update screenshots too please?
Ok thanks for the review @hckrman101 , i updated the code.
I also merged with the new main and solved the new conflicts!
Here the new screenshots:
I checked the head against the open points from the last review. The three mojibake strings are gone,
RX_VK_DLSS_STARTis removed, anddlss_nr_check()now usestry_lock(vk_dlss.cpp:961). Nothing else on main uses F8.One new problem. The text merges cleanly with current main, but
tests/test_menu_keys.pythen fails withValueError: substring not foundat line 249. That check came in with #2197 (merged 16:12 today) and cutsmenu_tickatif (open_now.load() && page == 5) {. This PR turns that line into} else if (...)(vk_menu.cpp:3960) and puts the NR Compare branch in front of it. The test passes on this head alone and on main alone. Please merge main and update the test's anchor and stubs for the new branch, rather than reshaping the code to fit the test. The other dlss/menu/recorder/fps/rumble/stick/framegen checks pass on the merge.The bigger call is still the maintainer's: this or #1833 (+49.6k lines, also open and mergeable). There's also whether an undocumented NGX feature-18 path ships with only the menu opt-in.
Fix the comment above, but also can we maybe rename 'DLSS 5' to something a bit more descriptive? eg 'DLSS 5 Neural Rendering'. also the row should be under the upscaler model
This now conflicts with main in
gpu/vk/vk_menu.cpp,gpu/vk/vk_menu.h,tests/test_audio_output_menu.py,tests/test_stick_dead_zone.py. Could you merge main into the branch (or rebase) when you get a chance? I'll take another look once it's up to date.@hckrman101 requested edits done, merged with all the new commits on main, solved the conflits, updated the screenshots above
The Compare menu is now extended to all the DLSS 5 features using the "advanced" option.
I also added all the localization needed for the 13 supported languages
The test_menu_keys anchor problem is fixed. I merged b5a7474 into current main (clean) and ran the dlss, menu, recorder, fps_overlay, rumble, stick, framegen, audio_output, env_on, utf8 and prompt_skip checks: 49 passed, and 3 were skipped because this PC lacks the Vulkan headers and dotnet. hckrman101's mojibake, RX_VK_DLSS_START and try_lock points are handled too. CI's build workflows are still waiting for approval.
What's left isn't code. #1833 was rebuilt today on current main as a standalone NGX feature-18 path that runs before the HUD, and its CI is green. So the two are now real alternatives, and only one of them can land. This one has the Graphics submenu hckrman101 asked for, hides on builds without NGX, has its strings in all 13 languages, and has Compare. #1833 runs inside the temporal chain, before the HUD. The other open question for @NotRexed is whether an undocumented feature-18 path ships with nothing but a menu opt-in.