perf(vk): the renderer's play profile covers the compute fallback, the overworld and the dungeons #599

Merged
HumanBean merged 1 commit from HumanBean/Longshot:perf/vk-profile-fallback into main 2026-11-14 23:01:48 +00:00
Owner

Why

The renderer's committed play profile came from one 3090 session in Kokiri Forest and the Market, so GPUs without mesh shaders (whose frames go through the compute fallback) and most areas got no counts. This adds two recordings from an RX 580 across 28 of the 31 teleport destinations. Follows #569; part of #505's "ship play profiles".

How to reproduce

The recordings, on Linux with a base of main (scripts/dev_packs.py base):

  1. A counting renderer: OOT_WORK=<empty folder> RX_RELEASE=1 RX_VK_ONLY=1 RX_VK_PGO=gen python -I nx2/build.py --standalone, its sa/build/longshot_vk.so copied over a runtime's (dev_packs.py pack with RX_VK_PGO=gen builds nothing when the tree is the base's: a pack is only rebuilt for changed files).
  2. The game with RX_VK_PGO_FILE=<file>, <file>.reset once Link is controllable, then the Insert menu's Debug teleport to each destination (live input !cheat 1000+index), a few seconds standing, the camera turned, a short run; <file>.dump at the end.
  3. llvm-profdata merge -o merged.profdata <the committed profile, unpacked> <recordings> and xz -9e.

What changed

  • assets: assets/profiles/longshot_vk.profdata.xz replaced by the merge of the committed profile and two new recordings (166 KB). 1,744 renderer functions ran in at least one recording (1,660 before); 76 of them never ran in the old profile, among them the compute fallback's draw path (fallback_record, fallback_buffers, fallback_task_groups, fallback_pipelines_ready in gpu/vk/vk_draw.cpp).
  • assets: assets/profiles/README.md: the three recordings (GPU, driver, build, route, what didn't teleport), and that the merged profile is not measured yet.

No code changes: every renderer build already compiles with this file (#569); a new profile recompiles the renderer's own 35 files once.

Measurements

Not measured: the profile's effect was measured for the first recording alone (-4 to -5 % frame time standing, -3 % running in the Market on an RTX 3090, assets/profiles/README.md). This change adds counts for code the old profile never saw (mainly the compute fallback) and leaves the mesh-shader path's counts in place; on the lab RX 580 the frame time varies by more between sessions (±2 ms) than this could move. A before/after on a GPU without mesh shaders that isn't GPU-bound would settle it.

What the lab's build of main shows: the build compiles the renderer with the committed profile (the Vulkan back end: built with the profile .../work/longshot_vk.shipped.profdata) and LLVM 23.1.5 reads it.

Flags and settings

None.

Testing

Tested: the merge with llvm-profdata 23.1.5 (show reads the result: 4,739 functions, 1,744 with counts). The recordings: RX 580, RADV POLARIS10, Linux, i7-9700K, child Link: 16 overworld destinations (532 s; Hyrule Castle and Gerudo Fortress, adult only, didn't teleport) and 12 dungeon destinations plus Desert Colossus (265 s; the Spirit Temple didn't teleport). No local checks run (tests/run_all.py); no build with the new file yet.

Not tested: a build of this PR (the file is the same format and LLVM as the one the lab's build of main read); Windows (llvm-mingw reading it: the file before this one is the same format); any frame-time effect.

Must be tested: a frame-time A/B on a GPU without mesh shaders (old profile against this one); a Windows build reading it (the build log names the profile, or says it couldn't read it and builds without).

Risks

A profile changes how the renderer's code is laid out and inlined, never what it does: the worst case is a little slower, not wrong. Code the new recordings ran more often gets favoured; the 3090's mesh-shader counts stay in the merge. A compiler that can't read the file builds without it. Reverting the commit restores the old profile.

Issues

See #505

Checklist

Everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description) of the status line's type.
  • Why gives the reason plainly and links the issues that fit (the tracker searched).
  • Measurements has a verdict, or one line saying why there is nothing to measure.
  • Testing names what was tested, what wasn't, and what must still be tested, where and how.
  • Rebased on current main.
  • python -I -B tests/run_all.py passes (any failure that also fails on main is named). (not run here: left to CI)
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

When it applies

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • Docs updated.

🤖 Generated with Claude Code

## Why The renderer's committed play profile came from one 3090 session in Kokiri Forest and the Market, so GPUs without mesh shaders (whose frames go through the compute fallback) and most areas got no counts. This adds two recordings from an RX 580 across 28 of the 31 teleport destinations. Follows https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/569; part of https://git.magicbean.dev/MagicBeanDev/Longshot/issues/505's "ship play profiles". ## How to reproduce The recordings, on Linux with a base of main (`scripts/dev_packs.py base`): 1. A counting renderer: `OOT_WORK=<empty folder> RX_RELEASE=1 RX_VK_ONLY=1 RX_VK_PGO=gen python -I nx2/build.py --standalone`, its `sa/build/longshot_vk.so` copied over a runtime's (`dev_packs.py pack` with `RX_VK_PGO=gen` builds nothing when the tree is the base's: a pack is only rebuilt for changed files). 2. The game with `RX_VK_PGO_FILE=<file>`, `<file>.reset` once Link is controllable, then the Insert menu's Debug teleport to each destination (live input `!cheat 1000+index`), a few seconds standing, the camera turned, a short run; `<file>.dump` at the end. 3. `llvm-profdata merge -o merged.profdata <the committed profile, unpacked> <recordings>` and `xz -9e`. ## What changed - assets: `assets/profiles/longshot_vk.profdata.xz` replaced by the merge of the committed profile and two new recordings (166 KB). 1,744 renderer functions ran in at least one recording (1,660 before); 76 of them never ran in the old profile, among them the compute fallback's draw path (`fallback_record`, `fallback_buffers`, `fallback_task_groups`, `fallback_pipelines_ready` in `gpu/vk/vk_draw.cpp`). - assets: `assets/profiles/README.md`: the three recordings (GPU, driver, build, route, what didn't teleport), and that the merged profile is not measured yet. No code changes: every renderer build already compiles with this file (https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/569); a new profile recompiles the renderer's own 35 files once. ## Measurements Not measured: the profile's effect was measured for the first recording alone (-4 to -5 % frame time standing, -3 % running in the Market on an RTX 3090, `assets/profiles/README.md`). This change adds counts for code the old profile never saw (mainly the compute fallback) and leaves the mesh-shader path's counts in place; on the lab RX 580 the frame time varies by more between sessions (±2 ms) than this could move. A before/after on a GPU without mesh shaders that isn't GPU-bound would settle it. What the lab's build of main shows: the build compiles the renderer with the committed profile (`the Vulkan back end: built with the profile .../work/longshot_vk.shipped.profdata`) and LLVM 23.1.5 reads it. ### Flags and settings None. ## Testing **Tested:** the merge with `llvm-profdata` 23.1.5 (`show` reads the result: 4,739 functions, 1,744 with counts). The recordings: RX 580, RADV POLARIS10, Linux, i7-9700K, child Link: 16 overworld destinations (532 s; Hyrule Castle and Gerudo Fortress, adult only, didn't teleport) and 12 dungeon destinations plus Desert Colossus (265 s; the Spirit Temple didn't teleport). No local checks run (`tests/run_all.py`); no build with the new file yet. **Not tested:** a build of this PR (the file is the same format and LLVM as the one the lab's build of main read); Windows (llvm-mingw reading it: the file before this one is the same format); any frame-time effect. **Must be tested:** a frame-time A/B on a GPU without mesh shaders (old profile against this one); a Windows build reading it (the build log names the profile, or says it couldn't read it and builds without). ## Risks A profile changes how the renderer's code is laid out and inlined, never what it does: the worst case is a little slower, not wrong. Code the new recordings ran more often gets favoured; the 3090's mesh-shader counts stay in the merge. A compiler that can't read the file builds without it. Reverting the commit restores the old profile. ## Issues See https://git.magicbean.dev/MagicBeanDev/Longshot/issues/505 ## Checklist ### Everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`) of the status line's type. - [x] Why gives the reason plainly and links the issues that fit (the tracker searched). - [x] Measurements has a verdict, or one line saying why there is nothing to measure. - [x] Testing names what was tested, what wasn't, and what must still be tested, where and how. - [x] Rebased on current `main`. - [ ] `python -I -B tests/run_all.py` passes (any failure that also fails on `main` is named). (not run here: left to CI) - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### When it applies - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] Docs updated. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
perf(vk): the renderer's play profile covers the compute fallback, the overworld and the dungeons
Some checks failed
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 5s
Third-party parts / As their notes say (pull_request) Successful in 8s
PR description / Description follows the template (pull_request_target) Failing after 15s
278dee03f0
The committed renderer profile (assets/profiles/longshot_vk.profdata.xz) was one session on an RTX 3090,
Kokiri Forest and the Market only: GPUs without mesh shaders, whose frames go through the compute fallback,
got no counts for that path. Two recordings on an RX 580 (RADV, the compute fallback), child Link through 28
of the debug teleport's 31 destinations, are merged into it with llvm-profdata (LLVM 23.1.5): 1,744 functions
ran in at least one recording, 76 of them never in the first, among them the fallback's draw path. The note
in assets/profiles/README.md says what each recording covered.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
HumanBean changed title from WIP: perf(vk): the renderer's play profile covers the compute fallback, the overworld and the dungeons to perf(vk): the renderer's play profile covers the compute fallback, the overworld and the dungeons 2026-11-14 23:01:42 +00:00
HumanBean deleted branch perf/vk-profile-fallback 2026-11-14 23:01:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Longshot!599
No description provided.