Repository navigation
Conversation
…A's DLLs not included) - gpu/vk/vk_dlss.cpp, the DLSS part of vk_draw.cpp, vk/shaders/dlss_*.comp: the gameplay upscale network's place in the frame taken by DLSS, which draws the 3D at the DLSS mode's size and scales it to the output with the game's depth and its camera's motion. Ported from zortos293/Lichii (its Streamline loader, camera motion and their shaders; Lichii credits Duck912's Eglantine work). - NVIDIA Streamline v2.14.16's headers in third_party/streamline (MIT, gpu/PROVENANCE.md). sl.interposer.dll, sl.common.dll, sl.dlss.dll and nvngx_dlss.dll are loaded from a streamline folder beside the game exe, or the NVIDIA app's DLSS; the interposer and the model must carry a valid NVIDIA Corporation signature (WinVerifyTrust). Windows only: elsewhere DLSS is unavailable. - Menu rows DLSS (after a restart), DLSS mode (Ultra Performance .. DLAA, each with its size for the chosen output; it sets the 3D's scale in place of Resolution) and DLSS preset (J..M, at once); RX_DLSS, RX_DLSS_PRESET, RX_DLSS_DIR over them, RX_DLSS_DEBUG for its inputs. The scale sent to the game is for the output it runs at (the window crop). - readme: the rows, where NVIDIA's files come from; the Lichii credit.
…on top of NotRexed#850's DLSS frame code) A second backend for NotRexed#850's replacement of OoT's gameplay upscale, ported from the FSR 4.1 work on Lichii's OoT branch (madebyjordan/Lichii-Hyrule oot-dev, 7f8ae5b337..c5f2fce17d). It takes the same colour, depth and camera motion as DLSS; DLSS keeps priority when it is on. - vk_fsr4.cpp: AMD's FSR API (FidelityFX SDK 2.4). Only the MIT headers are vendored (third_party/fidelityfx); AMD's signed loader and upscaler DLLs load at run time from RX_FSR4_DIR or beside hookshot.exe. The newest 4.x provider the loader lists is picked explicitly (RDNA 2 and 3 run its INT8 model). LDR, non-linear colour, standard depth. One context per output size, render sizes up to it, so the Resolution row and the game's dynamic resolution need no new context. - Jitter: the game draws without one, so the draws that test or write the scene's depth move by a Halton (2, 3) sub-pixel offset through the viewport, and FSR is told it. The offset is part of the state dyn_pack compares, or a frame whose draws match the last frame's would keep the old one. From Lichii: the phase moves on at the network's pass (where the game's frame ends), not at presents; it is on only while FSR drew the last network pass. - AMD edge line (Lichii, RX 6700 XT): moved up or left, the AMD driver draws nothing into the scene's last column or row, a stale near-white value that became a flickering line in FSR's history. FSR's colour and the motion's depth repeat the column and row before them. Colour going into FSR is cleaned of NaN and Inf and clamped to [0, 1]; the output pass drops NaN and Inf for both upscalers. - FSR history resets when FSR did not draw the last network pass or on a camera cut, not by present count. - Menu: "AMD FSR 4.1" (Off/On, at once; ini key fsr4, RX_FSR4=0/1). Resolution sets what it upscales from (75% Quality, 50% Performance, 100% anti-aliasing only). RX_FSR4_JITTER=0 turns the jitter off. - What changes on native, compared with Lichii: no GPU-time divisor (Hookshot already scales the game's timer, so it keeps full quality), no hunt for the tonemap draw or depth reader (NotRexed#818 takes them where the draws are), no 4/3-only size check. - tests/test_fsr_jitter.py: the jitter is compared and applied, moves on at the network's pass, and the edge repeat is in both passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… images given back - The FSR context is made with FFX_UPSCALE_ENABLE_DYNAMIC_RESOLUTION: the render size changes under it with the Resolution row and the game's dynamic resolution. - vk_fsr4.cpp is Windows only (AMD's signed runtime is), with stubs elsewhere: the Linux build has no LoadLibraryExA. - AMD's dispatches count as work (note_work, vk_work.h), so full_barrier does not leave out the barrier after them as a repeat. - dlss_image gives a replaced image back 120 presents later, as typed_upscale does with its histories, instead of keeping it: DLSS fixes the render size, but FSR can run with Resolution Auto. - The dlss_*.comp headers regenerated at SPIR-V 1.6, as NotRexed#850 makes them. - readme: FSR 4 claims limited to what was tested (RX 6700 XT, INT8). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There is no AMD loader on Linux, so the upscaler library itself (amd_fidelityfx_upscaler_vk.so) is loaded with dlopen from RX_FSR4_DIR or beside the game. A Vulkan FSR 4 build reads the SDK's older backend description and records with descriptor buffers: the description is chained next to the current one, and VK_EXT_descriptor_buffer is enabled only when the library is there. Windows is unchanged. BITMAPFILEHEADER joins the POSIX windows.h shim, for the menu dump. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… exposure A Vulkan FSR 4 build lists its Auto provider before INT8 and FP8, so taking the last of equal versions chose FP8 on hardware without it. It also rejects a dispatch without an exposure: the game's colour is already tonemapped, so it gets a 1x1 R32F of 1. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The file was Windows-only, which hid the Linux loading. Remove the guard and its stubs, and say in the readme what Linux needs. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first half of an FSR backend: its shaders. Adds AMD's FidelityFX SDK v1.1.4 GPU sources under third_party/fidelityfx-sdk, unmodified and MIT, with a provenance note, and scripts/fsr3_shaders.py to compile the eleven variants into gpu/vk/shaders/fsr3_*_comp_spv.h. Eleven, not eight: the eight passes, plus wave-free variants of both pyramids for devices without the subgroup operations the single-pass downsampler prefers, and an accumulate compiled with sharpening on. The option set lives in one place in the script because each option is a promise about the inputs -- HDR colour, low-resolution motion that is not jittered, reversed depth -- and the host code has to hand the passes what they were compiled for. This is the SDK-source route rather than AMD's FidelityFX API, so no runtime library is needed, none is included, and one code path serves Windows and Linux. NotRexed#577 vendors AMD's API headers for the other route under third_party/fidelityfx; if both land, one should go. The headers are checked in, like every other shader in gpu/vk/shaders, so a clone builds with no glslang. tests/test_fsr3_shaders.py recompiles all eleven and compares, and validates each module with spirv-val, so the headers cannot drift from their sources and an invalid module is caught here rather than on a device. It is wired into run_all's tool table, and glslang-tools is added to the Linux CI step that had spirv-tools only. That costs about 1.3 MB of generated hex. Generating at build time would remove it at the price of a glslang dependency for every build. No renderer change: nothing includes these headers yet. The host side that records the passes is the next commit. Checked here: all eleven compile and pass spirv-val, the check passes, and it fails as it should on a changed word in a header, a changed compile option and a missing header. python -I -B tests/run_all.py: 90 passed, with the same 8 failures and 12 skips as upstream/main (a missing clang++ or SPIR-V headers). Assisted-by: Claude Opus 5 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The renderer hands FSR tonemapped, square-root encoded colour (LDR), a standard D32 depth and render-pixel motion, so build the passes that way (HDR input off, inverted depth off) instead of converting the inputs. Regenerate the eleven headers, make --check ignore glslang's version comment (same SPIR-V) and pin the options in tests/test_fsr3_shaders.py. The note in third_party/fidelityfx-sdk no longer points at docs/upscaling.md, which this series does not bring in. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The backend runs on the frame chain NotRexed#1008 brings (dlss_dispatch, fsr4_evaluate, FsrJitter, opts.fsr4), so it needs that pull request until it lands. Merged rather than rebased so its commits keep their hashes and drop out of this diff once it is merged. The conflict in gpu/vk/vk_menu.cpp keeps both sides: help_of from NotRexed#1008 and kMenuWidth = menu_hit::kWidth from NotRexed#946. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first half of the backend: what an evaluation needs before one can be recorded. gpu/vk/vk_fsr3.cpp builds the eleven pass pipelines from the SPIR-V the previous commit checked in, the two samplers every pass declares at bindings 1000 and 1001, and the SDK's eighteen internal images. The resource table and the per-pass binding lists are written out in the SDK's order rather than derived, because they are the SDK's and not ours: ffx_fsr3upscaler.cpp fixes the formats and sizes, and each pass file numbers its own bindings. One wrong entry is a validation error at best and a wrong picture at worst. The one place that knowingly departs from the SDK is the luma history, allocated R8G8B8A8_UNORM because that is what the pass files declare as its storage format, where the SDK allocates RGBA16F -- a storage format qualifier has to match. supported() asks once whether the device has push descriptors and every storage format the images need, so a device that cannot run the passes says so before an allocation fails mid-frame rather than after. prepare() re-makes the images when the render or upscale size changes and tears everything down rather than leaving a half-built set behind. Nothing calls this yet, so there is no behaviour change. Builds clean with RX_VK_ONLY=1, 0 warnings. Linux, RTX 5060 Ti, driver 615.71.09. Assisted-by: Claude Opus 5 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The other half: the constants, the clears, the barriers and the nine dispatches, following the SDK's ffx_fsr3upscaler.cpp rather than inventing an order. cbFSR3Upscaler is laid out field for field with a static_assert on its 148 bytes, because every pass reads it by offset and a field out of place is a wrong picture rather than a compile error. What is faithful to the SDK and worth checking in review: the jitter phase count moves one step a frame toward 8*(ratio^2) instead of jumping; the SPD counter, its mips and the previous-nearest-depth scratch are cleared every frame while the accumulation and frame info are cleared only on a reset; the Lanczos weights are built once and copied in; the two ping-pong sets swap on parity at the end; and RCAS only runs when sharpening is asked for, otherwise the sharpening accumulate variant writes the output directly. Three things specific to this renderer rather than the reference. Barriers are synchronization2, which is what this tree loads (vkCmdPipelineBarrier is not in vk_loader.h). The constant blocks live in one host-visible mapped buffer with a set of slots per frame in flight, so writing one frame cannot disturb a frame still being read. And descriptors are pushed per pass, with the two samplers at the bindings the SDK's GLSL fixes them to. upscale() refuses rather than guesses. No colour, depth or motion is a refusal, and so is a missing near plane or field of view: device_to_view_depth and tan_half_fov are built from them, and a guessed camera makes disocclusion wrong in a way that reads as a renderer bug. Nothing calls this yet, so there is no behaviour change. Untested beyond compiling: builds clean with RX_VK_ONLY=1, 0 warnings, Linux, RTX 5060 Ti, driver 615.71.09. No pass has executed, so nothing here is claimed to produce a correct image yet. Assisted-by: Claude Opus 5 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The reference implementation documents that device_to_view_depth only scales FSR's disocclusion thresholds and uses a typical near plane and field of view, so refusing without the real camera was stricter than the evidence warrants. Inputs defaults both instead. Assisted-by: Claude Opus 5 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Read the camera for finite standard depth, bind the SDK's default exposure (an image of zero reads as 1.0), and use the no-wave pyramids where the device lacks the subgroup operations. The images of an old size were destroyed while in flight and the new ones never left UNDEFINED: retire them and restart the history instead. Add available() and reason() so the menu can show why it cannot run. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FSR 3.1 now runs on the chain FSR 4.1 uses (dlss_dispatch), from the same colour, depth, motion and jitter, with near, far and field of view read from the camera matrix; the output goes through dlss_output.comp as before, and the history restarts whenever the engine changes. The choice is Off, Auto, FSR 4.1 or FSR 3.1. Auto takes FSR 4.1 when AMD's library is present with a model for the card, else the built-in FSR 3.1, else the game's upscale; FSR 4.1 failing in play falls back to FSR 3.1. gpu/vk/upscale_engine.h holds that choice and the camera read, plain data so tests/upscale_engine_test.cpp checks them without a game or a GPU. RX_UPSCALER and upscaler= are the new keys; RX_FSR4=0/1 and an old ini's fsr4= still work (Off and Auto). The menu row is still the AMD FSR 4.1 row, whose On is now Auto: the next commit makes it the four-value row. Assisted-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
|
Hi! This PR has merge conflicts with |
Author
|
I will rebase all PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 2 of 3 of the split of #871. Adds FSR 3.1 as a second engine on the frame chain from #1008, so cards and systems without FSR 4 still get a temporal upscaler.
The branch merges cleanly on current
main. It carries one merge of #1008, whose conflict with #946 invk_menu.cppis resolved by keeping both sides (kMenuWidth = menu_hit::kWidthand #1008'shelp_of).What changed
gpu/vk/vk_fsr3.cppand.h: FSR 3.1's images, pipelines and nine dispatches. Three commits are notquiteog's, from Compile AMD's FSR 3.1 upscaler passes from the FidelityFX SDK #822.gpu/vk/upscale_engine.h: the choice between Off, Auto, FSR 4.1 and FSR 3.1, as plain data thattests/upscale_engine_test.cppchecks without a game or a GPU. Auto takes FSR 4.1 when AMD's library is present with a model for the card, else FSR 3.1, else the game's upscale. If FSR 4.1 fails in play, FSR 3.1 takes over.RX_FSR4=0/1andfsr4=still read as Off and Auto. New:RX_UPSCALER=off|auto|fsr4|fsr3andupscaler=.Known limit until part 3: the menu row is still
AMD FSR 4.1, whose On now means Auto. Without AMD's library FSR 3.1 runs while the row says no FSR 4 was found. Part 3 replaces the row.Left out on purpose from #821 and #822, because none of it is on the tested path: the input contract, the seam, the census, the camera hooks and
HOS_FPS_FORCE.How it was tested
e0f3ccfa, Ultrawide on6095c4d)5120x2160 -> 5120x2160, switched live several times, no crash or device lost in the log.vk_fsr3.cpp,vk_fsr4.cppand the selection code are unchanged from that treehookshot_vk.sobuilds with 0 warnings.tests/run_all.py fsr upscale menu: 8 passedThat run used
RX_VK_NO_WARM=1,RX_VK_NO_PREDICT=1andRX_VK_PRECOMPILE=0because of #803, andRX_VK_ANISO=16.Not tested
🤖 Generated with Claude Code