fix(vk): FSR 3.1 frees its images once the chain lets it go, not at its next upscale #556
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
beanstalk: approved @ 1697603
beanstalk: approved @ 2c5a62e
beanstalk: approved @ 4fd82b7
beanstalk: approved @ 64d6d09
beanstalk: approved @ 6f91fae
beanstalk: approved @ 70a78f9
beanstalk: approved @ 8d361dc
beanstalk: approved @ 9d8356e
beanstalk: approved @ abf2227
beanstalk: approved @ d82f202
beanstalk: approved @ e5f1e40
beanstalk: approved @ ee8ab5f
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!556
Loading…
Reference in a new issue
No description provided.
Delete branch "zeldaootr/Longshot:fsr3-release-frees-its-images"
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?
Type: fix · Risk: low · Tested on: Linux x86-64 (game-free); Steam Deck OLED, SteamOS 3.9.5, RADV (a tester's run) · Needs: none
Why
A player who tried AMD FSR 3.1 and went back to the game's own upscaler kept FSR 3.1's images in video memory for the rest of the session: about 40-60 MB on the Steam Deck, about 320 MB at 4K. The tracker has no issue for it (searched).
How to reproduce
Seen on: Steam Deck OLED, RADV VANGOGH, Mesa 26.2.0-devel git-5c65d4fc31, SteamOS 3.9.5 (a tester's run, main
7ff5256e); first found by readinggpu/vk/vk_fsr3.cpp, and the game-free test reproduces itSettings and switches: defaults (on the Deck: output 1280x720, Render resolution 50%, the game's own upscaler, frame generation off, VRAM budget 2.2 GB)
Steps: in Kokiri Forest, set the Upscaler to AMD FSR 3.1, wait 10 s, set it back to the game's own; wait for the
not used for 120 framesline and 5 s more, then read the nextvk: VRAM:lineExpected: FSR 3.1's images are freed: the renderer holds less besides the textures than before FSR 3.1 was tried
Actual: on main what the renderer holds besides the textures ends within 29 MB of where it began (-29 and +29 MB in two runs): FSR 3.1's images wait for its next upscale, which never comes
What changed
FSR 3.1's release now asks the chain to free its images a few frames on, once the GPU is past them, instead of leaving the ones still in flight for an upscale that never comes. The memory comes back when the Upscaler row leaves FSR 3.1.
release()ingpu/vk/vk_fsr3.cppretires its images until the GPU is past them, but freed only those already complete; the rest waited for FSR 3.1's next upscale or prepare. It now asks the chain to free them a few frames on (temporal_later), asTemporalEngine::releaseexpects.tests/test_fsr3_release_frees.pycompiles the realImage,State,destroy_now,drop_image,free_dead,all_imagesandreleasewith the timeline andtemporal_laterstood in for: release while the GPU is behind, then the GPU past it, and every image and view must be destroyed exactly once, none early.Measurements
Verdict: pass, it helps. On a tester's Steam Deck OLED, after leaving FSR 3.1 the renderer held about 74 MB less besides textures than on main (median 1,091.5 against 1,165.5 MB); within each run it fell by 115 and 102 MB with this PR and stayed within 29 MB on main. The texture cache, at its budget there, took up part of the space: used minus free, textures included, came out the same in both builds. Switching back to FSR 3.1 makes its images again and the picture is right. The game-free test: not all images freed on main, 22 of 22 here.
Hardware: Steam Deck OLED, AMD Custom APU 0932 (RADV VANGOGH), 16 GB, Mesa 26.2.0-devel git-5c65d4fc31, SteamOS 3.9.5 (build 20261023.100), kernel 7.2.7-valve2, Game Mode, docked, stock clocks (dukenheimer's run, test request T-UH7H); game-free: Linux x86-64 server, no GPU or game
Scene: Kokiri Forest after Continue, standing; main's own defaults on that Deck (Quality preset Auto, output 1280x720, Render resolution 50%, so FSR 3.1 upscaled 640x360 to 1280x720; frame generation off; VRAM budget 2.2 GB)
Method: the
vk: VRAM:lines (logged every 600 frames) oflongshot_log.txt: the last one before FSR 3.1 was set (after 25 s standing), and the next one after thenot used for 120 framesline plus 5 s; "besides textures" is used, minus the free space in its blocks, minus the textures. Upscaler set through the menu's own setter (control bridge): FSR 3.1 for 10 s, back to the game's own, later FSR 3.1 again for 12 s and a picture. Four runs, interleaved (this PR, main, main, this PR), one test folder with warm caches and the binaries swapped; the median of each build's two runs. Game-free:python3 -I -B tests/test_fsr3_release_frees.py --cxx g++ --headers(the Vulkan headers'include) at93f9d02band at6732e8b3(rebased onto mainaa95d35f), with g++ 13.3 and with clang 23.1.5; before that, atb5ec0f79and69fd56bdon main53f96d78, and before the first rebase at97223942andacd34022, twice each, alternatingHow to reproduce: build main
7ff5256e, and main with this PR's renderer fromacd34022(the PR changes onlygpu/vk/vk_fsr3.cppand a test), both x86-64-v3 with the release play profile and LLVM 23.1.5; then the steps under How to reproduce, reading thevk: VRAM:lines7ff5256eacd34022(main with this PR's renderer)The textures, which fill up to their 2,560 MB budget there, held 48 to 85 MB more in this PR's runs, so the total did not fall. The expected 40-60 MB was for the Deck's 1280x800; this run was docked at 1280x720 and measured 47 to 101 MB less besides textures than main. The tester's report with the pictures: #556 (comment)
aa95d35f(with the test,93f9d02b)6732e8b3Flags and settings
None.
Testing
Tested: Linux x86-64, game-free. The new test fails on the test-only commit
93f9d02band passes at6732e8b3, this branch rebased onto mainaa95d35f, with g++ 13.3 and with clang 23.1.5 (before, it did the same atb5ec0f79and69fd56bdon main53f96d78, and at97223942andacd34022, twice each, alternating) (python3 -I -B tests/test_fsr3_release_frees.py --cxx g++ --headerswith the Vulkan headers'include). This PR's own tests and the checks its fix commit edits ran at both commits, and once more onland/integration27553c83 (main7ff5256ewith this PR and twelve other fixes merged), where the thirteen fixes' tests and edited checks pass, 16 of 16; the fullpython3 -I -B tests/run_all.pyran on that branch too (see the checklist).In the game: dukenheimer ran test request T-UH7H on a Steam Deck OLED (RADV VANGOGH, Mesa 26.2.0-devel, SteamOS 3.9.5, Game Mode, docked) and reported a pass on 2026-11-15 at 03:06 UTC (#556 (comment)). The builds were main
7ff5256eand main with this PR's renderer built from its head then,acd34022(6732e8b3after the rebases, the same change bygit patch-id; not the combined build), four runs interleaved. FSR 3.1 itself ran on the Deck: the Upscaler was set to AMD FSR 3.1 through the menu's own setter, upscaling 640x360 to 1280x720, for 10 s, then back to the game's own; FSR 3.1 let its images go (thenot used for 120 framesline, 8 to 9 s after), the nextvk: VRAM:line showed the drop above, and FSR 3.1 set again made its images again with the picture right in all four runs (nothing missing or garbled in the pictures). No crash, device lost or device fault; the kernel's amdgpu lines were only the display'sLosing delta precision while programming shaper LUTnotices.The branch has been rebased since the tester's run, onto main
aa95d35f, with its commits re-authored under the forge's noreply address; each commit's change is identical to before bygit patch-id, so the commits named above are the ones tested and the result stands for this head (80f66c9b).Not tested: FSR 3.1 on Windows, and on another GPU maker. The Deck's own 1280x800 (the run's output was 1280x720), and 4K, where about 320 MB is expected back. More than one switch away from FSR 3.1 in a session. Frame generation, whose images this PR does not touch (see Risks).
Must be tested: None
Risks
What could break: The free runs through the chain's
temporal_later, after the GPU is past the images, so an image freed early would show as a validation error or a device lost right after a switch away from FSR 3.1 (none in the tester's four runs). About 39-58 MB come back at the Deck's 1280x800 and about 320 MB at 4K, once per switch away from FSR 3.1; where the texture cache is at its budget, as on the tester's Deck, the textures take the space up. Found with it and not fixed here: frame generation's images are never released, and FSR 3.1 remakes about 43 MB at each resolution step.Turning it off: revert the commit
Compatibility: Nothing changes
Checklist
Everyone
type(scope): description) of the status line's type.main. Onto mainaa95d35fwith no conflict, the commits re-authored under the forge's noreply address: each of the three commits' changes (the test, the fix, thedocs/tested/file) is identical to before bygit patch-id. Since53f96d78, main changed nothing in this PR's files.python -I -B tests/run_all.pypasses (any failure that also fails onmainis named). Run on this branch at157d688bon main53f96d78, before this rebase (80f66c9bnow, the same patches bygit patch-id; the Vulkan and SPIR-V headers from the CPM cache, 8 at once, on a loaded Linux x86-64 server): 531 passed, 15 failed, 48 skipped. The 15 are the ones that fail on main53f96d78in the same run:test_appimage_player_build,test_bake_portability,test_cpm_discovery,test_crash_dialog,test_env_on,test_lift_cache,test_lift_cleanup_error,test_make_game_cache,test_pipeline_tour,test_readback_late,test_vk_pgo,test_vram_budget_row,test_walk_key,nx2/test_mesh_first_types.pyandnx2/test_texture_init_barrier.py. Main's run also timed outtest_fpx_sticky(it passes alone there). After the rebase onto mainaa95d35f, at80f66c9b: 10 checks, this PR's test and those that read its changed files, with g++ 13.3 and with clang 23.1.5: all 10 pass.third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.docs/tested/for each new measured run (format indocs/tested-configurations.md).docs/tested/2026-11-15-fsr3-release-dukenheimer-t-uh7h.md, the tester's run;scripts/tested_configurations.pyandtests/test_tested_configurations.pypass with it.mainand passing here.RX_VK_ONLY=1 RX_RELEASE=1 RX_TARGET=windowswith llvm-mingw 20261104 linkedlongshot_vk.dll(sha256 25117493...), and the same withoutRX_TARGETlinkedlongshot_vk.so; the changed file has no new warning under-Wall -Wextraon either platform againstmain. The tester's renderer linked for Linux (x86-64-v3, LLVM 23.1.5). After the rebase onto mainaa95d35f,gpu/vk/vk_fsr3.cppat80f66c9bchecked whole (-fsyntax-only -Wall -Wextra, clang 23.1.5 for Linux and llvm-mingw 20261104 for Windows): the same warnings as main aa95d35f's, none new.Filled in: the full game-free suite on the combined branch, the Windows and Linux builds, and the test request T-UH7H. Still work in progress until a Steam Deck run is in.
Test request T-UH7H: pass
Built main
7ff5256e, and main with this PR's renderer from its headacd34022(the PR changes onlygpu/vk/vk_fsr3.cppand a test).Output 1280x720, render 640x360 (main's own defaults on this Deck), so FSR 3.1 upscaled 640x360 -> 1280x720.
Result
The
vk: VRAM:lines (MB). "Besides textures" is from the same line: used, minus the free space in its blocks, minus the textures.and 1,177 MB on main. That is 47 to 101 MB less, 74 on average; the request expected about 40-60 MB at 1280x800.
they began.
2,560 MB budget here, held 48 to 85 MB more in this PR's runs.
vk: AMD FSR 3.1: not used for 120 frames (...): what it made and its images let go; the next upscale with it makes them again, 8 to 9 s after leaving FSR 3.1 (about 15 fps) in all four runs. Main logs the same line.(
vk: fsr3: 640x360 -> 1280x720), and nothing is missing or garbled (pictures attached: before, with FSR 3.1, and FSR 3.1 again).precision while programming shaper LUT" notices, 6 a start.
Setup
kernel 7.2.7-valve2. Game Mode, docked, stock clocks.
7ff5256e; main + this PR, its renderer built from the PR's head. Both for x86-64-v3 with the release play profileand LLVM 23.1.5. One test folder (warm caches) with the binaries swapped.
1280x720, Render resolution 50%, the game's own upscaler, frame generation off, VRAM budget 2.2 GB.
vk: VRAM:line before is the last one logged by then.not used for 120 framesline, then 5 s more, then the nextvk: VRAM:line (logged every 600 frames).acd34022f2157d688bb1Thank you, dukenheimer, for T-UH7H on the Steam Deck (#556 (comment)), with FSR 3.1 switched on and off in the game.
Rebased onto main
53f96d78with no conflict: the test and fix commits are the same as before (git range-diff:97223942is nowb5ec0f79,acd34022is now69fd56bd), and the run is added asdocs/tested/2026-11-15-fsr3-release-dukenheimer-t-uh7h.mdin a third commit,157d688b. The description now ticks the rebase anddocs/tested/boxes.Tests run again after the rebase:
tests/test_fsr3_release_frees.pyfails atb5ec0f79(image 1 not freed) and passes at the tip (22 images freed), with g++ 13.3 and with clang 23.1.5. The fullpython3 -I -B tests/run_all.pyon this branch: 531 passed, 15 failed, 48 skipped, the same 15 that fail on main53f96d78in the same run (named in the checklist).gpu/vk/vk_fsr3.cppchecked whole for Linux and Windows: the same warnings as main's, none new.Why the Deck result still holds: main changed nothing in the lines this PR changes. Since the tested base
7ff5256e, main changedgpu/vk/vk_fsr3.cppin one commit,b80a68f1(PsychoV35 compatibility by default): achain_hdrcallback on the chain's engine, true only with HDR output and the PsychoV35 tone mapper, and a colour-format pair check at the start offsr3_upscale.release(),free_dead,drop_imageand the images this PR frees are untouched, and the tester's run had no HDR output, so neither change was on its path.WIP: fix(vk): FSR 3.1 frees its images once the chain lets it go, not at its next upscaleto fix(vk): FSR 3.1 frees its images once the chain lets it go, not at its next upscale157d688bb180f66c9b19Rebased onto
mainaa95d35f(head80f66c9b); the commits are re-authored with the forge's noreply address: no code change, the same patches bygit patch-id.Tests re-run on the new base, g++ 13.3 and clang 23.1.5:
test_fsr3_release_freesfails at the test-only commit93f9d02b(image 1 not freed) and passes at6732e8b3; the 10 checks that are this PR's or read its files all pass. The Deck run (T-UH7H) stands; the description names the new commits.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.