fix(vk): a mesh fallback program with bigger payloads reuses the record arena #551
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
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!551
Loading…
Reference in a new issue
No description provided.
Delete branch "zeldaootr/Longshot:mesh-fallback-records-shared"
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 (two testers' runs) · Needs: none
Why
On GPUs that draw mesh shaders through the compute fallback (by default Linux AMD cards, the Steam Deck among them), each program needing a bigger payload buffer made another 64 MB record buffer that nothing used again, so video memory went for nothing over a session.
How to reproduce
Seen on: Linux x86-64, game-free (the real
fallback_buffers_ofwith stand-in Vulkan calls); in the game, a Steam Deck OLED (RADV, the compute fallback by default), where the leftover arenas show as about 80 to 195 MB more GPU memory than with the fixSettings and switches: defaults (the compute mesh fallback is the default on RADV)
Steps: on
mainaa95d35fwith this PR's test added (6e6a3fb7), runpython -I -B tests/test_fallback_buffer_cleanup.py --cxx g++: two programs of different payload sizes on one threadExpected: both use the one record arena
Actual:
FAIL payload_growth_keeps_records: a bigger payload made another record arenaWhat changed
A mesh fallback program whose payload needs a bigger buffer now reuses the thread's 64 MB record arena instead of making another one, so video memory no longer grows by an arena for each such program.
fallback_buffers_of()ingpu/vk/vk_draw.cppgives a new payload buffer the newest pair's record buffer when it is big enough (it always is: every program takes the same fixed area), instead of making another; on a failure later in the function the shared buffer is not freed.tests/fallback_buffer_cleanup_test.cppgetspayload_growth_keeps_records(a program with bigger payloads must keep the records buffer and its address) andshared_records_payload_failure(a growth that shares the arena and then cannot make its payload, or gets no address for it, leaves the shared arena and the set before it alone; it passes on main too, where nothing is shared, and guards the fix's clean-up), run bytests/test_fallback_buffer_cleanup.py.Measurements
Verdict: fixed: one record arena instead of two in the game-free test (two interleaved rounds); on two testers' Steam Decks about 80 MB less held besides textures (dukenheimer, a 5-minute route) and 81 and 195 MiB less GPU memory on a still view (p0lux), fps not lower.
Hardware: Linux x86-64 server (Ubuntu 24.04), no GPU or game used; gcc 13.3, clang 23.1.5
Scene: no game: the game-free check
Method:
python3 -I -B tests/test_fallback_buffer_cleanup.py --cxx g++at the test-only commit6e6a3fb7(mainaa95d35fplus the test) and atba2cbea0, twice each, alternatingHow to reproduce: check out each commit and run the command above
aa95d35f(with the test,6e6a3fb7)ba2cbea0In the game, two testers' Steam Deck OLED runs (RADV VANGOGH, SteamOS 3.9.5, 16 GB, the compute fallback), each against main without this PR:
e8faf57e(the same change, on main7ff5256e) against main7ff5256e, Mesa 26.2.0-devel, Game Mode, docked, stock clocks, at that Deck's own Auto defaults (1280x720 output, 50% render resolution, the game's own upscaler, frame generation off, VRAM budget 2.2 GB). Two 5-minute runs each, interleaved, through Kokiri Forest, Hyrule Field and Kokiri again, the same inputs every run. What the renderer holds besides textures (from thevk: VRAM:lines) was lower at all three spots: a median of 1,221 MB (1,151 to 1,289) with this PR against 1,298 MB (1,283 to 1,355) on main, about 80 MB less, about one of the 64 MB arenas this PR stops leaving (the lines do not name them). The raw "used" figures move in 64 to 128 MB steps and the textures differ by up to about 320 MB between runs, so they are noisy: the means were lower with the PR at each spot (Kokiri 4,341 against 4,469 MB, the Field 4,054 against 4,278, Kokiri again 4,278 against 4,598), and one PR run was above one main run in the first area. fps 20.3 and 20.7 with it, 19.9 and 20.2 on main: not lower. The arrival pictures match in all runs, nothing missing (flicker cannot be judged from stills). No crash, device loss or fault. That Deck ran short of memory in every run (about 4 GB swapped), so itsvk: memory:working set says little.9e6f231d, with and without this PR and #472 together (d4c9070b,e8faf57eand18243506cherry-picked), on top of other open PRs that tester plays with, the same in both; two starts a build, in both orders. The GPU memory the driver counts for the game (drm-memory-gtt+drm-memory-vramof its fdinfo) at the end of a 720-present span: 4,258 against 4,177 MiB (-81) and 4,356 against 4,161 MiB (-195); fps 33.41 / 30.82 without, 33.40 / 31.16 with. The build with the change gave the same figure on both starts (16 MiB apart), the one without moved by about 100 MiB between starts (4,349 on a third start), which fits one to three 64 MB record buffers made or not. No fatal line and no GPU timeout in the kernel log on the four starts. #472 makes no buffer, so the tester reads the memory difference as this PR's, but the two were not built apart.Flags and settings
None
Testing
Tested: Linux x86-64, game-free. The new test fails on the test-only commit
6e6a3fb7and passes atba2cbea0(this branch rebased ontomainaa95d35f), twice each, alternating, and undertests/run_all.pywith g++ 13.3 and with clang 23.1.5 at both commits. At the tip, the 109 checks that readgpu/vk/vk_draw.cppor the changed test: 106 passed, 1 skipped, and 2 failed that fail or are skipped by OS onmainaa95d35ftoo (test_pipeline_tour;test_shader_module_guard, a Windows-only check run here by name). Before the rebase the same atd4c9070bande8faf57e(main7ff5256e). Steam Deck: dukenheimer's T-YHDU run and p0lux's still-view run, in Measurements.Not tested: How many payload growths a session sees in this game, so how much memory it saves in general (64 MB of video memory for each growth, per recording thread). GPUs that use the fallback other than the Deck's, and Windows (where the fallback is not the default).
Must be tested: None
Risks
What could break: pairs that share a record buffer now use it from more than one program; that was already the design (one records area for every program, each draw clearing its slots behind a barrier). The pairs are never freed one by one, so no buffer is freed twice.
Turning it off: revert the commit
Compatibility: Nothing changes
Issues
None filed.
Checklist
Everyone
type(scope): description) of the status line's type.main. Onto mainaa95d35f, no conflict; the test and fix commits are the same changes as before (git patch-id).python -I -B tests/run_all.pypasses (any failure that also fails onmainis named). The full suite on mainaa95d35f(Linux, g++ 13.3, the Vulkan headers set): 528 passed, 15 failed, 50 skipped; on this branch the new test and the 109 checks that read the changed files ran, with no failure thatmaindoes not have (see Testing). The 15 that fail on main: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_mods_size_table,test_options_budget_once,test_pipeline_tour,test_readback_late,test_vk_pgo,test_walk_keyandnx2/test_texture_init_barrier.py.third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.mainand passing here.tests/that reads changed source updated in this PR, not weakened.gpu/vk/vk_draw.cppatba2cbea0checked whole (-fsyntax-only -Wall -Wextra, the build's defines) with clang 23.1.5 for Linux and llvm-mingw 20261104 for Windows: the same diagnostics asmainaa95d35f's (102 and 103), none new; on Linux both stop at the same narrowing error in a line this PR does not touch. Before the rebase, the combined branch 27553c83 linkedlongshot_vk.dll(llvm-mingw 20261104,RX_VK_ONLY=1 RX_RELEASE=1 RX_TARGET=windows) andlongshot_vk.so.Filled in: the full game-free suite on the combined branch, the Windows and Linux builds, and the test request T-YHDU. Still work in progress until a Steam Deck run is in.
Test request T-YHDU: pass
Built from this PR's head
e8faf57e(on main7ff5256e); the comparison is main7ff5256e. Setup and method below.Result
vk: VRAM:used, MB, at each area's last line"Held besides textures" is from the same line: used, minus the free space in its blocks, minus the textures.
VRAM. The raw "used" figures move in 64-128 MB block steps, and the textures (2.2 to 2.6 GB) differ by up to ~320 MB between
runs at the same spot, so the lines are noisy. At the same spots the means are lower with this PR:
In the first Kokiri area one run with the PR (4,405) is above one run of main (4,277) and below the other (4,661). What the renderer
holds besides textures is lower at all three spots: a median of 1,221 MB (1,151 to 1,289) with this PR against 1,298 MB (1,283 to
1,355) on main, about 80 MB less. That is about one of the 64 MB arenas this PR stops leaving, though these lines don't name them.
fps: 20.3 and 20.7 over the whole 5 minutes with this PR, 19.9 and 20.2 on main. Not lower.
Picture: the arrival pictures (Kokiri, the Field, Kokiri again) match across all six runs, the combined build's included. Nothing
is missing; they differ only in Navi's place and in when the area title or the "Saving..." icon showed. Flicker can't be judged from
stills, but nothing was missing in any.
Faults: none in the six runs (no crash, device lost or device fault, no stalled GPU). The kernel's amdgpu lines were only the
display's "Losing delta precision while programming shaper LUT" notices, 6 a start, in every run.
Memory: at these settings this Deck ran short of memory in every run, with about 4 GB swapped and MemAvailable down to 280-880 MB.
So the
vk: memory:working set below swings with swapping and says little.The last `vk: VRAM:` and `vk: memory:` lines of each run
Setup
kernel 7.2.7-valve2. Game Mode, docked, stock clocks.
7ff5256e; main + this PR alone (the renderer built from the PR's head); and a combined build of main + #550 to #558,merged in order, all clean. All built for x86-64-v3 with the release play profile and LLVM 23.1.5. One test folder (warm caches) with
the binaries swapped; the shader caches' stamp is the same for all three.
1280x720, Render resolution 50% (640x360), the game's own upscaler, frame generation off, VRAM budget 2.2 GB.
HyruleField_Child (the Lost Woods bridge), 110 s, the teleport back to KokiriForest_Child, 50 s.
off events that blocked the teleports.
arrival.
The arrival pictures, all six runs (Kokiri, the Field, Kokiri again):
Thank you for the Deck run, dukenheimer: your result is in the description as you reported it, including its limits. Marking this ready for review.
WIP: fix(vk): a mesh fallback program with bigger payloads reuses the record arenato fix(vk): a mesh fallback program with bigger payloads reuses the record arenaA second Steam Deck run, on a still view, where the driver's own count shows the saving.
Setup: Steam Deck OLED (RADV VANGOGH, SteamOS 3.9.5, 16 GB), the compute fallback, headless. A still heavy view (about 2,150 draws a frame) loaded from a save; memory read at the end of a 720-present span on the settled view. The two builds are the renderer alone, swapped in one game folder built from main
9e6f231d.drm-memory-gtt+drm-memory-vramof its fdinfo), pair 1The build with the change gives the same figure on both starts (16 MiB apart). The one without moves by about 100 MiB from one start to the next (4,258 and 4,356 here, 4,349 on a start this morning), which fits one to three 64 MB record buffers made or not, depending on the start. No fatal line and no GPU timeout in the kernel log on the four starts.
Limits: the two builds differ by this PR and #472 together (
d4c9070b,e8faf57eand18243506cherry-picked), on top of main9e6f231dplus the open PRs I play with (#223, #384, #387, #391, #567, #568, #590 and a local change), the same in both. #472 makes no buffer, so I read the memory difference as this PR's, but the two were not built apart. Two starts a build.Thank you, p0lux, for the still-view Deck run: it is in the description as you reported it (81 and 195 MiB less GPU memory, fps not lower, built together with #472, which makes no buffer), beside dukenheimer's T-YHDU run. Rebased onto
mainaa95d35fwith no conflict (the same two changes,git patch-id) and the description moved to the current template.The test was run again on the new base (two arenas at the test-only commit, one at the tip, two rounds, g++ and clang); both Deck runs still hold:
mainhas not changedfallback_buffers_of()since7ff5256e, and since p0lux's base9e6f231donly #761 (Arc cards' occlusion copy) and #742 (an agents skill) landed.e8faf57e94ba2cbea046View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.