fix(vk): Arc B580 no longer draws white shards while moving: a part ends only right before a plain draw #443

Open
nyannoying wants to merge 3 commits from nyannoying/Longshot:fix/part-begins-with-plain-draw into main
First-time contributor

Why

On an Intel Arc B580, Kokiri Forest shows white shards (exploded triangles over the ground, trees and Link) for single frames while you walk, in about 2% of the frames.

What changed

  • vk: a submission cut into parts (RX_VK_CHUNK, maybe_split() in gpu/vk/vk_replay.cpp) no longer ends a part right after its 120th draw or dispatch. maybe_split() asks for the end (part_end_wanted) and replay() makes it (split_part()) right before the next plain draw that will be recorded, so no cut leaves a part beginning with a mesh draw or a dispatch. part_ends_before_draw() decides it: on by default on Intel, RX_VK_SPLIT_BEFORE_DRAW either way elsewhere. The comment there has the cause and the numbers.
  • tests: tests/test_split_before_draw.py checks the request, the cut and its place in replay() (it fails on main). tests/test_split_ub_flush.py and tests/test_parallel_small_cb.py read the part's end in split_part() now.
  • docs: RX_VK_SPLIT_BEFORE_DRAW row in docs/development.md.

Flags and settings

Flag What it does Default now Recommendation Helps on Doesn't help on Untested on
RX_VK_SPLIT_BEFORE_DRAW=0/1 1: a part of a split submission ends only right before a plain draw; 0: after its 120th draw or dispatch, as before 1 on Intel GPUs; 0 elsewhere On by default on Intel Arc B580 (no white shards while moving, same frame rate) — Arc A-series, Intel iGPUs, Arc on Linux (Mesa); AMD and NVIDIA keep 0

What was found

  • The shards appear exactly when a command buffer begins with mesh draws: every plain draw after them in that command buffer is drawn as exploded triangles. With the default 120-draw parts the cut falls among the depth pre-pass's mesh draws, or on the culling dispatch before them, in about 2% of the frames.
  • A cut forced after that pass's first mesh draw (a debug switch, not in this PR) showed it in 333 of 335 frames. Leaving out only the new part's leading mesh draws: 0 of 324. Leaving out only its first plain draw: 340 of 342.
  • Ruled out with that forced cut: a race with the part before (the GPU waited for after every part, 1.5 ms each: 317 of 319), a state the replay keeps (all of a draw's state sent again before every draw: 319 of 328), the uniform data (what the draws were given was byte for byte the submission's own), the recording's stream (its first 64 KB left unused, and one 80 MB stream that never moves on: no change), the readback refresh, the late pages' fix, RX_VK_PROTECT_BARE=1, mirror syncs in later parts. The Khronos validation layer (1.4.363) names nothing, with or without a cut.
  • So this looks like a driver fault and not an error in the calls. A submission's own first recording can still begin with mesh draws, as the game sent it; no shards were seen from that.

Measurements

main: 5e072fc8 (2026-11-14)
this PR: fix/part-begins-with-plain-draw @ f3264534
Hardware: Intel Arc B580 12 GB, driver 32.0.101.9154; Core i5-13600K; 64 GB; Windows 11 Pro (26100-series Insider, 10.0.29704)
Scene: Kokiri Forest (child), a recorded 30 s walk from Link's balcony replayed through the control bridge (the same stick input every run); frame generation off
Method: the switch alternated run by run on one build. Three pairs with a screenshot of every presented frame the bridge could take (330-390 a run), each counted for white shards (pixels of 235+ in all channels below the top fifth of the picture, 2,000 or more) and the flagged ones looked at; then two pairs without screenshots for the frame rate, from the log's vi: ... frames presented (... fps over the last 5.0 s) lines.
How to reproduce: walk through Kokiri Forest for a minute on an Arc B580; RX_VK_SPLIT_BEFORE_DRAW=0 gives main's behaviour.

Baseline: this PR @ f3264534, RX_VK_SPLIT_BEFORE_DRAW=0 (main's path), which is main's code path. main itself was not the comparison because on the B580 it loses the device entering Kokiri Forest (the float atomic add loop; fixed in #444). The build that ran is this PR's change (f3264534, gpu/vk/vk_replay.cpp alone) applied to 4da0099b: main cf605c85 with three changes not merged yet, that float-add fix (3c8b0a99), the uniform snapshot on Arc discrete cards and XeSS (b46daa73). Both columns are that one build; only the switch differs. This PR's branch itself is on main 5e072fc8 and was not run in the game on this card for that reason; gpu/vk/vk_replay.cpp's change applies to both bases unchanged.

this PR @ f3264534, RX_VK_SPLIT_BEFORE_DRAW=0 (main's path) this PR @ f3264534 (default: 1 on Intel)
Frames with white shards, 3 runs each 40 of 1,121 (25 of 353, 6 of 390, 9 of 378) 0 of 1,101 (0 of 332, 0 of 387, 0 of 382)
fps, median of each run's 5 s windows 51.7, 48.2 54.6, 49.9
V1 off: 25 of 353   V2 on: 0 of 332   V3 off: 6 of 390   V4 on: 0 of 387   V5 off: 9 of 378   V6 on: 0 of 382
V7  off fps: 39.1 50.6 56.5 56.1 45.4 52.7
V8  on  fps: 38.0 52.7 56.4 56.6 44.6 57.9
V9  off fps: 38.2 46.6 53.0 53.7 48.0 48.3
V10 on  fps: 37.1 51.6 57.6 58.2 48.2 47.6

The first window of each run includes the walk's start, the fifth a turn against a tree; the frame rate is the same both ways.

Testing

Tested: Arc B580, 101.9154, Windows 11, Kokiri Forest: the runs above (ten files in docs/tested/), plus on a debug build of the same change the forced cut (0 of 324, against 333 of 335), a cut whose place steps through the submission frame by frame (0 of 326, against 5 full-screen frames in 980), and three more walks (0 of 1,134). Outside the forest, four more launches alternated the same way, each to Hyrule Field and the Market by the debug teleport with the walk's first 20 s in each: Hyrule Field 12 of 496 frames with shards with RX_VK_SPLIT_BEFORE_DRAW=0 (4 of 232, 8 of 264) against 0 of 496 with the default; the Market 1 of 236 (a broken frame right after the arrival, perhaps not this fault) against 0 of 156. No device loss in either. python -I -B tests/run_all.py: 486 passed, 6 failed, 70 skipped; the 6 are test_module_ids, test_pad_layout, test_tested_configurations, test_oot_state_tap, test_fpx_sticky and test_spawn_emit, which fail the same way on main 5e072fc8 here.

Not tested: areas other than Kokiri Forest, Hyrule Field and the Market (the Market's walks are partly a load, so it is thinly covered); other Intel GPUs; Linux, a Linux build included (no Linux compiler on this PC: the change adds two flags and a function in plain C++ with no platform call, and T-VQXE builds it there, so the template's two-platform box is left out, not ticked); long sessions; RX_VK_PARALLEL (off by default; the cut is refused there as before).

Needs other testers:

  • Arc A750/A770 and Intel iGPUs (Core Ultra), Windows: a walk through Kokiri Forest, expecting no white shards and no fps loss (T-GMJ7)
  • Any Intel GPU on Linux (Mesa): the same, to see whether the open driver shows the fault at all with RX_VK_SPLIT_BEFORE_DRAW=0 (T-VQXE)

Screenshots

Kokiri Forest while walking, Arc B580: posted in the first comment (frames with shards from a run with RX_VK_SPLIT_BEFORE_DRAW=0).

Risk and rollback

Only Intel GPUs change by default. A part can run a few draws past 120 until a plain draw comes, and a run of mesh draws or dispatches with no plain draw in it is not cut; the frame rate measured the same. RX_VK_SPLIT_BEFORE_DRAW=0 turns it off; reverting the commit is enough.

Reviewer notes

  • The fault is the driver's as far as these tests can say, so the change avoids the pattern rather than fixing a cause in the replay. If someone knows a state a mesh pipeline leaves behind at the start of a command buffer on Intel, that would be the better fix.
  • A plain draw that draw() then leaves out (no targets, a program not ready) still begins the part; exactness there would need draw() to say whether it recorded. Not done without a measurement that needs it.
  • RX_VK_CHUNK=100000 (no parts) is also clean on this card, at 26-41 fps against 54-59.
  • #397 reports missing geometry faces on an Arc A750 on Windows; whether that is this fault is not known, hence the test request for Alchemist cards.

Issues

None filed yet for the shards.

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.
  • 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.
  • Flags noted, and the switch reference updated (docs/development.md, the README).
  • Screenshots for a change that shows on screen.
  • A file in docs/tested/ for each new measured run (format in docs/tested-configurations.md; no appended row or assembled view).
  • 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.
  • Docs updated.

🤖 Generated with Claude Code

## Why On an Intel Arc B580, Kokiri Forest shows white shards (exploded triangles over the ground, trees and Link) for single frames while you walk, in about 2% of the frames. ## What changed - vk: a submission cut into parts (`RX_VK_CHUNK`, `maybe_split()` in `gpu/vk/vk_replay.cpp`) no longer ends a part right after its 120th draw or dispatch. `maybe_split()` asks for the end (`part_end_wanted`) and `replay()` makes it (`split_part()`) right before the next plain draw that will be recorded, so no cut leaves a part beginning with a mesh draw or a dispatch. `part_ends_before_draw()` decides it: on by default on Intel, `RX_VK_SPLIT_BEFORE_DRAW` either way elsewhere. The comment there has the cause and the numbers. - tests: `tests/test_split_before_draw.py` checks the request, the cut and its place in `replay()` (it fails on `main`). `tests/test_split_ub_flush.py` and `tests/test_parallel_small_cb.py` read the part's end in `split_part()` now. - docs: `RX_VK_SPLIT_BEFORE_DRAW` row in `docs/development.md`. ## Flags and settings | Flag | What it does | Default now | Recommendation | Helps on | Doesn't help on | Untested on | |---|---|---|---|---|---|---| | `RX_VK_SPLIT_BEFORE_DRAW=0/1` | 1: a part of a split submission ends only right before a plain draw; 0: after its 120th draw or dispatch, as before | 1 on Intel GPUs; 0 elsewhere | On by default on Intel | Arc B580 (no white shards while moving, same frame rate) | — | Arc A-series, Intel iGPUs, Arc on Linux (Mesa); AMD and NVIDIA keep 0 | ## What was found - The shards appear exactly when a command buffer begins with mesh draws: every plain draw after them in that command buffer is drawn as exploded triangles. With the default 120-draw parts the cut falls among the depth pre-pass's mesh draws, or on the culling dispatch before them, in about 2% of the frames. - A cut forced after that pass's first mesh draw (a debug switch, not in this PR) showed it in 333 of 335 frames. Leaving out only the new part's leading mesh draws: 0 of 324. Leaving out only its first plain draw: 340 of 342. - Ruled out with that forced cut: a race with the part before (the GPU waited for after every part, 1.5 ms each: 317 of 319), a state the replay keeps (all of a draw's state sent again before every draw: 319 of 328), the uniform data (what the draws were given was byte for byte the submission's own), the recording's stream (its first 64 KB left unused, and one 80 MB stream that never moves on: no change), the readback refresh, the late pages' fix, `RX_VK_PROTECT_BARE=1`, mirror syncs in later parts. The Khronos validation layer (1.4.363) names nothing, with or without a cut. - So this looks like a driver fault and not an error in the calls. A submission's own first recording can still begin with mesh draws, as the game sent it; no shards were seen from that. ## Measurements main: 5e072fc8 (2026-11-14) this PR: fix/part-begins-with-plain-draw @ f3264534 Hardware: Intel Arc B580 12 GB, driver 32.0.101.9154; Core i5-13600K; 64 GB; Windows 11 Pro (26100-series Insider, 10.0.29704) Scene: Kokiri Forest (child), a recorded 30 s walk from Link's balcony replayed through the control bridge (the same stick input every run); frame generation off Method: the switch alternated run by run on one build. Three pairs with a screenshot of every presented frame the bridge could take (330-390 a run), each counted for white shards (pixels of 235+ in all channels below the top fifth of the picture, 2,000 or more) and the flagged ones looked at; then two pairs without screenshots for the frame rate, from the log's `vi: ... frames presented (... fps over the last 5.0 s)` lines. How to reproduce: walk through Kokiri Forest for a minute on an Arc B580; `RX_VK_SPLIT_BEFORE_DRAW=0` gives main's behaviour. Baseline: this PR @ f3264534, `RX_VK_SPLIT_BEFORE_DRAW=0` (main's path), which is main's code path. main itself was not the comparison because on the B580 it loses the device entering Kokiri Forest (the float atomic add loop; fixed in https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/444). The build that ran is this PR's change (f3264534, `gpu/vk/vk_replay.cpp` alone) applied to 4da0099b: main cf605c85 with three changes not merged yet, that float-add fix (3c8b0a99), the uniform snapshot on Arc discrete cards and XeSS (b46daa73). Both columns are that one build; only the switch differs. This PR's branch itself is on main 5e072fc8 and was not run in the game on this card for that reason; `gpu/vk/vk_replay.cpp`'s change applies to both bases unchanged. | | this PR @ f3264534, `RX_VK_SPLIT_BEFORE_DRAW=0` (main's path) | this PR @ f3264534 (default: 1 on Intel) | |---|---|---| | Frames with white shards, 3 runs each | 40 of 1,121 (25 of 353, 6 of 390, 9 of 378) | 0 of 1,101 (0 of 332, 0 of 387, 0 of 382) | | fps, median of each run's 5 s windows | 51.7, 48.2 | 54.6, 49.9 | ``` V1 off: 25 of 353 V2 on: 0 of 332 V3 off: 6 of 390 V4 on: 0 of 387 V5 off: 9 of 378 V6 on: 0 of 382 V7 off fps: 39.1 50.6 56.5 56.1 45.4 52.7 V8 on fps: 38.0 52.7 56.4 56.6 44.6 57.9 V9 off fps: 38.2 46.6 53.0 53.7 48.0 48.3 V10 on fps: 37.1 51.6 57.6 58.2 48.2 47.6 ``` The first window of each run includes the walk's start, the fifth a turn against a tree; the frame rate is the same both ways. ## Testing **Tested:** Arc B580, 101.9154, Windows 11, Kokiri Forest: the runs above (ten files in `docs/tested/`), plus on a debug build of the same change the forced cut (0 of 324, against 333 of 335), a cut whose place steps through the submission frame by frame (0 of 326, against 5 full-screen frames in 980), and three more walks (0 of 1,134). Outside the forest, four more launches alternated the same way, each to Hyrule Field and the Market by the debug teleport with the walk's first 20 s in each: Hyrule Field 12 of 496 frames with shards with `RX_VK_SPLIT_BEFORE_DRAW=0` (4 of 232, 8 of 264) against 0 of 496 with the default; the Market 1 of 236 (a broken frame right after the arrival, perhaps not this fault) against 0 of 156. No device loss in either. `python -I -B tests/run_all.py`: 486 passed, 6 failed, 70 skipped; the 6 are `test_module_ids`, `test_pad_layout`, `test_tested_configurations`, `test_oot_state_tap`, `test_fpx_sticky` and `test_spawn_emit`, which fail the same way on main 5e072fc8 here. **Not tested:** areas other than Kokiri Forest, Hyrule Field and the Market (the Market's walks are partly a load, so it is thinly covered); other Intel GPUs; Linux, a Linux build included (no Linux compiler on this PC: the change adds two flags and a function in plain C++ with no platform call, and T-VQXE builds it there, so the template's two-platform box is left out, not ticked); long sessions; `RX_VK_PARALLEL` (off by default; the cut is refused there as before). **Needs other testers:** - Arc A750/A770 and Intel iGPUs (Core Ultra), Windows: a walk through Kokiri Forest, expecting no white shards and no fps loss (T-GMJ7) - Any Intel GPU on Linux (Mesa): the same, to see whether the open driver shows the fault at all with `RX_VK_SPLIT_BEFORE_DRAW=0` (T-VQXE) ## Screenshots Kokiri Forest while walking, Arc B580: posted in the first comment (frames with shards from a run with `RX_VK_SPLIT_BEFORE_DRAW=0`). ## Risk and rollback Only Intel GPUs change by default. A part can run a few draws past 120 until a plain draw comes, and a run of mesh draws or dispatches with no plain draw in it is not cut; the frame rate measured the same. `RX_VK_SPLIT_BEFORE_DRAW=0` turns it off; reverting the commit is enough. ## Reviewer notes - The fault is the driver's as far as these tests can say, so the change avoids the pattern rather than fixing a cause in the replay. If someone knows a state a mesh pipeline leaves behind at the start of a command buffer on Intel, that would be the better fix. - A plain draw that `draw()` then leaves out (no targets, a program not ready) still begins the part; exactness there would need `draw()` to say whether it recorded. Not done without a measurement that needs it. - `RX_VK_CHUNK=100000` (no parts) is also clean on this card, at 26-41 fps against 54-59. - https://git.magicbean.dev/MagicBeanDev/Longshot/issues/397 reports missing geometry faces on an Arc A750 on Windows; whether that is this fault is not known, hence the test request for Alchemist cards. ## Issues None filed yet for the shards. ## 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. - [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] Flags noted, and the switch reference updated (docs/development.md, the README). - [x] Screenshots for a change that shows on screen. - [x] A file in `docs/tested/` for each new measured run (format in `docs/tested-configurations.md`; no appended row or assembled view). - [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] Docs updated. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A submission is cut into parts every 120 draws and dispatches (RX_VK_CHUNK, maybe_split). On an Intel Arc B580 (Windows,
driver 32.0.101.9154, native mesh shaders) a command buffer that begins with mesh draws drew every plain draw after them
as exploded triangles: white shards over Kokiri Forest while moving, in about 2% of the frames, whenever the cut fell
among the depth pre-pass's mesh draws or on the culling dispatch before them. A cut forced there showed it in 333 of 335
frames; with only the new part's leading mesh draws left out, 0 of 324. It is not a race, not a state the replay keeps,
and the validation layer names nothing.

maybe_split now only asks for the part's end (part_end_wanted), and replay() makes it (split_part) right before the next
plain draw that will be recorded, so no cut leaves a part beginning with a mesh draw or a dispatch. On by default on
Intel, where it was measured: 0 of 1,101 frames against 40 of 1,121 over six alternated walks, at the same frame rate.
RX_VK_SPLIT_BEFORE_DRAW=1 turns it on elsewhere, =0 off.

tests/test_split_before_draw.py checks the request, the cut and its place in replay(); test_split_ub_flush.py and
test_parallel_small_cb.py read the part's end in split_part now.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
docs(tested): the split-before-draw runs on an Arc B580, ten files
Some checks failed
Website / Website on Cloudflare (pull_request_target) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 5s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
Website / Website on Cloudflare (pull_request) Has been cancelled
8ecee6d4b5
Co-Authored-By: Claude Fable 5.2 <[email protected]>
Author
First-time contributor

Kokiri Forest while walking, Arc B580 (101.9154): twelve of the 25 frames with white shards in run V1 of the Measurements (353 frames, RX_VK_SPLIT_BEFORE_DRAW=0, main's path). The same walk with the default showed none in 1,101 frames, so there is no picture of that side beyond an ordinary frame.

this PR @ f3264534, RX_VK_SPLIT_BEFORE_DRAW=0 (main's path)

Kokiri Forest while walking, Arc B580 (101.9154): twelve of the 25 frames with white shards in run V1 of the Measurements (353 frames, `RX_VK_SPLIT_BEFORE_DRAW=0`, main's path). The same walk with the default showed none in 1,101 frames, so there is no picture of that side beyond an ordinary frame. ![this PR @ f3264534, RX_VK_SPLIT_BEFORE_DRAW=0 (main's path)](https://git.magicbean.dev/attachments/52605cc0-870c-4aa8-a6e4-56166c7bf40d)
Author
First-time contributor

The two test requests are open (T-GMJ7: Arc A-series or an Intel iGPU on Windows; T-VQXE: any Intel GPU on Linux) and named in the description. Both wait for a maintainer's testing wanted label.

The two test requests are open (T-GMJ7: Arc A-series or an Intel iGPU on Windows; T-VQXE: any Intel GPU on Linux) and named in the description. Both wait for a maintainer's testing wanted label.
nyannoying changed title from WIP: fix(vk): Arc B580 no longer draws white shards while moving: a part ends only right before a plain draw to fix(vk): Arc B580 no longer draws white shards while moving: a part ends only right before a plain draw 2026-11-14 14:10:37 +00:00
Author
First-time contributor

Description: the box for the two updated checks (test_split_ub_flush.py, test_parallel_small_cb.py, both extended, neither weakened) added and ticked; a Linux build named under Not tested, since this PC has no Linux compiler.

Description: the box for the two updated checks (test_split_ub_flush.py, test_parallel_small_cb.py, both extended, neither weakened) added and ticked; a Linux build named under Not tested, since this PC has no Linux compiler.
Author
First-time contributor

The float-add fix this was measured on top of is open now: #444. A B580 needs it to reach Kokiri Forest at all, so a tester on that card wants both.

The float-add fix this was measured on top of is open now: https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/444. A B580 needs it to reach Kokiri Forest at all, so a tester on that card wants both.
Author
First-time contributor

New runs outside the forest (four launches, the switch alternated; four more files in docs/tested/, the description's Testing updated): Hyrule Field shows the same shards on main's path, 12 of 496 frames, and none with the default, 0 of 496. The Market: 1 of 236 against 0 of 156; its one flagged frame is a broken frame right after the arrival and may be something else. No device loss in either area.

this PR @ f3264534, RX_VK_SPLIT_BEFORE_DRAW=0 (main's path): the eight flagged frames of run A3 in Hyrule Field

this PR @ f3264534 (default: 1 on Intel): a frame of run A4 in Hyrule Field

New runs outside the forest (four launches, the switch alternated; four more files in `docs/tested/`, the description's Testing updated): Hyrule Field shows the same shards on main's path, 12 of 496 frames, and none with the default, 0 of 496. The Market: 1 of 236 against 0 of 156; its one flagged frame is a broken frame right after the arrival and may be something else. No device loss in either area. ![this PR @ f3264534, RX_VK_SPLIT_BEFORE_DRAW=0 (main's path): the eight flagged frames of run A3 in Hyrule Field](https://git.magicbean.dev/attachments/aea1896f-4ab7-41fc-96eb-e99956785903) ![this PR @ f3264534 (default: 1 on Intel): a frame of run A4 in Hyrule Field](https://git.magicbean.dev/attachments/a3a1411e-736e-440e-b303-7ba3d99cc4d4)
docs(tested): the split-before-draw runs in Hyrule Field and the Market, four files
Some checks are pending
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 / Workflow lint (actionlint) (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
Website / Website on Cloudflare (pull_request) Blocked by required conditions
Website / Website on Cloudflare (pull_request_target) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 4s
c8201e51d9
Co-Authored-By: Claude Fable 5.2 <[email protected]>
Member

Test request T-GMJ7: mixed

Hardware: Intel Arc Graphics (the integrated GPU of a Core Ultra 9 185H laptop, shared memory), driver 32.0.101.9175, Windows 11 Pro 10.0.26300, 64 GB RAM.
Built 8ecee6d4b5, this pull request's head when I started (its base then was 5e072fc8c2), as one Windows build used for every run. The game's own log names it v3.0.0-rc.3-66-g8ecee6d4b (source 97178958).
What I checked: ten game runs of that one build in Kokiri Forest, alternating the switch: RX_VK_SPLIT_BEFORE_DRAW=0 (main's path) and RX_VK_SPLIT_BEFORE_DRAW=1 (this pull request's path, the default on Intel). Nothing else differed. Every run started from the same autosave outdoors (the game wrote it after Link left the house; no save file was edited) and played the same 50 second input sequence: walking and turning on the paths between the houses, with camera centering off so the views stay comparable. Output 1280x720 in a window, frame generation off, no co-op, no audio.
The shader caches were filled first by twelve warm-up runs (several were rejected for reasons that have nothing to do with this pull request, for example a cold first start that my own freshness check stopped after a one-second stall, and a route that began at the house door instead of outdoors; none of them is in the tables), then saved and put back in the same state before every run, so the walks are not spent compiling. One program (the same one each time) was still translated for the first time during the walk in three of the ten runs, V2, f2 and f3, taking 18 to 22 ms; that happened with both switch values.
Six runs, V1 to V6 (switch 0, 1, 0, 1, 0, 1), were for shards: during each walk the game took a picture of every frame it could, through its control bridge as in the pull request's description. That is just over half of the frames it presented. Each picture was counted with the description's rule (235 or more in red, green and blue, below the top fifth of the picture, 2,000 or more such pixels). I looked at every flagged picture, and at seven unflagged pictures from each run spread across the walk (42 in all).
Four more runs, f1 to f4 (switch 0, 1, 0, 1), were for the frame rate: no pictures during the walk, one after it, and the game's own vi: ... frames presented (... fps over the last 5 s) lines read for the ten 5 second windows of the walk.
Result, shards:

Run Switch value Pictures taken during the walk Flagged by the white-pixel rule Frames with shards after looking Game exit
V1 0 322 0 0 0
V2 1 339 0 0 0
V3 0 311 0 0 0
V4 1 328 0 0 0
V5 0 322 0 0 0
V6 1 325 0 0 0
all, switch 0 0 955 0 0
all, switch 1 1 992 0 0
  • White shards: none in either column. The highest white-pixel count in any of the 1,947 walking pictures is 8, against the limit of 2,000. For scale, the twelve frames in the first comment on this pull request come to between 56,000 and 223,000 on the same measure (their picture scaled to 1280x720 by area).
  • Ten pictures were flagged over the six runs, none of them taken during a walk: the title screen (the logo's glow) and the load menu (the white border of the selected entry), both shown before the walk starts. I looked at all ten and none shows exploded triangles. The four frame-rate runs took no pictures during their walks; the one picture each took after the walk shows the forest with no white at all (0 flagged pixels).
  • The fault did not show up here with the old behaviour either. The description counts 40 frames with shards in 1,121 with the switch at 0 on an Arc B580 (3.6%). The same rate over my 955 pictures with the switch at 0 would be about 34 frames, and I saw none. So these runs cannot show that the change fixes anything on this GPU. They show that nothing white appears with the switch on (the Intel default), and that it did not appear with the old path on this walk either.

Result, frame rate (the four picture-free runs):

Run Switch value Game exit Median of the ten 5 s readings (fps) Mean over the 50 s walk (frames shown / seconds) Slowest and fastest 5 s reading
f1 0 0 11.85 11.63 9.2 and 14.1
f2 1 0 14.05 13.86 11.8 and 15.3
f3 0 0 14.05 14.38 12.1 and 16.5
f4 1 0 13.10 13.57 12.1 and 16.4
  • Switch 0 (f1, f3): medians 11.85 and 14.05, so the two runs of the same switch differ by 2.20 fps (17%); mean of the two 12.95. Switch 1 (f2, f4): medians 14.05 and 13.10, differing by 0.95 fps (7%); mean 13.58.
  • Is the difference between the switches beyond the spread between two runs of the same switch? No. Switch 1 was not slower: its mean is 0.63 fps (4.8%) higher, which is well inside the 2.20 fps between the two switch-0 runs, and the ranges overlap. The mean over the whole walk says the same (13.0 for switch 0, 13.7 for switch 1; 0.71 fps higher, spreads 2.75 and 0.29). The slowest 5 second reading was 9.2 fps with switch 0 and 11.8 with switch 1. The game prints only 5 second averages and I recorded no per-frame times, so there is no 1% low.
  • This is a small sample: two runs per switch, and the two switch-0 runs differ by 17%, far more than the 5% I would want between repeats for a clean comparison, and the walks end in slightly different places because the game's physics runs in real time. So a loss smaller than about 2 fps (15%) could not have been seen. If the slowest run, f1, is left out, switch 0 is 14.05 against 13.58 for switch 1, which is 0.47 fps (3%) the other way, still inside the 0.95 fps between the two switch-1 runs. The six picture-taking runs read 12.05 to 13.15 (median of their 5 second readings), in the same range. In this scene the game runs at about 12 to 14 frames per second on this GPU with either switch value.
  • All ten runs ended by themselves with exit code 0, no forced stop, and no crash, fatal or device-lost line in the log. Every run, with either switch value, also logs two "a capture's wait for write-back ... timed out" lines (three in f1) while the save loads, before the walk, with or without pictures; nothing else unusual.
  • Tested commit: 8ecee6d4b5. The pull request's current head, c8201e51d9, adds only run records under docs/tested; I compared the two by the public diff (the changed lines of every code and test file are identical), so this result carries to it. I did not run that head itself.
  • Why mixed rather than pass: no shards with either setting, and no frame-rate loss, but the fault never showed with the old setting on this GPU either, and the two runs of the same setting differ by 17%, too much for a clean frame-rate comparison.
  • Picture 1 (below): the top row is V5 (switch 0), the bottom row is V6 (switch 1), at 0, 22, 41 and 51 seconds into the walk. Look for white exploded triangles over the ground, the trees and Link: there are none in either row.

Not tested: an Arc discrete card (A-series or B-series) or any other Intel GPU; Linux with Mesa (T-VQXE); frame generation (off in every run); other places than this Kokiri Forest walk (Hyrule Field, the Market) and walks longer than 50 seconds; shards during the four frame-rate walks (no pictures were taken during them); a larger frame-rate sample than two runs per switch; what the laptop's screen showed, because the pictures are the game's own captures and a shard that appeared only on screen and not in the capture would not be seen.

Kokiri Forest on Intel Arc Graphics, Windows: V5 with RX_VK_SPLIT_BEFORE_DRAW=0 (top) and V6 with RX_VK_SPLIT_BEFORE_DRAW=1 (bottom) at the same moments of the walk; no white exploded triangles in either row

Test request T-GMJ7: mixed Hardware: Intel Arc Graphics (the integrated GPU of a Core Ultra 9 185H laptop, shared memory), driver 32.0.101.9175, Windows 11 Pro 10.0.26300, 64 GB RAM. Built 8ecee6d4b588a2ab4c3f8bef629800c162d3ca81, this pull request's head when I started (its base then was 5e072fc8c2adadba5ea610148be1c47800ba0cca), as one Windows build used for every run. The game's own log names it v3.0.0-rc.3-66-g8ecee6d4b (source 97178958). What I checked: ten game runs of that one build in Kokiri Forest, alternating the switch: `RX_VK_SPLIT_BEFORE_DRAW=0` (main's path) and `RX_VK_SPLIT_BEFORE_DRAW=1` (this pull request's path, the default on Intel). Nothing else differed. Every run started from the same autosave outdoors (the game wrote it after Link left the house; no save file was edited) and played the same 50 second input sequence: walking and turning on the paths between the houses, with camera centering off so the views stay comparable. Output 1280x720 in a window, frame generation off, no co-op, no audio. The shader caches were filled first by twelve warm-up runs (several were rejected for reasons that have nothing to do with this pull request, for example a cold first start that my own freshness check stopped after a one-second stall, and a route that began at the house door instead of outdoors; none of them is in the tables), then saved and put back in the same state before every run, so the walks are not spent compiling. One program (the same one each time) was still translated for the first time during the walk in three of the ten runs, V2, f2 and f3, taking 18 to 22 ms; that happened with both switch values. Six runs, V1 to V6 (switch 0, 1, 0, 1, 0, 1), were for shards: during each walk the game took a picture of every frame it could, through its control bridge as in the pull request's description. That is just over half of the frames it presented. Each picture was counted with the description's rule (235 or more in red, green and blue, below the top fifth of the picture, 2,000 or more such pixels). I looked at every flagged picture, and at seven unflagged pictures from each run spread across the walk (42 in all). Four more runs, f1 to f4 (switch 0, 1, 0, 1), were for the frame rate: no pictures during the walk, one after it, and the game's own `vi: ... frames presented (... fps over the last 5 s)` lines read for the ten 5 second windows of the walk. Result, shards: | Run | Switch value | Pictures taken during the walk | Flagged by the white-pixel rule | Frames with shards after looking | Game exit | |---|---|---|---|---|---| | V1 | 0 | 322 | 0 | 0 | 0 | | V2 | 1 | 339 | 0 | 0 | 0 | | V3 | 0 | 311 | 0 | 0 | 0 | | V4 | 1 | 328 | 0 | 0 | 0 | | V5 | 0 | 322 | 0 | 0 | 0 | | V6 | 1 | 325 | 0 | 0 | 0 | | all, switch 0 | 0 | 955 | 0 | 0 | | | all, switch 1 | 1 | 992 | 0 | 0 | | - White shards: none in either column. The highest white-pixel count in any of the 1,947 walking pictures is 8, against the limit of 2,000. For scale, the twelve frames in the first comment on this pull request come to between 56,000 and 223,000 on the same measure (their picture scaled to 1280x720 by area). - Ten pictures were flagged over the six runs, none of them taken during a walk: the title screen (the logo's glow) and the load menu (the white border of the selected entry), both shown before the walk starts. I looked at all ten and none shows exploded triangles. The four frame-rate runs took no pictures during their walks; the one picture each took after the walk shows the forest with no white at all (0 flagged pixels). - The fault did not show up here with the old behaviour either. The description counts 40 frames with shards in 1,121 with the switch at 0 on an Arc B580 (3.6%). The same rate over my 955 pictures with the switch at 0 would be about 34 frames, and I saw none. So these runs cannot show that the change fixes anything on this GPU. They show that nothing white appears with the switch on (the Intel default), and that it did not appear with the old path on this walk either. Result, frame rate (the four picture-free runs): | Run | Switch value | Game exit | Median of the ten 5 s readings (fps) | Mean over the 50 s walk (frames shown / seconds) | Slowest and fastest 5 s reading | |---|---|---|---|---|---| | f1 | 0 | 0 | 11.85 | 11.63 | 9.2 and 14.1 | | f2 | 1 | 0 | 14.05 | 13.86 | 11.8 and 15.3 | | f3 | 0 | 0 | 14.05 | 14.38 | 12.1 and 16.5 | | f4 | 1 | 0 | 13.10 | 13.57 | 12.1 and 16.4 | - Switch 0 (f1, f3): medians 11.85 and 14.05, so the two runs of the same switch differ by 2.20 fps (17%); mean of the two 12.95. Switch 1 (f2, f4): medians 14.05 and 13.10, differing by 0.95 fps (7%); mean 13.58. - Is the difference between the switches beyond the spread between two runs of the same switch? No. Switch 1 was not slower: its mean is 0.63 fps (4.8%) higher, which is well inside the 2.20 fps between the two switch-0 runs, and the ranges overlap. The mean over the whole walk says the same (13.0 for switch 0, 13.7 for switch 1; 0.71 fps higher, spreads 2.75 and 0.29). The slowest 5 second reading was 9.2 fps with switch 0 and 11.8 with switch 1. The game prints only 5 second averages and I recorded no per-frame times, so there is no 1% low. - This is a small sample: two runs per switch, and the two switch-0 runs differ by 17%, far more than the 5% I would want between repeats for a clean comparison, and the walks end in slightly different places because the game's physics runs in real time. So a loss smaller than about 2 fps (15%) could not have been seen. If the slowest run, f1, is left out, switch 0 is 14.05 against 13.58 for switch 1, which is 0.47 fps (3%) the other way, still inside the 0.95 fps between the two switch-1 runs. The six picture-taking runs read 12.05 to 13.15 (median of their 5 second readings), in the same range. In this scene the game runs at about 12 to 14 frames per second on this GPU with either switch value. - All ten runs ended by themselves with exit code 0, no forced stop, and no crash, fatal or device-lost line in the log. Every run, with either switch value, also logs two "a capture's wait for write-back ... timed out" lines (three in f1) while the save loads, before the walk, with or without pictures; nothing else unusual. - Tested commit: 8ecee6d4b588a2ab4c3f8bef629800c162d3ca81. The pull request's current head, c8201e51d938748e67ef1988c7d76424681a3005, adds only run records under docs/tested; I compared the two by the public diff (the changed lines of every code and test file are identical), so this result carries to it. I did not run that head itself. - Why mixed rather than pass: no shards with either setting, and no frame-rate loss, but the fault never showed with the old setting on this GPU either, and the two runs of the same setting differ by 17%, too much for a clean frame-rate comparison. - Picture 1 (below): the top row is V5 (switch 0), the bottom row is V6 (switch 1), at 0, 22, 41 and 51 seconds into the walk. Look for white exploded triangles over the ground, the trees and Link: there are none in either row. Not tested: an Arc discrete card (A-series or B-series) or any other Intel GPU; Linux with Mesa (T-VQXE); frame generation (off in every run); other places than this Kokiri Forest walk (Hyrule Field, the Market) and walks longer than 50 seconds; shards during the four frame-rate walks (no pictures were taken during them); a larger frame-rate sample than two runs per switch; what the laptop's screen showed, because the pictures are the game's own captures and a shard that appeared only on screen and not in the capture would not be seen. ![Kokiri Forest on Intel Arc Graphics, Windows: V5 with RX_VK_SPLIT_BEFORE_DRAW=0 (top) and V6 with RX_VK_SPLIT_BEFORE_DRAW=1 (bottom) at the same moments of the walk; no white exploded triangles in either row](https://git.magicbean.dev/attachments/7922c3a3-2309-4ac6-af11-980f268a5cc0)
Some checks are pending
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 / Workflow lint (actionlint) (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
Website / Website on Cloudflare (pull_request) Blocked by required conditions
Website / Website on Cloudflare (pull_request_target) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 4s
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
Some workflows are waiting to be reviewed.
This branch is out-of-date with the base branch
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/part-begins-with-plain-draw:nyannoying-fix/part-begins-with-plain-draw'
git switch 'nyannoying-fix/part-begins-with-plain-draw'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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!443
No description provided.