Repository navigation
AMD FSR 4.1 as a second upscaler engine, on #841's frame chain - #1008
madebyjordan wants to merge 8 commits into
Conversation
ffd25be to
322e690
Compare
322e690 to
b9ce469
Compare
bbd11e9 to
050fc55
Compare
hckrman101
left a comment
There was a problem hiding this comment.
Read the rebuilt version (050fc55) against current main. Pulling the frame chain out into vk_temporal.cpp behind a small engine interface is a good shape, and the move looks faithful: I diffed temporal_upscale against main's dlss_upscale and prepare against make_feature. The only changes are the engine indirection, s.drawing's handover and the near/far/fov capture, so the DLSS half should behave as it did. It merges cleanly with main, CI is green (including the DLSS+FSR link check), there are no new HOS_OPT ids (the new values 3/4 go under the existing dlss key), and nothing new needs adding to tests/run_all.py. Provenance is documented: the headers carry AMD's MIT notice, the README pins SDK v2.4.0, and the signed DLLs aren't vendored.
What I'd still look at, inline:
~ContextcallsffxDestroyContextfrom a function-static at process exit (likely a hang or crash on close).- The Linux-only code isn't compiled anywhere in CI.
- Nit: FSR's inputs are made at the output size.
On the other FSR PRs: #1008 isn't superseded. #1095 and #1313 only vendor FSR 3.1 shader sources, with no file overlap. #1096/#1097 were stacked on the old #1008 (dlss_dispatch, the #850 base) and touch the same files (vk_fsr4., vk_dlss., vk_menu.cpp, vk_draw.cpp). They're dirty now and would need rebasing onto the TemporalEngine interface here, where FSR 3.1 would fit as a third engine. #1335 is a separate FSR 3.1 + FSR 4 + DLSS NR stack (its own vk_ffx.cpp/vk_fsr3.cpp/vk_ngx.cpp) that edits upscaler_rows.h, vk_dlss.cpp, vk_menu.cpp, vk_draw.cpp, vk_main.cpp, build.py and make_game.py too. The two will conflict whichever lands first, so it's worth deciding which FSR 4 path main takes before both go further.
| uint32_t width = 0, height = 0; // (its output, which is also the most the render size can be) | ||
| uint64_t memory = 0; // (what AMD's library says it holds) | ||
| ~Context() { | ||
| if (context) lib().destroy(&context, nullptr); |
There was a problem hiding this comment.
This destructor also runs at process exit: st()'s function-static State (and any temporal_later lambdas still holding a shared_ptr<Context> in vk_temporal's dead) get destroyed then. Hookshot leaves through ExitProcess (hos_main.c, hos_relaunch.c) and never destroys the device. So on Windows this calls into AMD's DLL after it has already had its DLL_PROCESS_DETACH (it was loaded after hookshot_vk.dll, so it detaches first), while other threads have been killed, possibly inside the driver holding its locks. On Linux, exit() runs it while the render thread may still be recording with the same context. Either way it's a likely crash or hang on close. DLSS on main avoids this because its handles are raw pointers with no destructor. The simplest fix is to leak the statics, e.g. static State& s = *new State; here (and the same for Library), so nothing runs at exit.
| made = 2; | ||
| } | ||
| // (the inputs at the context's largest render size: the render size moves under it without new images) | ||
| *in_w = ow, *in_h = oh; |
There was a problem hiding this comment.
Nit: this makes the chain's colour/depth/motion images output-sized even at 33%. At 4K that's about 130 MB (RGBA16F + R32F + RG16F) instead of about 15 MB. It's fine with maxRenderSize = output for Auto, but the fixed modes could ask for the mode's size and only grow when the render size does. Not blocking.
| env: | ||
| RX_VK_ONLY: '1' | ||
| RX_RELEASE: '1' | ||
| HOOKSHOT_FSR: '1' |
There was a problem hiding this comment.
This only compiles the Windows side. All the #ifndef _WIN32 code in vk_fsr4.cpp (dlopen, the _DEPRECATED backend chain, unit_exposure) and the descriptor-buffer feature in vk_main.cpp never gets compiled in CI, and the PR says Linux wasn't tested. Because it's header-only, a cheap step in an existing Linux job (for example HOOKSHOT_FSR=1 on the AppImage/source-checks vk build, or a single -fsyntax-only of vk_fsr4.cpp with -DHOOKSHOT_FSR -Ihost/posix) would at least keep it building.
050fc55 to
d76e877
Compare
|
Thanks for the careful read, and for checking the move against your originals. All three are addressed in the new commit:
A second pass turned up a few small things, fixed in the same commit:
Also rebased on current |
The inputs NotRexed#841 builds for DLSS (scene camera and depth, the colour as the network samples it, camera and actor motion, the host camera jitter) are not DLSS's own, so they move out of vk_dlss.cpp into vk_temporal.cpp, a frame chain with engines behind a small interface (TemporalEngine: start, prepare, evaluate, release, memory). vk_dlss.cpp keeps NGX, the feature and its evaluation, unchanged in what they do. vk_fsr4.cpp is the second engine, through AMD's FSR API (MIT headers in third_party/fidelityfx; AMD's signed DLLs are the player's, loaded at run time). - Upscaler row: Game's own, NVIDIA DLSS, NVIDIA DLAA, AMD FSR 4, AMD FSR 4 Native AA. FSR uses DLSS's Render resolution steps (same ratios). Saved key stays dlss; opts.dlss is now opts.upscaler. - Build switch HOOKSHOT_FSR=1 (make_game.py --fsr, a Builder tick) compiles vk_fsr4.cpp with AMD's headers and puts the camera jitter into the game, as an NGX build does. Default builds are unchanged. - RX_VK_FSR=0/1/2, RX_VK_FSR_DIR for AMD's library. - The DLSS CI job also builds FSR, and runs when the chain changes. Co-authored-by: NoBoDyZ <neotrax70@gmail.com> Co-authored-by: hckrman101 <239247847+hckrman101@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…caler On a GPU without cooperative matrices (AMD RDNA 2) the fixed shares' own upscale networks (67% 6676619641320ba7, 58%, 50%, 33%) are left out and upscale_stub stretches the scene linearly, so DLSS or FSR only ever saw the game's 3/4. The stub now offers the frame to the temporal upscaler first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ler's input Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n upscale_stub Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…upscaler Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ender size, its Linux side built in CI - vk_fsr4.cpp lib() and st(), vk_temporal.cpp st(): leaked statics. Hookshot exits through ExitProcess / exit() with the device alive; a destructor then called ffxDestroyContext after AMD's DLL detached (hckrman101's review). - FSR's inputs are as large as the largest render size its context has had, not the output's (about 15 MB instead of 130 MB at 4K and 33%). - linux-appimage.yml builds hookshot_vk.so once more with HOOKSHOT_FSR=1, so the #ifndef _WIN32 parts of vk_fsr4.cpp and vk_main.cpp are compiled in CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Renaming it to opts.upscaler broke every test that builds its own Options stand-in (test_audio_output_menu, test_stick_dead_zone). The saved key was dlss all along; the field keeps that name, documented as the Upscaler row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d76e877 to
514bd35
Compare
… PIPESTATUS) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AMD FSR 4.1 as a second upscaler engine, on the frame chain #841 merged for DLSS. Rebuilt on current
main: it no longer carries #850's DLSS.What changed
vk_dlss.cppintovk_temporal.cppbehind a small engine interface.vk_dlss.cppkeeps NGX, the feature and its evaluation, and does the same thing as before.vk_fsr4.cppruns FSR 4.x through AMD's FSR API on those same inputs, taking the newest FSR 4 AMD's library offers (never an older FSR in its place). Only AMD's MIT headers are vendored (third_party/fidelityfx); AMD's signed DLLs are the player's.dlss.make_game.py --fsr/HOOKSHOT_FSR=1/ a Builder tick. It also turns on the camera jitter in the game. Default builds are unchanged.Tested
tests/run_all.py: 177 pass; the 5 failures also fail on plainmainhere (Windows symlinks, local clang warnings and headers).Related
🤖 Generated with Claude Code