Repository navigation
perf(vk): with batched submits (RADV), send a batch at once while the GPU is idle (#1993) - #1999
Conversation
… GPU is idle (#1993) The held batch waited for the next wait or present while the GPU had finished everything sent, so it sat idle until the game waited for it (serial replay's mid-frame late-page wait above all). Proposed and measured by mrdev023 in #1993: RX 9070 XT, RADV, Kokiri Forest, 33-41 fps -> 46-61, no flashes; batching still groups submits while the GPU is busy. RX_VK_BATCH_IDLE=0 keeps the old hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Tested this branch as is (
Same gain as in #1993, no flashes. |
…e tests' fixtures stub both) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A/B on Windows (RTX 4060 Ti, batching forced on with
With the batch held, the GPU sits idle and loses ~12 fps here, matching what #1993 measured on RADV. The idle flush brings batching back to the unbatched frame rate, and Windows' default (batching off) is unchanged. 🤖 Generated with Claude Code |
…ggle stub lacks switching; actionlint SC2012) (#2092) Main has been red since #2046 and the builder track switch landed: - **tests/test_pipeline_state_portable.py** (Windows): the fixture compiles with \`-Werror\` and clang on Windows marks \`fopen\` deprecated. It now passes \`-D_CRT_SECURE_NO_WARNINGS\`, as the other fixture tests do. - **tests/test_make_game_ngx.py** (all OSes): \`Builder.apply_mode\` now calls \`self.switching()\`, and the test's stub had none. It gets \`switching=lambda: False\`. - **.github/workflows/linux-appimage.yml** (actionlint, from #2079): the object count used `ls | wc -l` (shellcheck SC2012). It counts with a glob array, as the loop above it already does. Checked locally: both pass (fixture built with clang++ and Vulkan headers 1.4.345; test_make_game_ngx 17 tests OK). Unblocks #1999 and the other open PRs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…c fixture getenv deprecation) (#2109) Main is red again. [#1866](#1866) added this to the finish block of `make_game.main()`: ```python if fsr_wanted(a, out) and getattr(a, "fetch_fsr_runtime", False): ``` `tests/test_finish_output.py` and `tests/test_linux_update.py` (`test_a_packaged_build_puts_the_launcher_in_the_folder_and_the_game_in_bin`) run that block on its own, without `a`, so both fail with `NameError: name 'a' is not defined`. Both tests now pass an argument namespace with FSR off (`fsr=False, no_fsr=False, update=None, fetch_fsr_runtime=False`). The production code is unchanged. Checked locally: test_finish_output passes. The test_linux_update case only runs on Linux; CI covers it. Locally on Windows that file has unrelated symlink failures that are the same before and after this change. This unblocks #1999 and the other open PRs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Those came from my first write-up in #1993, and they were my misreading. The log line
I don't think it is, after profiling it today (
So on this box the frame is the CPU replay plus the mid-frame wait, and the GPU mostly waits for work. That also explains why |
… by default The idle send (NotRexed#1999) costs a Steam Deck LCD (Van Gogh, RADV) ~5 ms of queue submit a frame in Kokiri Forest on current main (11-12 ms with it, 6.6-7.1 without; 18.6-18.8 fps -> 20.0-20.7), where each vkQueueSubmit costs ~1 ms. The rule is limited to Van Gogh by device ID (0x163f LCD, 0x1435 OLED); every other GPU, other APUs included (780M, 890M, 8060S, unmeasured), keeps it. RX_VK_BATCH_IDLE=1 or 0 still chooses, and the log says which. Assisted-by: Claude Opus 5.5 (Anthropic) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implements #1993's proposal by @mrdev023, as a default where batching is on.
With batched submits (on by default with RADV, so Linux AMD including the Steam Deck;
RX_VK_BATCH=1elsewhere), a held batch waited for the next wait, present or the 32-buffer cap. That happened even when the GPU had finished everything it was sent. So the GPU sat idle until the game waited for it, and with serial replay that's mid-frame, attake_capture's late-page wait.Now, when a submit joins the batch and the GPU has completed every batch sent so far (
batch_tl>=batch_flushed), the batch goes out at once. While the GPU is busy, submits are still grouped.The reporter's numbers (RX 9070 XT, RADV, Kokiri Forest, FSR 4, 5120x1440):
Flushes went from about 5.7 a frame to about 10 of 3.7 command buffers each, and the late-page wait from about 1.4 to 0.64 ms.
RX_VK_BATCH_IDLE=0keeps the old behaviour.Not yet checked here: I have no RADV machine. I'll A/B it on Windows with
RX_VK_BATCH=1(NVIDIA) for fps and flashes before merging. Drivers other than RADV are unchanged, since batching stays off there by default.🤖 Generated with Claude Code