feat(log): the recording streams' line counts the descriptor pools made when a recording's own ran out #387
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
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/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!387
Loading…
Reference in a new issue
No description provided.
Delete branch "p0lux/Longshot:feat/desc-pool-count"
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?
Why
A recording's descriptor pool is 8192 sets of up to 32768 descriptors a type, 24 or 48 of them at once, and the driver keeps memory for all of it: on a Steam Deck a quarter of that (
RX_VK_DESC_POOL_DIV=4, an existing switch) gives back about 130 MB of GPU memory. Whether a smaller default is safe depends on how often a recording then runs out of its pool, and nothing said. This adds that count to a log line. Its first values: a half never runs out in three scenes, a quarter does once or twice in Kokiri Forest, an eighth and a sixteenth hundreds of times.What changed
pools_extraingpu/vk/vk_draw.cpp, counted inbind_descriptors()where a pool made because the recording's own ran out is kept (cur->extra), and written at the end of the "recording streams" line thatdraw_begin_recording()logs every 3,000 recordings.make_pool()'s comment says where to read it.RX_VK_DESC_POOL_DIVindocs/development.md's switch reference (it was not there), with the line that counts; two run files indocs/tested/.tests/recording_admission_test.cppchecks a kept extra pool is counted and one that could not be kept is not; it,tests/sampler_admission_test.cpp,tests/draw_stream_visibility_test.cppandtests/fsr_uniform_ownership_test.cppdeclare the counter, since they cut this code out of the source.Flags and settings
None new or changed.
RX_VK_DESC_POOL_DIV=<1..32>(existing, unset by default: the full size) is what the count is for; it is now in the switch reference.Measurements
main:
514591a3(2026-11-13)this PR: feat/desc-pool-count @ d4b89309 (this PR's code commit,
a593baaa, on that main; on the fork asmeasured/desc-pool-count-d4b89309). The branch itself is on main0caf0618: its code is the same change (git range-diffshows only the neighbouring rows ofdocs/development.mddiffering). Between the two mains the pools' code changed in one place, which does not change how many a recording makes: their reset at a recording's start is now inside a recorder scope (rec::OwnSlot, forRX_VK_RECORDER_OWN). So these numbers still hold. It was measured on514591a3because the game folder on the Deck is a build of an earlier main, in which 514591a3's back end is known to run; main'svk_api.hhas changed since (#136, #137).Hardware: Steam Deck OLED (AMD Custom APU 0932, RADV VANGOGH, Mesa 26.2.0-devel), 16 GB shared with the GPU, SteamOS 3.9.5, kernel 7.2.7-valve2; the GPU's clock fixed at 1600 MHz
Scene: three saves, standing still: a heavy view (about 2,100 draws a frame), Kokiri Forest (about 2,550), Hyrule Field (about 1,600); no screen (headless), handheld profile, Minimum preset, the game's own upscaler, no frame generation, no cap
Method: the back end built alone from each commit (clang, same flags), swapped in one game folder. Each run starts the game, loads the save by script, waits 3 log windows (the first 360 presents in game), then measures 720 presents: fps by the clock, the log's replay time, and the render thread's user-space cycles and instructions a frame (
perf stat -t). Main then this PR, alternated: 3 runs each on the heavy view, 2 in Kokiri Forest. Then this PR's renderer alone withRX_VK_DESC_POOL_DIVunset, 2, 4, 8 and 16: the count is the last "recording streams" line of the run's log (so since the start of the run), memory is read at the end of the measured span from/proc/<pid>/fdinfo(drm-memory-gtt) and/proc/meminfo, KiB divided by 1,024How to reproduce:
RX_VK_DESC_POOL_DIV=8inlongshot_env.txt, a save in Kokiri Forest, and after a minutegrep "recording streams" longshot_log.txtThe count costs nothing (medians; each run in brackets, in the order run):
514591a3Kokiri Forest's work a frame varies from run to run by more than the two renderers differ: this PR's renderer alone ran 83.17 to 88.10 M instructions a frame over its eight runs there, and the lowest was the run that made 1,044 pools. At the full size the counted path is not taken (0 below), so the change is nine more words in a line logged every 3,000 recordings.
What the count says, this PR's renderer, one run a cell unless two or three values are given:
RX_VK_DESC_POOL_DIV=2RX_VK_DESC_POOL_DIV=4RX_VK_DESC_POOL_DIV=8RX_VK_DESC_POOL_DIV=16drm-memory-gtt, MiB), heavy viewMemAvailable(MiB, the whole system's), heavy viewMemAvailable, Kokiri ForestMemAvailable, Hyrule FieldRead with care: the memory of single runs is not a ranking. The full size's own three runs on the heavy view differ by 254 MiB of GPU memory. Every smaller size is under the full size's median in every scene, and in Kokiri Forest an eighth and a sixteenth give back no more than a quarter, since the pools they make on demand take memory too. Making 700 to 1,000 pools in a run cost no fps on this driver; what it costs on others is not measured.
The memory a smaller pool gives back was measured with rounds the evening before, on a build without this change (main
fbd42024with other renderer-only changes, 22ed63d6), the switch alone, 4 rounds alternated on the heavy view, medians:RX_VK_DESC_POOL_DIV=4RX_VK_DESC_POOL_DIV=16drm-memory-gtt)RssAnonMemAvailableTesting
Tested:
python -I -B tests/run_all.pyon macOS with the Vulkan headers given: 486 passed, 36 failed, 39 skipped; the 36 fail the same way on main0caf0618on that machine (no/proc, noposix_fallocate, an older Python, the Linux launch scripts and the like).test_recording_admission.py,test_sampler_admission.py,test_draw_stream_visibility.pyandtest_fsr_uniform_ownership.py, whose fixtures changed, pass.e0eb2244) and from the commit on main514591a3(clang, on the Deck): 0 failed.4e2cd9f7; the head adds a docs file to it), cross-built with llvm-mingw 20261104 on Linux: 0 failed,longshot_vk.dllmade. Not run.Not tested:
Needs other testers:
None: the count comes from the game's draws, not from the hardware.
Screenshots
Nothing on screen.
Risk and rollback
One relaxed atomic increment where an extra pool is kept, which the default size does not reach in these scenes, and nine more words in a line logged every 3,000 recordings. Reverting the commit removes both.
Reviewer notes
HANDLE_TABLE_SIZE, #107), which is probably what fills an eighth's 4,096 samplers in Kokiri Forest.Issues
None.
Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
Assisted-by:/Co-Authored-By:trailers.docs/tested/for each new measured run (format indocs/tested-configurations.md; no appended row or assembled view).tests/that reads changed source updated in this PR, not weakened.Measured on the Deck (head
e0eb2244; description updated):514591a3and the commit on it, alternated, 3 runs each on the heavy view, 2 in Kokiri Forest): the same. Heavy view 23.99 against 24.05 fps, 62.68 against 62.56 M instructions a frame on the render thread. Kokiri Forest's own run-to-run spread is larger than the two renderers' difference there (the description says how much).docs/tested/. The measured commit is on the fork asmeasured/desc-pool-count-d4b89309.WIP: feat(log): the recording streams' line counts the descriptor pools made when a recording's own ran outto feat(log): the recording streams' line counts the descriptor pools made when a recording's own ran outView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.