WIP: chore(restore): Hookshot's tools, checks, docs and tested-configuration rows merged after Longshot branched #284

Draft
TrashPanda wants to merge 20 commits from TrashPanda/Longshot:restore/tools-checks-docs into main
Contributor

Why

Longshot lost the tools, checks, docs and tested-configuration rows Hookshot merged after Longshot branched. This brings
back the ones that do not touch the game, so they can merge on game-free checks alone. Split out of #209.

What changed

Split out of #209 as its reviewer asked (review on #209, point 4, group a). Each commit is the merged Hookshot pull request under its original author, carried through Longshot's rename; a Restored-from: trailer names it, and the bare Hookshot numbers in the messages and the restored text are now full URLs.

Credit to the authors of the restored work: jarynclouatre, jabbaxipil, Mooki, Jiro131, nullifyshot, Mark Roberts, Wagner Junior, Waryxxful, VineeSouzaa, Dukenheimer, Jordan Ella, RoblesLeo.

  • tests: tests/srccut.py, one source cutter, with 80 checks moved to it (a missing or repeated marker now fails);
    run_all.py --changed runs the checks that read what changed; the startup pool placement and fallback checks now
    execute
  • ci: .forgejo/workflows/ci.yml runs the authored Vulkan fixtures on lavapipe, started by hand like the other full checks
  • scripts: hookshot_bench.py, a repeatable benchmark route through the control bridge; a mistyped date in a claim no
    longer stops the test-request replay (scripts/test_requests.py)
  • release: the RTX 5090 fork list's note says what its build changed
  • docs: the README's work/ffx-sdk had a form feed in place of /f; 11 tested-configuration rows; RX_VK_IMAGE_PREALLOC
    and RX_VK_TEST_ALLOWED_MB documented

Split siblings: test-request pinning #285, rc.4 player fixes #286, renderer fixes #287, new defaults and speed-ups #288.

Commits, in order:

  • 9e566b8c fix(agents): a mistyped date in a claim does not stop the test request replay (Hookshot 2949, by jarynclouatre)
  • cc5adb88 docs: tested configurations: RX 7900 XTX, RADV Mesa 26.2.6, Ubuntu 24.04 GNOME X11 (v2.1.0) (Hookshot 2616, by jabbaxipil)
  • 415f8a5c docs(tested): record paired Linux RTX 4090 rolling results (Hookshot 2778, by Mooki)
  • 3dbeb31d docs: add tested-configurations rows for DLSS Frame Generation on an RTX 4090 (Windows) (Hookshot 2771, by Jiro131)
  • fad3f216 docs(tested): RTX 5080 on Windows, Hookshot PR 2306's native float add against the loop (Hookshot 2844, by nullifyshot)
  • 4719600a docs: add the tested-configurations row for Hookshot PR 2748's game run (Hookshot 2757, by Jiro131)
  • 84d4afd7 docs: add tested-configurations rows for the recorder thread on an RTX 4090 (Windows) (Hookshot 2912, by Jiro131)
  • 92ebb364 docs(tested): RX 7700 XT on CachyOS, v2.2.0-rc.1 in Kokiri Forest (Hookshot 3014, by Mark Roberts)
  • 785f565c docs: tested configurations: RX 5500 XT 8 GB (RDNA1, no mesh shaders), Windows 11, v2.2.0-rc.1-6 (Hookshot 3028, by Wagner Junior)
  • b16b31e8 docs: tested configurations: RX 5600 XT 6 GB (RDNA1, no mesh shaders), Windows 11, main de866017 (Hookshot 2715, by Waryxxful)
  • eea4379f docs: add RTX 5050 Laptop 8 GB runs with and without RX_VK_COMPACT=1 on v2.1.0 (Hookshot 2889, by VineeSouzaa)
  • 482379b2 docs(tested): RTX 5090 on Windows, Kokiri Forest: main against v2.1.0, 49f75dc8 and the last main before Hookshot PR 2602 (Hookshot 2840, by Dukenheimer)
  • 440009b3 test(vk): execute startup pool placement and fallback checks (Hookshot 2877, by Mooki)
  • a71a26ef feat(tests): run_all.py --changed runs the checks that read what changed (Hookshot 2887, by Jordan Ella)
  • 0155452d fix: readme's work/ffx-sdk, and the build log names an FSR 4 tick without AMD's license (Hookshot 2553, by RoblesLeo)
  • 417c5dd9 build(release): the RTX 5090 fork list's note says what its build changed (a follow-up to Hookshot PR 2143) (Hookshot 2703, by Dukenheimer)
  • 9ee58f7a feat(scripts): hookshot_bench.py, a repeatable benchmark route through the control bridge (Hookshot 2714, by Waryxxful)
  • 9817a531 ci: execute authored Vulkan fixtures on lavapipe (Hookshot 2866, by Mooki)
  • 065cb1ae test: one source cutter for the checks (tests/srccut.py), 80 checks moved to it (Hookshot 2914, by Jordan Ella)
  • 63584e06 docs: the restored Hookshot references as full URLs (mine)

Flags and settings

Flag What it does Default now Recommendation Helps on Doesn't help on Untested on
run_all.py --changed Runs only the checks that read what changed against a base Off (a flag) Use it while iterating; the full run before a PR Contributors - Windows
RX_VK_IMAGE_PREALLOC=<blocks> Existing; now documented (image blocks made at start) 15% of the device-local heap, 2 to 24 blocks Default - - -
RX_VK_TEST_ALLOWED_MB=<MiB> Existing diagnostic cap on the allowance the eviction policy sees; now documented Off Diagnostics only - - -

Measurements

No game change: the measurement is the game-free checks, main and this PR on the same PC.

main: d9648863 (2026-11-13)
this PR: restore/tools-checks-docs @ 28c64f55 (the runs; now 63584e06, after the docs-only rebase onto main's 514591a3)
Hardware: RTX 4070 Ti (driver 595.99.02), Ryzen 7 9800X3D, Ubuntu 26.04.1
Scene: none (game-free checks)
Method: python3 -I -B tests/run_all.py --jobs 6, once on each
How to reproduce: the same command on each commit, with LONGSHOT_VULKAN_HEADERS and LONGSHOT_SPIRV_HEADERS set

main @ d9648863 this PR @ 28c64f55
run_all.py: passed / failed / skipped 513/2/18 517/2/18
failing test_lift_cache.py, test_menu_i18n.py test_lift_cache.py, test_menu_i18n.py

The numbers still hold on 514591a3: main's #274 changed a Discord link in 11 docs files and nothing these checks or builds compile; the checks that read those docs were run again on this head.

Testing

Tested: python3 -I -B tests/run_all.py --jobs 6 on Linux (Ubuntu 26.04.1, Python 3.14, Vulkan and SPIR-V headers found): this PR @ 28c64f55: 517 passed, 2 failed, 18 skipped (test_lift_cache.py, test_menu_i18n.py); main @ d9648863 on the same PC: 513 passed, 2 failed, 18 skipped (test_lift_cache.py, test_menu_i18n.py). test_lift_cache fails on main the same way (the lift's scripts do not import here), and test_menu_i18n fails on that main too. Main then gained 514591a3 (#274, a Discord link in 11 docs files only); after the rebase onto it, the checks that read those docs passed again at 63584e06.

Not tested: the lavapipe job has not run on Longshot's Forgejo runners: it starts by hand, so a maintainer's
hand-started CI run is its first (expecting the Vulkan fixtures job to find one lavapipe ICD and pass).
hookshot_bench.py needs a running game, and I did not run it.

Needs other testers: None

Screenshots

Nothing on screen

Risk and rollback

None in the game. A check that srccut.py now cuts could fail where its marker is missing or repeated, which is the
point; each commit reverts on its own.

Reviewer notes

Please merge with rebase, not squash, so that each author keeps their commit.

Issues

See #209

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. (test output only: no game run to interleave; WIP)
  • 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 row in docs/tested-configurations.md for each measured run. (The 11 restored rows, from their authors' runs.)
  • A check under tests/ that reads changed source updated in this PR, not weakened.
  • Docs updated.
## Why Longshot lost the tools, checks, docs and tested-configuration rows Hookshot merged after Longshot branched. This brings back the ones that do not touch the game, so they can merge on game-free checks alone. Split out of [#209](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/209). ## What changed Split out of [#209](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/209) as its reviewer asked (review on #209, point 4, group a). Each commit is the merged Hookshot pull request under its original author, carried through Longshot's rename; a `Restored-from:` trailer names it, and the bare Hookshot numbers in the messages and the restored text are now full URLs. Credit to the authors of the restored work: jarynclouatre, jabbaxipil, Mooki, Jiro131, nullifyshot, Mark Roberts, Wagner Junior, Waryxxful, VineeSouzaa, Dukenheimer, Jordan Ella, RoblesLeo. - tests: `tests/srccut.py`, one source cutter, with 80 checks moved to it (a missing or repeated marker now fails); `run_all.py --changed` runs the checks that read what changed; the startup pool placement and fallback checks now execute - ci: `.forgejo/workflows/ci.yml` runs the authored Vulkan fixtures on lavapipe, started by hand like the other full checks - scripts: `hookshot_bench.py`, a repeatable benchmark route through the control bridge; a mistyped date in a claim no longer stops the test-request replay (`scripts/test_requests.py`) - release: the RTX 5090 fork list's note says what its build changed - docs: the README's `work/ffx-sdk` had a form feed in place of `/f`; 11 tested-configuration rows; `RX_VK_IMAGE_PREALLOC` and `RX_VK_TEST_ALLOWED_MB` documented Split siblings: test-request pinning [#285](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/285), rc.4 player fixes [#286](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/286), renderer fixes [#287](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/287), new defaults and speed-ups [#288](https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/288). Commits, in order: - `9e566b8c` fix(agents): a mistyped date in a claim does not stop the test request replay ([Hookshot 2949](https://github.com/NotRexed/Hookshot/pull/2949), by jarynclouatre) - `cc5adb88` docs: tested configurations: RX 7900 XTX, RADV Mesa 26.2.6, Ubuntu 24.04 GNOME X11 (v2.1.0) ([Hookshot 2616](https://github.com/NotRexed/Hookshot/pull/2616), by jabbaxipil) - `415f8a5c` docs(tested): record paired Linux RTX 4090 rolling results ([Hookshot 2778](https://github.com/NotRexed/Hookshot/pull/2778), by Mooki) - `3dbeb31d` docs: add tested-configurations rows for DLSS Frame Generation on an RTX 4090 (Windows) ([Hookshot 2771](https://github.com/NotRexed/Hookshot/pull/2771), by Jiro131) - `fad3f216` docs(tested): RTX 5080 on Windows, Hookshot PR 2306's native float add against the loop ([Hookshot 2844](https://github.com/NotRexed/Hookshot/pull/2844), by nullifyshot) - `4719600a` docs: add the tested-configurations row for Hookshot PR 2748's game run ([Hookshot 2757](https://github.com/NotRexed/Hookshot/pull/2757), by Jiro131) - `84d4afd7` docs: add tested-configurations rows for the recorder thread on an RTX 4090 (Windows) ([Hookshot 2912](https://github.com/NotRexed/Hookshot/pull/2912), by Jiro131) - `92ebb364` docs(tested): RX 7700 XT on CachyOS, v2.2.0-rc.1 in Kokiri Forest ([Hookshot 3014](https://github.com/NotRexed/Hookshot/pull/3014), by Mark Roberts) - `785f565c` docs: tested configurations: RX 5500 XT 8 GB (RDNA1, no mesh shaders), Windows 11, v2.2.0-rc.1-6 ([Hookshot 3028](https://github.com/NotRexed/Hookshot/pull/3028), by Wagner Junior) - `b16b31e8` docs: tested configurations: RX 5600 XT 6 GB (RDNA1, no mesh shaders), Windows 11, main de866017 ([Hookshot 2715](https://github.com/NotRexed/Hookshot/pull/2715), by Waryxxful) - `eea4379f` docs: add RTX 5050 Laptop 8 GB runs with and without RX_VK_COMPACT=1 on v2.1.0 ([Hookshot 2889](https://github.com/NotRexed/Hookshot/pull/2889), by VineeSouzaa) - `482379b2` docs(tested): RTX 5090 on Windows, Kokiri Forest: main against v2.1.0, 49f75dc8 and the last main before Hookshot PR 2602 ([Hookshot 2840](https://github.com/NotRexed/Hookshot/pull/2840), by Dukenheimer) - `440009b3` test(vk): execute startup pool placement and fallback checks ([Hookshot 2877](https://github.com/NotRexed/Hookshot/pull/2877), by Mooki) - `a71a26ef` feat(tests): run_all.py --changed runs the checks that read what changed ([Hookshot 2887](https://github.com/NotRexed/Hookshot/pull/2887), by Jordan Ella) - `0155452d` fix: readme's work/ffx-sdk, and the build log names an FSR 4 tick without AMD's license ([Hookshot 2553](https://github.com/NotRexed/Hookshot/pull/2553), by RoblesLeo) - `417c5dd9` build(release): the RTX 5090 fork list's note says what its build changed (a follow-up to Hookshot PR 2143) ([Hookshot 2703](https://github.com/NotRexed/Hookshot/pull/2703), by Dukenheimer) - `9ee58f7a` feat(scripts): hookshot_bench.py, a repeatable benchmark route through the control bridge ([Hookshot 2714](https://github.com/NotRexed/Hookshot/pull/2714), by Waryxxful) - `9817a531` ci: execute authored Vulkan fixtures on lavapipe ([Hookshot 2866](https://github.com/NotRexed/Hookshot/pull/2866), by Mooki) - `065cb1ae` test: one source cutter for the checks (tests/srccut.py), 80 checks moved to it ([Hookshot 2914](https://github.com/NotRexed/Hookshot/pull/2914), by Jordan Ella) - `63584e06` docs: the restored Hookshot references as full URLs (mine) ## Flags and settings | Flag | What it does | Default now | Recommendation | Helps on | Doesn't help on | Untested on | |---|---|---|---|---|---|---| | `run_all.py --changed` | Runs only the checks that read what changed against a base | Off (a flag) | Use it while iterating; the full run before a PR | Contributors | - | Windows | | `RX_VK_IMAGE_PREALLOC=<blocks>` | Existing; now documented (image blocks made at start) | 15% of the device-local heap, 2 to 24 blocks | Default | - | - | - | | `RX_VK_TEST_ALLOWED_MB=<MiB>` | Existing diagnostic cap on the allowance the eviction policy sees; now documented | Off | Diagnostics only | - | - | - | ## Measurements No game change: the measurement is the game-free checks, main and this PR on the same PC. main: d9648863 (2026-11-13) this PR: restore/tools-checks-docs @ 28c64f55 (the runs; now 63584e06, after the docs-only rebase onto main's 514591a3) Hardware: RTX 4070 Ti (driver 595.99.02), Ryzen 7 9800X3D, Ubuntu 26.04.1 Scene: none (game-free checks) Method: `python3 -I -B tests/run_all.py --jobs 6`, once on each How to reproduce: the same command on each commit, with `LONGSHOT_VULKAN_HEADERS` and `LONGSHOT_SPIRV_HEADERS` set | | main @ d9648863 | this PR @ 28c64f55 | |---|---|---| | `run_all.py`: passed / failed / skipped | 513/2/18 | 517/2/18 | | failing | test_lift_cache.py, test_menu_i18n.py | test_lift_cache.py, test_menu_i18n.py | The numbers still hold on `514591a3`: main's #274 changed a Discord link in 11 docs files and nothing these checks or builds compile; the checks that read those docs were run again on this head. ## Testing **Tested:** `python3 -I -B tests/run_all.py --jobs 6` on Linux (Ubuntu 26.04.1, Python 3.14, Vulkan and SPIR-V headers found): this PR @ `28c64f55`: 517 passed, 2 failed, 18 skipped (test_lift_cache.py, test_menu_i18n.py); main @ `d9648863` on the same PC: 513 passed, 2 failed, 18 skipped (test_lift_cache.py, test_menu_i18n.py). `test_lift_cache` fails on main the same way (the lift's scripts do not import here), and `test_menu_i18n` fails on that main too. Main then gained `514591a3` (#274, a Discord link in 11 docs files only); after the rebase onto it, the checks that read those docs passed again at `63584e06`. **Not tested:** the lavapipe job has not run on Longshot's Forgejo runners: it starts by hand, so a maintainer's hand-started CI run is its first (expecting the Vulkan fixtures job to find one lavapipe ICD and pass). `hookshot_bench.py` needs a running game, and I did not run it. **Needs other testers:** None ## Screenshots Nothing on screen ## Risk and rollback None in the game. A check that `srccut.py` now cuts could fail where its marker is missing or repeated, which is the point; each commit reverts on its own. ## Reviewer notes Please merge with **rebase**, not squash, so that each author keeps their commit. ## Issues See #209 ## 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). - [ ] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (test output only: no game run to interleave; WIP) - [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 row in `docs/tested-configurations.md` for each measured run. (The 11 restored rows, from their authors' runs.) - [x] A check under `tests/` that reads changed source updated in this PR, not weakened. - [x] Docs updated.
`scripts/test_requests.py`'s `until_time` passes any two digits for the
month, day, hour and minute to `time.strptime`, which raises on a date
like 2026-13-12 or 99:99. `replay()` did not catch it, so one mistyped
claim line in the room (`claim: until 2026-13-12 16:40Z`) stopped every
command that replays the room, for everyone, until that line left the
fetched history.

## Change

`until_time` returns `None` for a date that is not one, so the claim
gets the default length, as a claim without a date already does.

## Testing

- `tests/test_test_requests.py`, new cases: claims with month 13 and
with 99:99 replay, and each claim gets the default length. They fail on
main (`ValueError`) and pass here.
- Full suite on Linux: 442 passed, 85 skipped, 1 failed
(`test_bake_portability`: `zstandard` is not installed on this machine;
it fails the same on main).

Restored-from: https://github.com/NotRexed/Hookshot/pull/2949
Adds a row to `docs/tested-configurations.md` for an RX 7900 XTX on
Linux with RADV, on the v2.1.0 release. The page had no 7900 XTX, Ubuntu
24.04, GNOME X11 or Mesa 26.2.6 row yet.

- Kokiri Forest, at the stream by the village: 36.2 fps at about 2,726
draws, GPU time 16.8 ms a frame.
- The same view after about 10 minutes in Hyrule Field and Castle Town:
34.1 fps, the same as before exploring at the same draw count. No fade
on this 24 GB card in that session.
- Inside the Deku Tree, a short walk: 45.4 fps at about 811 draws, GPU
time 11.0 ms.

Stock v2.1.0 settings apart from fullscreen, 2560x1440 output and 100%
render resolution. No `RX_VK_` variables. udmabuf access on.

See https://github.com/NotRexed/Hookshot/issues/2156 (the GPU time numbers next to the 780M ones) and https://github.com/NotRexed/Hookshot/pull/993 (the
fresh and after-exploring comparison in full).

Assisted-by: Claude Opus 5.5 (measurements, analysis, drafting)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: jabbaxipil <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2616
**What this is for:** keep the Linux RTX 4090 results from https://github.com/NotRexed/Hookshot/pull/2595 in the
tested-configurations table. **What is measured:** twelve rows covering
four builds and three scene/settings pairs, with both repeats'
log-window FPS medians and ranges. **Not measured:** other cards,
Windows or presentation through a real window.

## What changed

- Adds v2.1.0, pre-fix main `ef81aee7`, main `46780503`, and this
morning's main `51da0464`, newest build first. The newest rows also
retain their contemporaneous `46780503` controls rather than treating
the overnight figures as that comparison.
- Folds repeats and unchanged cells as the existing table does. Logged
version strings retain the diagnostic-only instrumentation; 240 fps is
explicitly a cap, not Uncapped.

## How they were measured

Arch Linux, i9-13900K, RTX 4090, NVIDIA 615.78.08; 2048x1152, warmed
caches. Timed camera sweeps in Kokiri Forest and Hyrule Field used
alternating runs in exclusive timing holds; every retained run met the
quiet criteria (other CPU below three cores on average and six at the
peak).

These are medians and ranges of complete 120-present **game-log
windows**, not the trace-derived whole-window means in the [overnight
comparison](https://github.com/NotRexed/Hookshot/issues/2595#issuecomment-6819741343)
and [morning
comparison](https://github.com/NotRexed/Hookshot/issues/2595#issuecomment-6823250809).
Extraction checks retained each quoted source line and checked build,
device, settings, quiet eligibility and fault counts. Existing captures
show the loaded scenes; camera views are not pixel-locked.

Documentation-only: `git diff --check` passes. No dedicated
documentation checker or test reading this table was found, so there was
no matching test to run through `tests/run_all.py --strict --jobs 1`. No
code or fixture changed and no new game run was needed.

## Limits

One card, no window, a timed route—not scanout, physical-input testing,
continuous flicker proof or a long-session memory test. Each row carries
the date its runs ended. The fixed-release reference was one overnight
session and was not rerun beside every newer build: its Kokiri Forest
runs ended before midnight (2026-11-11), its Hyrule Field and DLAA runs
after it (2026-11-12), and those two rows say so.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra <[email protected]>

---------

Co-authored-by: GPT-6 Astra <[email protected]>
Co-authored-by: Claude Fable 5.2 <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2778
These runs belong in the tested-configurations table. They are the first
rows for DLSS Frame Generation from NGX on an RTX 40 card under Windows.
They also record two open problems with a build and a driver: https://github.com/NotRexed/Hookshot/pull/2695's 36
fps at 4x, which persists after https://github.com/NotRexed/Hookshot/pull/2701, and the `framegen_record` crash
that https://github.com/NotRexed/Hookshot/pull/2658 fixes.

Six rows, all 2026-11-12 on one machine: RTX 4090 (NVIDIA 621.01, 144 Hz
display), Windows 11 Home, i9-13900K. `main` 51da0464 was built from
source with NGX (SDK 310.9.16). Settings: DLSS DLAA (model K) at
2560x1440, frame generation by Auto, frame pacing on, cap 60, V-Sync
Auto. Kokiri Forest from a save.

- 2x, Reflex off and on: DLSS-G made every frame, median 60.0 fps in
play.
- 4x, in a window and fullscreen: the runtime makes 1 frame, so the
renderer's own made them on mailbox
([#2701](https://github.com/NotRexed/Hookshot/pull/2701)). The game
stayed at 36.0 fps (144 / 4), with 0 frames on time in each
frame-interpolation report. Details in the comment on https://github.com/NotRexed/Hookshot/pull/2701.
- The two crashes on `main` in `framegen_record` (a multiplier step, and
a fullscreen-to-window switch at 4x), and `main` plus https://github.com/NotRexed/Hookshot/pull/2658 with no
crash over the same steps. Details in the comment on https://github.com/NotRexed/Hookshot/pull/2658.

Figures come from `hookshot_log.txt` ("N presents, X fps", the
frame-interpolation and DLSS Frame Gen lines). "In play" means the
120-present windows after the load. The feel (smooth, pacing, latency)
is what the tester saw while playing.

Docs only, no code. https://github.com/NotRexed/Hookshot/pull/2757 and https://github.com/NotRexed/Hookshot/pull/2769 also add rows at the top of the same
table, so whichever merges later needs a one-line rebase.

Tracking: https://github.com/NotRexed/Hookshot/pull/2510.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2771
The tested configurations had no RTX 5080 on Windows and none of the
runs behind my numbers on https://github.com/NotRexed/Hookshot/pull/2306 (native float add on storage buffers).
This adds them, so the next tester can see what is already covered.

Four rows, newest first, all on the same PC (RTX 5080 16 GB, NVIDIA
621.14, Windows 11, Ryzen 9 9900X3D, 64 GB), headless at the game's
default 2048x1152 output, the 60 fps cap with normal pacing, Link
standing 150 s, `vk: GPU time` every 120 presents:

| Where | Native add | `RX_VK_NATIVE_FADD=0` |
|---|---|---|
| Kakariko Village, child | 6.70 ms (6.5-7.5) | 7.00 ms (6.7-8.0) |
| Death Mountain Trail, child | 4.60 ms (4.4-5.2) | 4.80 ms (4.7-5.7) |
| Death Mountain Trail, adult | 5.40 ms (4.5-6.3) | 5.60 ms (4.8-6.6) |

- The child runs are a build of https://github.com/NotRexed/Hookshot/pull/2306 rebased onto main 87991bc
(`v2.1.0-rc.3-249-g48e2fe4`); the adult runs a build of main c544828
with https://github.com/NotRexed/Hookshot/pull/2694 (the bridge's `age` command, to switch to the adult) and
https://github.com/NotRexed/Hookshot/pull/2306's commits (`v2.1.0-rc.3-252-g5692d75`). The build strings are `git
describe` of those commits; the run logs are gone.
- Posted on https://github.com/NotRexed/Hookshot/pull/2306 at the time:
https://github.com/NotRexed/Hookshot/pull/2306#issuecomment-6817565938
(adult) and the child numbers above it.
- Docs only. `python -I -B tests/run_all.py`: 419 passed; the 5 failures
are main's own on this PC (fpx_sticky, spawn_emit, bake_portability,
input_background, lift_cache).
- Not covered: one run each way, no night, no other GPU.

Before opening I checked the open PRs that edit this file (34) and main:
none has these runs.

See https://github.com/NotRexed/Hookshot/issues/2306

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: breakthetargets <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2844
that run was only described in the PR; `docs/tested-configurations.md`
asks for a row per run, so the next tester can see that this setup is
covered.

One row, newest first: build `v2.1.0-rc.3-256-gf79aa054` (https://github.com/NotRexed/Hookshot/pull/2748's branch
plus the damaged-texture check change of https://github.com/NotRexed/Hookshot/pull/2754), Windows 11, RTX 4090 on
NVIDIA 621.01, 5120x1440, upscaler and frame generation off, 60 fps cap,
Kokiri Forest from a save. The figures come from `hookshot_log.txt`: 32
windows of 120 presents in Kokiri, median 56.1 fps (43.4-60.6) at
1,764-3,926 draws, no device lost.

Docs only: no code, no test change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2757
The recorder thread (https://github.com/NotRexed/Hookshot/pull/1473) has so far been measured only on AMD under
Linux. These rows add NVIDIA under Windows. On this CPU-bound machine it
cuts the replay's time by about a fifth, and heavy scenes run 7 fps
faster.

**Setup**
- Hardware: i9-13900K, RTX 4090 (621.01), Windows 11 Home, fullscreen.
- Build: `main` 9b6072cd, built from source (llvm-mingw, no DLSS).
- Settings: 2560x1440 output, uncapped (`HOS_FPS_MAX=1000`; the
GPU-bound wait was 0 throughout).
- Route: Kokiri Forest from a save, the same 2-minute walk each run,
1,000 to 4,500 draws a frame.
- Runs: one warm-up, then base, `RX_VK_RECORDER=thread`,
`RX_VK_RECORDER=thread`, base.

**Replay time on the Presentation Thread, median of the 120-present
windows with 1,000+ draws (first one after the load left out)**

| | base 1 | recorder 1 | recorder 2 | base 2 |
|---|---|---|---|---|
| submit (ms a frame) | 8.74 | 6.98 | 6.97 | 8.62 |
| draw | 5.64 | 4.44 | 4.39 | 5.52 |
| commands | 2.12 | 1.15 | 1.14 | 2.08 |
| fps | 81.9 | 81.7 | 81.7 | 80.8 |

**Fps by draw count (both runs of each arm pooled)**

| draws | base | recorder |
|---|---|---|
| 1,000-1,500 | 90.1 | 87.2 |
| 1,500-2,000 | 84.2 | 84.0 |
| 2,000-2,500 | 78.6 | 81.8 |
| 2,500-3,000 | 72.5 | 75.0 |
| 3,000-4,500 | 65.3 | 72.1 |

**Reading**
- The gain is in `commands` and `draw`, the parts the recorder takes off
the replay thread.
- Below about 2,000 draws the frame rate does not move, so something
other than the replay sets the frame there. The overall median is
therefore flat (81.7 against 81.2) while heavy scenes gain 7 fps.
- Cost: the replay waited for the recorder about 145 ms in each 10 s
(the longest 0.3 ms), and the recorder spun idle about 5 s in each 10 s.
That is half a core, so it may cost more on CPUs with fewer cores.
- No visual difference. The log shows no recorder refusal, and the same
failure lines as base. The tester found the pacing good with the
recorder, and average without.

An earlier session on `main` 51da0464, same machine and route, gave the
same picture: replay −18%, 70 fps against 62 above 3,000 draws.

Docs only, no code.

Assisted-by: Claude Code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2912
No run on an RX 7700 XT was recorded yet, and Linux AMD is the tier with
the fewest measured runs. This adds one row to the tested
configurations.

**What was run:** the v2.2.0-rc.1 release AppImage (commit 4aee2365,
`source b73bb675` in the log), on CachyOS (kernel 7.3.3, COSMIC Wayland)
with an RX 7700 XT 12 GB on Mesa RADV 26.2.6, a Core i7-14700KF and 64
GB. Output 2560x1440 fullscreen, the default 60 fps cap. The numbers
come from `hookshot_log.txt`.

**What was measured:** Kokiri Forest, standing still at the same spot,
about 2,600 draws a frame, with three settings in one session:

| Upscaler | fps | Slowest frame of each 600 |
|---|---|---|
| Off | 55.6-56.3 | 23-24 ms |
| AMD FSR 3.1 at 100% | 55.2-55.8 | 23.6-23.9 ms |
| AMD FSR 3.1 Quality (1707x960) | 60.0 (the cap) | 21.6-24.5 ms |

Lowering the render resolution alone reached the cap, so this card is
GPU-bound at native 1440p. Video memory used was 7.8-8.1 of 10.8 GB. The
run got past the opening cutscene with no device lost. 10-12 programs
failed from the title screen on, with nothing visibly wrong. A SCUF
Gaming Controller (`2e95:0504`) is mapped by SDL as an Xbox pad, and
Layout preset Xbox / PC puts its face buttons right.

**Checks:** `python -I -B tests/run_all.py` gives 456 passed, 2 failed,
71 skipped. The 2 failures happen on `main` too, on this machine only
(missing `zstandard` and Tk), and are not touched by a docs change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/3014
**Why.** The page has no RX 5500 XT row. With https://github.com/NotRexed/Hookshot/pull/2715 (RX 5600 XT 6 GB),
this would be the second RDNA1 card without mesh shaders (https://github.com/NotRexed/Hookshot/pull/1001) on it.
This one has 8 GB and runs the v2.2.0-rc.1 release candidate with a
player's overclock.

**What.** One row: free play as child Link after the three Spiritual
Stones, measured per map from the game's own log (the 5-second fps
lines, `GPU time`, the `status:` lines). Settings: Handheld profile, FSR
3.1 at 75%, frame generation off. For comparison, the same build with
frame generation Auto at 165 Hz. The full numbers and the logs, with the
user name replaced, are in
https://github.com/NotRexed/Hookshot/issues/1001#issuecomment-6842826850.

These are free-play numbers, not the scripted standing runs of https://github.com/NotRexed/Hookshot/pull/2715, so
they show what a player sees rather than a fixed spot.

Docs only; no test or script reads this page.

See https://github.com/NotRexed/Hookshot/issues/1001

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/3028
**Why.** The page has no RX 5000 row yet, and RDNA1 is one of the cards
without mesh shaders (https://github.com/NotRexed/Hookshot/pull/1001) that runs the compute fallback. These are
the first measured runs on one, made from the same save each time so
they can be compared later.

Two rows:
- **Main `de866017`:** Kokiri Forest and Hyrule Field over four runs,
the first start's preparation times on this card (shader programs 120 s,
predicted pipelines 3,603 s, noted pipelines 2,355 s; later starts 11
s), and VRAM at the driver's allowance.
- **One switch a run:** `RX_VK_MIRROR=0`, `RX_VK_PARALLEL=3`,
`RX_VK_PRECOMPILE=0`.

All runs were scripted through the control bridge: teleport, 15 s to
settle, 60 s standing, from a copied save restored before each run. The
fps are the medians of the log's `N presents` lines.

Docs only; no checks read this page.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2715
Players on 8 GB cards have no real-play numbers for `RX_VK_COMPACT=1` on
the released v2.1.0, only emulated-allowance runs on a 12 GB card. This
adds two rows from a real 8 GB laptop.

Part of https://github.com/NotRexed/Hookshot/pull/993.

**What changed:** two rows at the top of
`docs/tested-configurations.md`, newest first, in the page's format:
v2.1.0 release on an RTX 5050 Laptop 8 GB (Pop!_OS, driver 595.104.02),
with `RX_VK_COMPACT=1` (three sessions) and without it (one ~100 min
session).

**How it was measured:** `hookshot_log.txt` only. VRAM share is the
`status: 600 frames ... VRAM X of Y GB` lines past 95% of the allowance;
fps is the "N presents, X fps" windows. Reproducible from the logs; I
can attach them.

- VRAM past 95% of the allowance: 87 of 494 lines without (18%), 7 of
334 with (2%).
- Windows under 30 fps: 2.7% without, 0.1 to 1.2% with.
- Mean fps: 54.1 without; 47.3, 46.2 and 55.7 with. The sessions had
different content, so the fps is **not** a controlled A/B and the rows
say so. The VRAM and stutter figures are the part that repeated in all
three sessions.

Docs only; no code, no game data, no `hookshot_options.ini` or
`hookshot_env.txt` contents beyond the switch named in the row.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2889
The tested configurations had no RTX 40/50 Windows run of Kokiri Forest,
and no single-PC comparison of main against the builds before
i7-13700K.

**What changed:** seven rows at the top of
`docs/tested-configurations.md`:
- main `46780503`, standing at the Kokiri village autosave: 2048x1152
uncapped 65.7 ± 1.7 fps (GPU 7.1 ms, no GPU-bound wait), 5120x2160 57.2
± 0.4, and DLSS + DLSS Frame Generation 2x capped at 165: game 61.9 /
shown 123.9. Each row includes the critical path from `HOS_CHAIN` +
`scripts/chain.py`: of 15.9 ms a frame, the Presentation thread's inline
replay is ~12.0 and sead::MainThread ~2.8.
- main `9776c36d` 61.9 fps against `55b976c0` (the last main before
alternated in rounds, with readback waits per game frame (2.4-2.9 /
8.2-9.4 / 0.1 / 0.1 ms).

All builds were made from source with the Hookshot Builder's toolchain
and v2.1.0's profile and hot list. The same autosave was loaded by a
scripted input, a warm-up run came first, and frames were measured 40-70
s after the first present (`HOS_PRESENT_TRACE`). The earlier summary on
https://github.com/NotRexed/Hookshot/pull/2602#issuecomment-6817467208.
A moving-route measurement (running and panning through Kokiri) follows
as a second commit.

**Tests:** docs only; no check reads this file. Nothing on screen.

See https://github.com/NotRexed/Hookshot/issues/2602

---------

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2840
**What this is for:** execute the real pool constructors behind
[hckrman101's merged
https://github.com/NotRexed/Hookshot/pull/2711](https://github.com/NotRexed/Hookshot/pull/2711), rather than
checking their wiring only as source text. **What is measured:**
GCC/Clang behavior checks, Windows-target compilation, and execution of
the test on Ubuntu and Windows in the fork. **Not measured:** new
gameplay, AMD or physical 8-GB-card behavior; no renderer behavior
changes here.

Refs https://github.com/NotRexed/Hookshot/issues/2711

## New coverage
A refused first allocation must retry with zero initial blocks, report
zero kept bytes, and return null if the retry fails. The fixture
compiles the production constructors against a refusing allocator and
also checks default placement, compaction off, explicit/zero counts and
cached reuse. Every original numeric/wiring assertion stays; `--source`
enables the negative comparison. The merged test checked the fallback
assignments as strings but did not execute the refusal.

## Checks
Arch Linux 7.2.15-1-omarchy, GCC 16.2.1 and Clang 23.1.3. Rebased head
`8bf7817f1` on main `4cf785a0b`; the test commit is identical to the
fork-tested version (`605cf9ec7 = 4788c8a77` in the range-diff). Only
independent documentation rows conflicted; both sets are retained, with
our rows together.

| Production source | GCC | Clang |
|---|---|---|
| Merged fix `1c0cd9803` | Six constructor cases and original checks
pass | Same |
| Its parent `b157c3e8` | Four constructor cases fail; compaction-off
and preallocation-off pass | Same |
| Rebased head `8bf7817f1` | Six constructor cases and original checks
pass again | Same |

The negative checks compile and fail behavior assertions, not
missing-string checks.
[Fork run
43268735876](https://github.com/mooki000/Hookshot/actions/runs/43268735876)
on `185a460b`: `tests/test_blocks_at_start.py` passes on Ubuntu (0.8 s)
and Windows (13.8 s).
The run's other failures were `test_readme_menu_rows.py` and, on
Windows, `test_wb_shadow_remake.py` (main failures tracked by https://github.com/NotRexed/Hookshot/pull/2857 and
https://github.com/NotRexed/Hookshot/pull/2868), plus `test_release_scripts.py` (the nightly race fixed since by
https://github.com/NotRexed/Hookshot/pull/2822). The whole workflow was not green; none of those failures is this
test.
Local Windows-target compilation passed both C++ units with `-std=c++20
-Wall -Wextra -Werror`. Earlier full suite: **476 passed, 0 failed, 20
skipped**; not repeated for this documentation-only rebase. The plain PR
gate passes.

## Historical rows, not new timing evidence
Four pre-merge Market runs retain their exact commits (`51da0464`, fix
`234f72a3`, combined `3972579c`) in the tested-configurations table:
Arch/RTX 4090, NVIDIA 615.78.08, 2560×1440, default DLSS model K at
DLAA/100%, ordinary shared-card runs. They are not relabelled as this
head's gameplay evidence.
Under the 7000-MiB/9-block model, utility blocks fell from nine to one
for the same 102 MiB of images; final budget snapshots were 835 versus
1771 MiB. No fatal/device/driver fault; no speed or real-card paging
claim. No new game run was made for this test follow-up.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra <[email protected]>

---------

Co-authored-by: GPT-6 Astra <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2877
A full `tests/run_all.py` is about 490 checks and several minutes, and
the ones an edit touches had to be picked by hand, which is how a check
that cuts a function far from the edit gets missed (AGENTS.md: "Tests
read the source"). This is the dev-loop proposal's D1 (https://github.com/NotRexed/Hookshot/pull/2636).

## Change

`tests/run_all.py --changed [BASE]` takes the files changed since BASE's
merge base (`origin/main` by default), committed or not, plus the
untracked ones, and runs:
- the checks whose text names one of them: by path, by file name
standing alone, or as a module they import (`import chunks`, `from
chunks import`);
- the changed checks themselves, and the byte-compile check;
- the C++ unit tests when something under `gpu/` changed;
- **every check** when the runner itself or a shared file under `tests/`
changed.

It prints how many files changed and how many checks read them, and that
a pull request still needs the whole run. Nothing else in the runner
changes.

## Example

On this branch (the runner changed): `--changed: 2 files changed since
origin/main, every check (the runner or a shared test file changed)`.
For a change to `nx2/chunks.py` alone it picks the chunk, emit and
lift-cache checks (under a quarter of all), not the renderer's.

## Testing

- **`tests/test_run_all_changed.py` (new):** which checks a changed file
picks (by path, by name and not inside a longer name, by import), that a
changed check runs itself, that the runner or a shared test file runs
everything, that an unnamed file runs none, and the files from git
(committed, uncommitted and untracked) in a scratch repository.
- **`run_all.py --changed origin/main` on this branch, Windows:** every
check, as above: 423 passed, 21 failed, 79 skipped. The 21 fail the same
way on `main` here (this PC's compilers and Linux-only checks).
- **The checks that read the changed files (10):** pass, apart from
`test_spawn_emit`, which fails the same way on `main` here.

See https://github.com/NotRexed/Hookshot/issues/2636 (D1).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2887
Follow-up to https://github.com/NotRexed/Hookshot/pull/1866's review.

- **readme:** the default `HOOKSHOT_FFX_SDK` folder read
`work<0x0C>fx-sdk` (a `\f` had turned into a form feed). It reads
`work/ffx-sdk` now.
- **Windows Builder:** an AMD FSR 4 tick saved before the builder asked
for AMD's license still builds with FSR 4 and fetches nothing, as
before. The build log now says so in one line: "AMD's license not
accepted yet: tick AMD FSR 4 again to have its runtime fetched".
`tests/test_ffx_sdk.py`'s source check covers the line.

Ran locally on Windows: `test_ffx_sdk`, `test_make_game_ngx`,
`test_builder_dlss_update` and `dotnet build` of the Builder, all
passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>

Ported to Longshot: only the readme fix. Longshot's builder is command line only (#181), so the Builder window's
log line and its source check are left out.

Restored-from: https://github.com/NotRexed/Hookshot/pull/2553
Follow-up to https://github.com/NotRexed/Hookshot/pull/2143, which merged before I could answer Joey-Magnus's and
hckrman101's question about `brett-d-rtx-5090-fork-fg-2x`. This changes
only that list's note, to say what its build was.

The "fork" was local builds of main at 0828863 (9 Nov), plus changes
that don't touch what goes into a record: DLSS-NR and an FXAA option in
the window-scaling pass, a sampler cache and its descriptor-reuse check,
a texture budget, menu rows and a voice feature. There are no changes to
shader translation, program variants, target formats or draw state.

`python -I nx2/pipeline_states.py check` passes. The list itself is
unchanged.

Refs https://github.com/NotRexed/Hookshot/issues/2034, https://github.com/NotRexed/Hookshot/pull/2143

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2703
**Why.** Most performance PRs say "not tested in the game yet", and the
reports that do test can't be compared, because each tester stands
somewhere else for a different time. https://github.com/NotRexed/Hookshot/pull/2595 asks for a repeatable route
through the control bridge. This is one, run on real hardware: last
night it measured six open PRs and five switches on an RX 5600 XT.

## What it does

`scripts/hookshot_bench.py GAME_DIR --name NAME [--save DIR] [--env
NAME=VALUE]...`

1. Starts the game folder with the bridge on (`hookshot_ctl.py launch`),
with the switches given.
2. Waits for frame 1 in 50-minute steps, up to 8 h, because the bridge
answers a `wait` within the hour and a first start's preparation can
take longer: 1.6 h of pipelines on the RX 5600 XT.
3. Presses A until the newest save is loaded.
4. For each place (default `KokiriForest_Child`, `HyruleField_Child`):
teleports there, waits until no event or load plays, settles 15 s, then
measures 60 s standing.
5. Takes a screenshot of each place, quits, and writes `summary.json`.
For each place it holds the medians of the log's `N presents` fps and
draws, `GPU time`, every part of `replay time (ms)`, the highest VRAM
used, the bridge's fps, the process's memory, and the share of the
window an event played in.

## Two things found the hard way, handled

- **The game saves by itself as it plays.** A slot is rewritten in each
run, and Continue loads the newest, so the second run started somewhere
else. `--save DIR` (with `--slot`) starts every run from the same save:
- **Windows:** the folder's `user/save` is set aside and put back after
the game has closed.
  - **Linux:** `launch --save` copies it into the run's own data folder.
- **A message can wait for a button.** The wake-up cucco hatches by the
game's clock, and its message held a run in an endless "event". An event
that lasts 8 s is closed with A, before the window and in it, and
`summary.json` counts the presses.

## Tests

- `tests/test_hookshot_bench.py` (16 checks, no game, no socket) runs
against a stand-in bridge on a fake clock:
  - the log sums from lines in the game's own format;
  - the first-frame wait going on after timeouts and giving up;
  - A until a save loads;
  - a refused teleport waited out;
  - no map wait when already there;
  - messages closed with A in both places;
- `saves_in` setting aside and putting back, and refusing a folder with
no slots or one left from an earlier run;
  - process memory and liveness on Windows and Linux.
- `python -I -B tests/run_all.py` on Windows: the new check passes; the
same 14 checks fail with and without this change (audio, menu i18n,
docker packages, ... on this Windows box), none in files it touches.
- In the game: Windows 11, RX 5600 XT, main `de866017`, the script
itself with `--save`. Kokiri Forest 33.2 fps, Hyrule Field 35.1, which
matches the local version that ran 23 times last night. The saves were
back in place afterwards.

`docs/control.md` gets a "A benchmark route" section. Its Known limits
now say the bridge has been driven inside a Windows game build
(`launch`, `status`, `wait`, `press`, `teleport`, `shot`, `quit`), which
it had not been before.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: NotRexed <[email protected]>
Restored-from: https://github.com/NotRexed/Hookshot/pull/2714
**Result:** all **13 authored cases pass** on `NVIDIA GeForce RTX 4090`
(615.78.08), `Intel(R) Graphics (RPL-S)` (Mesa ANV 26.2.5), and Ubuntu's
llvmpipe (Mesa 25.2.8). Validation is directly confirmed for every
fixture on lavapipe in CI; it was not installed for the local
NVIDIA/Intel runs. The validated fork job took **23 seconds from start
to finish**, including setup.

**What this is for:** give contributors real Vulkan execution checks
without a game dump, following [#2797's idea of game-free GPU
tests](https://github.com/NotRexed/Hookshot/issues/2797#issuecomment-6826819619).
The existing fixtures use the production write-back shader and
copy/presentation helpers, but ordinary source checks did not execute
their device paths. **Not measured:** the game, a swapchain, HDR, DLSS,
full renderer behavior or performance. Lavapipe is CPU software Vulkan,
not a hardware GPU.

Refs https://github.com/NotRexed/Hookshot/issues/2797. This is only the hosted, dump-free part of that proposal. It
needs no exception to “No game in CI,” no self-hosted runner and no
access to a tester's machine.

Device selection is explicit in both places: CI pins the lavapipe ICD
and matches the reported name `llvmpipe`; local runs pin the
NVIDIA/Intel ICD and match `RTX 4090` / `RPL-S` from `vulkaninfo`, not a
marketing label.

## Problem

- `tests/run_all.py --strict` fails missing build tools, but retains
each test's declared OS skips. Its shards do not add GPU opt-ins.
- `test_wb_diff_observations_gpu.py` therefore only compiles.
`test_vulkan_copy_span.py` runs its CPU fixture unless asked for
`--gpu`. The offscreen aspect fixture is skipped on both CI systems.
- A zero exit alone would be misleading: the copy fixture returns zero
when it prints `SKIP`. Write-back and aspect also do not turn validation
messages into process failures themselves.
- The aspect fixture preferred any discrete device and had no explicit
selection option. That is unsuitable for claiming that a particular
driver was exercised.

## What changed

- **First commit, test-only:** aspect gains `--device SUBSTRING`,
case-insensitive. No match fails and lists the devices seen. Without the
flag its existing first-discrete-else-first preference and output stay
unchanged.
- **One new job in `source-regressions.yml`:** `Vulkan fixtures
(lavapipe, validation)`, on `ubuntu-24.04`. It installs only the C++
compiler, Mesa Vulkan driver, loader/headers, validation layer and
`vulkaninfo`; records their versions; and requires exactly one lavapipe
ICD manifest. Both Vulkan loader variables point to that one file.
Checkout remains commit-pinned, without persisted credentials.
Permissions remain read-only; existing concurrency applies.
- **`tests/run_vulkan_fixtures.py`:** records `vulkaninfo --summary`,
requires one llvmpipe device and the validation layer, then explicitly
selects llvmpipe in all three fixtures. Nonzero exits, exit 77, skips,
missing/wrong device names, missing/repeated cases, zero readback counts
and validation errors fail the job. It keeps running the other fixtures
after a failure and writes the usual result/time/check/note summary.
- **Validation:** forces the Khronos layer and requires the loader to
confirm insertion into each fixture's instance and device chains.
Installed/advertised validation alone is not enough. The two fixtures
without an error callback have the layer log errors to stdout; the
wrapper reads that output and fails on errors. The copy fixture must
also report that its validation messenger is enabled. No product code is
changed to hide errors.
- **Game-free regression and contributor guide:** cover the failure
rules, workflow pinning/permissions/device settings, and the actual
aspect-selection function with authored device properties. Ordinary
source checks keep their GPU-independent defaults.

| Fixture | Executed checks | Required Vulkan support |
|---|---|---|
| Write-back observations | Five buffer/feedback cases, using the
production compute shader | 1.3, buffer device address, maintenance4,
compute subgroup votes, coherent host memory |
| Copy span | Four texels and untouched padding in a 24-byte
upload/readback span | 1.1, transfer queue, RGBA8 transfer support,
coherent host memory |
| Offscreen aspect | Seven aspect/crop/blit cases with pixel readback |
1.3, synchronization2, RGBA8 linear blits, graphics queue |

These capabilities are present in [Mesa 25.2.8's lavapipe
declarations](https://gitlab.freedesktop.org/mesa/mesa/-/raw/mesa-25.2.8/src/gallium/frontends/lavapipe/lvp_device.c)
and [format
handling](https://gitlab.freedesktop.org/mesa/mesa/-/raw/mesa-25.2.8/src/gallium/frontends/lavapipe/lvp_formats.c),
the Mesa release currently listed for Ubuntu 24.04 updates. The actual
runner's package and device versions are logged. There is no reduced
“pass” set: all 13 cases are required; a missing capability fails.

**When it runs:** every PR to main, main push and manual source-check
run, matching the existing unfiltered source workflow. Packaging jobs
ignore documentation-only changes and the large DLSS link job has narrow
filters; this small authored execution check stays with source
regressions. It also notices changes in the runner's Mesa on otherwise
unrelated PRs.

## How it was tested

Original runtime base `51da0464b4`; final
rebased base **`f5c9acc15b`**, head
**`d5d04b20a36433e9ff1de18acdf95ae0581eb879`**. All four commits are
patch-identical across the rebase. The fixture drivers/templates, shader
and copy inputs are unchanged; the exact generated aspect program is
byte-identical despite unrelated changes in its source file. Hardware
results therefore carry without repeating the same programs. The final
docstring-only commit changes no executable code.

Linux kernel `7.2.15-1-omarchy`, i9-13900K, Clang 23.1.3, GCC 16.2.1,
Python 3.12.16, Vulkan headers 1.4.345; 2026-11-12. All fixture
execution is offscreen, without a window or swapchain. Final
author/trailer/title/no-game-output checks pass on the rebased head.

- New regression, with Clang: first 10 checks pass; after requiring
direct layer-activation evidence, `Ran 11 tests in 0.213s`, `OK`. The
added case rejects either missing activation marker from every fixture.
- Same regression against the pinned main source: exits 1, for the
absent explicit selector and absent lavapipe job. The output/validation
rejection cases are device-free; they do not count as GPU execution.
- Original-base whole source suite on `d7760411`: `476 passed, 0 failed,
20 skipped in 213 s (linux, 4 at once)`, with `--strict --jobs 4`; no
shard.
- **Rebased whole suite on d5d04b20: `501 passed, 2 failed, 20 skipped
in 294 s (linux, 4 at once)`.** The new wrapper test passes. The two
failures are main's own at this base, not this change's:
`test_program_cache_one_variant.py` (fixed by https://github.com/NotRexed/Hookshot/pull/2861) and
`test_readme_menu_rows.py` (fixed by https://github.com/NotRexed/Hookshot/pull/2857). On Windows main has a
third, `test_wb_shadow_remake.py` (a fix is on its way as its own pull
request). [The fork's run on this rebased
head](https://github.com/mooki000/Hookshot/actions/runs/43271225010)
fails in exactly those three tests and nowhere else; its `Vulkan
fixtures (lavapipe, validation)` job, both Windows builds, the AppImage
and actionlint pass.
- Windows-target syntax: both the new selector-test translation unit and
the full generated aspect fixture pass with their warnings-as-errors
flags. The automatic checker intentionally marked the GPU-skipped driver
unjudged; an explicit compile-only capture of that same driver completed
the syntax check. Neither is a Windows device run.
- Real Windows source execution on `5857491d`:
`test_vulkan_fixtures_ci.py` passes in part 2/2 (1.3 s), including the
selector helper. Windows totals: part 1/2 `227 passed, 0 failed, 17
skipped in 209 s`; part 2/2 `236 passed, 0 failed, 16 skipped in 165 s`.
Full Windows Vulkan execution remains untested.
- **RTX 4090 / NVIDIA 615.78.08 / Vulkan 1.4.351:** all 13 cases pass,
all three commands exit 0; write-back 0.749 s, copy 0.617 s, aspect
4.566 s, including compilation. Runs at 10:41:26–10:41:31 -06:00;
1-minute load 7.03→8.07. **Validation layer not installed here**. No
Xid, device-loss or NVRM errors. The nine HDMI-0 EDID-read kernel
warnings are unrelated display messages, not validation errors.
- **Intel(R) Graphics (RPL-S) / Mesa ANV 26.2.5-arch1.1 / Vulkan
1.4.354:** all 13 cases pass with substring `RPL-S`, all commands exit
0; write-back 0.669 s, copy 0.901 s, aspect 0.963 s, including
compilation. Runs at 11:32:02–11:32:05 -06:00; load 121.24/115.20/76.38,
unchanged during the three commands. These are correctness results on a
busy PC, not a speed comparison. **Validation layer not installed
here**; kernel interval empty.
- **A setup mistake of mine, kept for the record:** the first Intel
attempt asked for `UHD Graphics 770`, which is not in the name the
driver reports, so the write-back fixture returned 77 with zero cases
run. That is the wrapper refusing a wrong device, as intended; the Intel
cases were then run with `RPL-S`.
- [The fork's source workflow on the patch-identical head
`6085c658`](https://github.com/mooki000/Hookshot/actions/runs/43270742409),
on the base from before main's three failures: every job passes, both
Windows parts included, and the Vulkan job confirms the Khronos layer in
each fixture's instance and device chains. Whole job: 23 to 26 seconds
in the earlier runs, 11 of them package setup.

The [first lavapipe
job](https://github.com/mooki000/Hookshot/actions/runs/43255289863/job/131311732104)
selected **llvmpipe (LLVM 20.1.2, 256 bits)**, API **1.4.318**, Mesa
**25.2.8-0ubuntu0.24.04.4**, with validation package **1.3.275.0-1**,
loader/headers **1.3.275.0-1build1**, Vulkan tools
**1.3.275.0+dfsg1-1**, GCC **13.3.0** and Python **3.12.3**.

| Fixture | Cases passed in each run | First compile + execute |
Validated compile + execute |
|---|---:|---:|---:|
| Write-back | 5 | 1.77 s | 1.52 s |
| Copy span | 1 | 0.87 s | 0.86 s |
| Offscreen aspect | 7 | 1.07 s | 0.97 s |

The validated result is **`3 passed, 0 failed, 0 skipped in 6.30 s
(lavapipe, validation on)`**.

No local lavapipe execution or validation-layer result is claimed for
these runs: the software ICD was absent when checked, and the Khronos
layer was unavailable to both local driver runs. No system packages were
installed for this work. The fork job supplies the lavapipe/validation
proof.

## Not tested

- No game or game-derived fixture data, full renderer startup/replay,
swapchain, display, HDR, DLSS or frame generation. The aspect fixture
still stubs filtered/HDR routing.
- No AMD/Steam Deck or Windows Vulkan execution. The new selector's
Windows syntax check is not a Windows device run.
- No frame-rate or hardware-performance comparison. Software Vulkan
cannot establish real-GPU correctness or speed.
- No extra synchronization-validation or GPU-assisted-validation
coverage is claimed; the job enables ordinary core validation.

## Risks

- An Ubuntu Mesa, LLVM or validation-layer update can change a result.
Versions and full error messages are kept so that a runner change can be
distinguished from a source change. Package versions are recorded, not
pinned to an apt revision that may disappear.
- One more concurrent job per source-check run. The two whole jobs took
26 and 23 seconds, below the approximately-one-minute target; later
runner/package changes can move that. The five-minute timeout is a
safety limit, not an expected duration.
- A renamed or additional fixture case requires updating the strict
expected-case list. A missing case must never look like a successful
run.

## Overlaps

- [#2807](https://github.com/NotRexed/Hookshot/pull/2807) is the
separate label-gated **self-hosted** hardware proposal. Its description,
review, proposed lint configuration and workflow test were read. This
change does not touch its files, register a runner or adopt its
game/sandbox path.
- The refreshed overlap check on the rebased branch found eight other
open PRs sharing these paths. Source-workflow hunks in https://github.com/NotRexed/Hookshot/pull/1025 (MCP
packages), https://github.com/NotRexed/Hookshot/pull/1872 (macOS checks), https://github.com/NotRexed/Hookshot/pull/2373 (Windows launcher tests) and
https://github.com/NotRexed/Hookshot/pull/2739 (.NET/launcher builds) were read; all four merge cleanly with this
branch. None adds this job.
- **Documentation conflict with https://github.com/NotRexed/Hookshot/pull/2561:** its rewrite removes the
contributor-guide testing section containing the new paragraph; the
actual conflict hunk was read. Keep the paragraph in its relocated
`docs/dev/testing.md` when the two changes meet. Other contributor-guide
hunks read: https://github.com/NotRexed/Hookshot/pull/2820's license list, https://github.com/NotRexed/Hookshot/pull/2317's data/cache paths, https://github.com/NotRexed/Hookshot/pull/2201's
version-policy guidance; https://github.com/NotRexed/Hookshot/pull/2274 also touches only the license list here.
- Arkex-ai's ASTC fixture from https://github.com/NotRexed/Hookshot/pull/2829 also passed a separate
lavapipe-with-validation trial today and is intended to join this job
after both changes merge; no ASTC code is included here.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra <[email protected]>

---------

Co-authored-by: GPT-6 Astra <[email protected]>
Co-authored-by: NotRexed <[email protected]>

Ported to Longshot: the job is in .forgejo/workflows/ci.yml and, like the other full checks there, runs when CI is
started by hand (workflow_dispatch), not on every push.

Restored-from: https://github.com/NotRexed/Hookshot/pull/2866
123 checks carry their own copy of a brace counter (`def block`) to cut
a function out of a source file. The copies count braces inside strings,
character literals and comments too, and when a function is renamed or
reshaped they stop with a bare `ValueError` or `IndexError` that doesn't
say which source or marker: the trap AGENTS.md warns about ("Tests read
the source"). This gives the checks one cutter and moves 80 of them to
it, each shown to cut exactly what it cut before. The dev-loop
proposal's D2 (https://github.com/NotRexed/Hookshot/pull/2636).

## Change

- **`tests/srccut.py` (new, standard library):**
- `block(text, marker)`: from the marker to the brace that closes the
first `{` after it, counting braces outside string and character
literals (raw strings too, and C++14 digit separators), comments and
preprocessor lines;
  - `between(text, start, end)`;
- a marker that is missing, or that appears twice, stops the check with
one message naming the source and the marker (`unique=False` takes the
first on purpose);
- `SRCCUT_CHECK_NAIVE=1` also cuts each block the old way and stops if
the two differ: what a migration runs to show it changed nothing.
- **80 checks import it** in place of their copy, one commit per source
file they read (`vk_menu.cpp`, `vk_draw.cpp`, `vk_memory.cpp`,
`vk_texture.cpp`, `hookshot_env.h`, `hos_main.c`, ...). Only exact
copies of the plain counter moved.
- **Not moved:**
- three checks whose `block` isn't the plain counter (a start offset;
positions returned): restored as they were;
- 13 checks whose marker appears more than once in the source (a
declaration before the definition, for example). The old counter took
the first one silently, so each needs a look rather than `unique=False`;
- 51 checks with other cutters (`function`, `body`, `between`, ...):
later, by source file.

## Testing

- **Every moved check, against today's `main`:** each run as `main` has
it and as moved with `SRCCUT_CHECK_NAIVE=1`, with its declared tools
(the Builder's clang, the Vulkan headers): **80 of 80 pass both ways**,
no cut differs.
- **`tests/test_srccut.py` (new):** braces in strings, character
literals, raw strings, comments and preprocessor lines; a fixture the
old counter cut wrongly; a missing marker and a repeated one name the
source; `between`; an unclosed block; the comparison with the old
counter.
- A follow-up after https://github.com/NotRexed/Hookshot/pull/2887: `run_all.py --changed` runs a test helper's
importers (srccut's) rather than every check.

See https://github.com/NotRexed/Hookshot/issues/2636 (D2).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Co-authored-by: NotRexed <[email protected]>

Ported to Longshot: test_builder_update_back.py and test_linux_update_skip.py are left out (Longshot removed them with
the Builder window, #181).

Restored-from: https://github.com/NotRexed/Hookshot/pull/2914
docs: the restored Hookshot references as full URLs
Some checks are pending
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Vulkan fixtures (lavapipe, validation) (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 4s
63584e064c
A bare #NNNN in Longshot's tree links to Longshot's own number. The restored
text's Hookshot pull requests and issues are written as
https://github.com/NotRexed/Hookshot/pull/NNNN (or /issues/NNNN).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Some checks are pending
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Vulkan fixtures (lavapipe, validation) (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 4s
This pull request is marked as a work in progress.
Some workflows are waiting to be reviewed.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'restore/tools-checks-docs:TrashPanda-restore/tools-checks-docs'
git switch 'TrashPanda-restore/tools-checks-docs'
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!284
No description provided.