fix(vk): the start-up bar counts the compute pipelines, not 100% through them #256

Open
gab9281 wants to merge 2 commits from gab9281/Longshot:fix/startup-bar-compute into main
Member

Why

On the first start after a shader preparation, the start-up screen sits at "100%, a few seconds left" for about 5 minutes (RTX 3060 Laptop), which looks like being stuck on the last shader. The bar counted only the noted pipelines, then stayed full while every compute program's pipeline was built.

What changed

  • vk: precompile_warm() in gpu/vk/vk_draw.cpp lists the compute programs' keys (program_cache_compute_keys()) before it starts. Both steps count on one total, the noted pipelines and then the compute pipelines, so the bar moves through the compute step instead of sitting at 100%. The work done is the same: only the count given to the bar changes.
  • tests: tests/test_warm_bounded.py checks that the compute step reports its own progress against the whole. It fails on main, where it reports progress(total, total).

Flags and settings

None.

Measurements

What changes is the number the start-up screen shows, not the time: the same pipelines are built in the same order. So the measurement is the bar's value at the start of the compute step, from the start-up log line, with the shaders' time on this PR for reference.

main: 36a12f6f (2026-11-13; precompile_warm's bar code is the same on main @ 514591a3, which this PR is on: main's renderer changes since, #234 and #260, are elsewhere in vk_draw.cpp)
this PR: fix/startup-bar-compute @ 2af5f18e (measured there; 82271725, the head now, changes only the count after a stopped noted step, which this start didn't have)
Hardware: RTX 3060 Laptop (NVIDIA 620.70.06), Ryzen 7 6800H, 15 GB, CachyOS (Linux 7.3.3), KDE Wayland
Scene: the start-up screen of the first start after a preparation (RX_VK_LOAD=create), default settings
Method: the start-up screen's vk: start-up: pipelines … of … log line once the noted pipelines are done, one start each, started through game-performance
How to reproduce: prepare the shaders (a build with --prepare-shaders), start the game, and watch the start-up screen and longshot_log.txt

main @ 36a12f6f this PR @ 2af5f18e
The bar when the compute step starts 24457 of 24457, 100%, "a few seconds left" 27918 of 29473, 95%
The bar through the compute step stays at 100% (about 5 min with nothing cached) counts up to 100%
main:    [hos host] vk: start-up: pipelines 24457 of 24457, 100% of all, a few seconds left
this PR: [hos host] vk: start-up: pipelines 27918 of 29473, 95% of all, a few seconds left
this PR: [hos host] vk: precompile: 25346 noted pipelines of 16072 programs and 9925 compute pipelines of 4127 compute programs built into the pipeline cache and let go
this PR: [hos host] vk: start-up: the shaders took 11.3 s

29473 = 25346 noted + 4127 compute programs. The two starts had different numbers of noted pipelines (main's folder was prepared at another commit), and this start had the compute pipelines cached (11.3 s), so the times aren't compared. A run-to-run timing table wouldn't show anything: no pipeline is added or removed.

Testing

Tested:

  • In the game, Linux (the hardware above): built at 2af5f18e (the same bar code at 82271725, rebased on main @ 514591a3 with no conflict), a first start after a preparation. The start-up screen counted through the compute step to the end, with the log lines above.
  • Game-free: python -I -B tests/test_warm_bounded.py passes, and fails on main. RX_CPM=<the CPM cache> python -I -B tests/run_all.py at 82271725 (main @ 514591a3): 517 passed, 1 failed, 15 skipped (Windows only). The failure, tests/test_menu_i18n.py (a pt_BR text of a menu line main changed), fails on main 514591a3 too.

Not tested:

  • Windows: the code is the same (precompile_warm isn't platform-specific). The game builds for Windows with llvm-mingw at 2c2100d1 (4:38, the same code on the main before); not run on Windows.
  • A start with nothing cached on this PR, where the compute step takes minutes: this PC had them cached by then. The count is the same either way.

Needs other testers:
None (this is the bar's count, the same on every GPU).

Screenshots

Nothing new on screen: the same start-up screen, with a percentage that keeps moving.

Risk and rollback

The progress callback gets a larger total. If the compute step is skipped (the preparation was stopped), the bar ends below 100%, as any stopped preparation does. Reverting the commit is enough.

Reviewer notes

The compute keys were already listed, after the noted pipelines; this lists them once, before.

A /code-review (high) found 7 things:

  • Fixed (2c2100d1):
    • after a noted step stopped part-way, the compute step's only tick said every noted pipeline was done (total + computes_done); it now reports done + computes_done;
    • the compute keys are indexed, not copied into a second list;
    • the test pins the expression and that no tick reports total.
  • Left as is, on purpose:
    • A compute pipeline costs more than a noted one, but both count as one. That is how the normal precompile (precompile_run) already counts its notes, computes and fallbacks on one total. The time left comes from the bar's rate over the last 15 s (ProgressClock), so it slows down with the step instead of saying "a few seconds" for minutes. A weight per kind would change both paths and is a follow-up.
    • Part 2's guess (prepare_guess) counts the computes play dispatched, not every kept one. The normal precompile has the same gap on a first start (computes_plan's "every kept one"). The bar never goes back, so at worst it holds still for a moment when the count replaces the guess. Same follow-up.
    • The total counts keys the worker skips (failed, TAAU). They are counted done as they are skipped, so the bar still reaches the end. The log's "built" line counts what was built.
    • The keys are listed before the noted step, even on a start that is stopped during it. This is one walk of the index under its lock, needed for the total from the start.

Issues

None: found while testing #206 (the start-up screen "stuck on the last shader").

Checklist

For everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description).
  • Rebased on current main.
  • python -I -B tests/run_all.py run and passing (any failure that also fails on main is named above).
  • Tested in the game, or what wasn't is named under Testing.
  • Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests).
  • Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (The bar's count, which doesn't vary between runs: see Measurements.)
  • 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.

If applicable

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • A game-free test added for the fix, failing on main and passing here.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
  • Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths.

🤖 Generated with Claude Code

https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi

## Why On the first start after a shader preparation, the start-up screen sits at "100%, a few seconds left" for about 5 minutes (RTX 3060 Laptop), which looks like being stuck on the last shader. The bar counted only the noted pipelines, then stayed full while every compute program's pipeline was built. ## What changed - vk: `precompile_warm()` in `gpu/vk/vk_draw.cpp` lists the compute programs' keys (`program_cache_compute_keys()`) before it starts. Both steps count on one total, the noted pipelines and then the compute pipelines, so the bar moves through the compute step instead of sitting at 100%. The work done is the same: only the count given to the bar changes. - tests: `tests/test_warm_bounded.py` checks that the compute step reports its own progress against the whole. It fails on main, where it reports `progress(total, total)`. ## Flags and settings None. ## Measurements What changes is the number the start-up screen shows, not the time: the same pipelines are built in the same order. So the measurement is the bar's value at the start of the compute step, from the start-up log line, with the shaders' time on this PR for reference. main: 36a12f6f (2026-11-13; `precompile_warm`'s bar code is the same on main @ 514591a3, which this PR is on: main's renderer changes since, #234 and #260, are elsewhere in `vk_draw.cpp`) this PR: fix/startup-bar-compute @ 2af5f18e (measured there; 82271725, the head now, changes only the count after a stopped noted step, which this start didn't have) Hardware: RTX 3060 Laptop (NVIDIA 620.70.06), Ryzen 7 6800H, 15 GB, CachyOS (Linux 7.3.3), KDE Wayland Scene: the start-up screen of the first start after a preparation (`RX_VK_LOAD=create`), default settings Method: the start-up screen's `vk: start-up: pipelines … of …` log line once the noted pipelines are done, one start each, started through `game-performance` How to reproduce: prepare the shaders (a build with `--prepare-shaders`), start the game, and watch the start-up screen and `longshot_log.txt` | | main @ 36a12f6f | this PR @ 2af5f18e | |---|---|---| | The bar when the compute step starts | 24457 of 24457, 100%, "a few seconds left" | 27918 of 29473, 95% | | The bar through the compute step | stays at 100% (about 5 min with nothing cached) | counts up to 100% | ``` main: [hos host] vk: start-up: pipelines 24457 of 24457, 100% of all, a few seconds left this PR: [hos host] vk: start-up: pipelines 27918 of 29473, 95% of all, a few seconds left this PR: [hos host] vk: precompile: 25346 noted pipelines of 16072 programs and 9925 compute pipelines of 4127 compute programs built into the pipeline cache and let go this PR: [hos host] vk: start-up: the shaders took 11.3 s ``` 29473 = 25346 noted + 4127 compute programs. The two starts had different numbers of noted pipelines (main's folder was prepared at another commit), and this start had the compute pipelines cached (11.3 s), so the times aren't compared. A run-to-run timing table wouldn't show anything: no pipeline is added or removed. ## Testing **Tested:** - In the game, Linux (the hardware above): built at 2af5f18e (the same bar code at 82271725, rebased on main @ 514591a3 with no conflict), a first start after a preparation. The start-up screen counted through the compute step to the end, with the log lines above. - Game-free: `python -I -B tests/test_warm_bounded.py` passes, and fails on main. `RX_CPM=<the CPM cache> python -I -B tests/run_all.py` at 82271725 (main @ 514591a3): 517 passed, 1 failed, 15 skipped (Windows only). The failure, `tests/test_menu_i18n.py` (a pt_BR text of a menu line main changed), fails on main 514591a3 too. **Not tested:** - Windows: the code is the same (`precompile_warm` isn't platform-specific). The game builds for Windows with llvm-mingw at 2c2100d1 (4:38, the same code on the main before); not run on Windows. - A start with nothing cached on this PR, where the compute step takes minutes: this PC had them cached by then. The count is the same either way. **Needs other testers:** None (this is the bar's count, the same on every GPU). ## Screenshots Nothing new on screen: the same start-up screen, with a percentage that keeps moving. ## Risk and rollback The progress callback gets a larger total. If the compute step is skipped (the preparation was stopped), the bar ends below 100%, as any stopped preparation does. Reverting the commit is enough. ## Reviewer notes The compute keys were already listed, after the noted pipelines; this lists them once, before. A `/code-review` (high) found 7 things: - **Fixed** (2c2100d1): - after a noted step stopped part-way, the compute step's only tick said every noted pipeline was done (`total + computes_done`); it now reports `done + computes_done`; - the compute keys are indexed, not copied into a second list; - the test pins the expression and that no tick reports `total`. - **Left as is, on purpose:** - *A compute pipeline costs more than a noted one, but both count as one.* That is how the normal precompile (`precompile_run`) already counts its notes, computes and fallbacks on one total. The time left comes from the bar's rate over the last 15 s (`ProgressClock`), so it slows down with the step instead of saying "a few seconds" for minutes. A weight per kind would change both paths and is a follow-up. - *Part 2's guess (`prepare_guess`) counts the computes play dispatched, not every kept one.* The normal precompile has the same gap on a first start (`computes_plan`'s "every kept one"). The bar never goes back, so at worst it holds still for a moment when the count replaces the guess. Same follow-up. - *The total counts keys the worker skips (failed, TAAU).* They are counted done as they are skipped, so the bar still reaches the end. The log's "built" line counts what was built. - *The keys are listed before the noted step, even on a start that is stopped during it.* This is one walk of the index under its lock, needed for the total from the start. ## Issues None: found while testing #206 (the start-up screen "stuck on the last shader"). ## Checklist ### For everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`). - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` run and passing (any failure that also fails on `main` is named above). - [x] Tested in the game, or what wasn't is named under Testing. - [x] Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). - [x] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (The bar's count, which doesn't vary between runs: see Measurements.) - [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. ### If applicable - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened. - [x] Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
fix(vk): the start-up bar counts the compute pipelines, not 100% through them
All checks were successful
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
PR description / Description follows the template (pull_request_target) Successful in 4s
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 6s
Third-party parts / As their notes say (pull_request) Successful in 8s
bf4228a9f2
The first start after a preparation (RX_VK_LOAD=create, precompile_warm)
builds the noted pipelines into the pipeline cache, then every compute
program's pipeline. The second step reported progress(total, total), so
the start-up screen sat at "pipelines N of N, 100%, a few seconds left"
through it: about 5 minutes for 4127 compute programs on an RTX 3060
Laptop, which looked like being stuck on the last shader. The compute
programs' keys are now listed before the noted pipelines (a walk of the
program cache's index), and both steps count on one total.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
fix(vk): the bar's count after a stopped noted step, and no copy of the compute keys
All checks were successful
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 5s
CI / Workflow lint (actionlint) (pull_request) Successful in 7s
Third-party parts / As their notes say (pull_request) Successful in 11s
PR description / Description follows the template (pull_request_target) Successful in 3s
2c2100d102
The review's findings: the compute step's tick said total + its own, so a
noted step stopped part-way (no compute step) told the bar every noted
pipeline was done. It says done + its own now. The compute keys are walked
once and indexed, not copied into a second list. The test pins the
expression and that no tick says total.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
gab9281 changed title from WIP: fix(vk): the start-up bar counts the compute pipelines, not 100% through them to fix(vk): the start-up bar counts the compute pipelines, not 100% through them 2026-11-13 18:05:07 +00:00
gab9281 force-pushed fix/startup-bar-compute from 2c2100d102
All checks were successful
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 5s
CI / Workflow lint (actionlint) (pull_request) Successful in 7s
Third-party parts / As their notes say (pull_request) Successful in 11s
PR description / Description follows the template (pull_request_target) Successful in 3s
to 8227172508
All checks were successful
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
Website / Website on Cloudflare (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 8s
Third-party parts / As their notes say (pull_request) Successful in 11s
PR description / Description follows the template (pull_request_target) Successful in 5s
2026-11-13 19:36:53 +00:00
Compare
All checks were successful
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
Website / Website on Cloudflare (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 8s
Third-party parts / As their notes say (pull_request) Successful in 11s
PR description / Description follows the template (pull_request_target) Successful in 5s
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'fix/startup-bar-compute:gab9281-fix/startup-bar-compute'
git switch 'gab9281-fix/startup-bar-compute'
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!256
No description provided.