Initialize parallel segments' new images before their first use #1108

Merged
klimovich008 merged 4 commits from parallel-segment-init-order into main 2026-11-09 15:15:28 +00:00
klimovich008 commented 2026-11-09 11:40:35 +00:00 (Migrated from github.com)

What this fixes

With RX_VK_PARALLEL, a new image's first layout change (UNDEFINED → GENERAL plus its zero clear) went into the upload command buffer of whichever segment worker created it. An earlier segment is submitted first and could already use that image (a re-upload copy or an ASTC/BC3 dispatch) while it was still UNDEFINED (VUID-vkCmdDraw-None-09600). The BC3 scratches' first transitions had the same race.

Why merge

  • Removes a stream of parallel-only validation errors.
  • The GPU no longer writes into images whose layout was never set.
  • The parallel replay stays opt-in and the serial path is unchanged.

Change

  • gpu/vk/vk_texture.cpp
  • gpu/vk/vk_texture.h
  • gpu/vk/vk_replay.cpp
  • tests/test_parallel_init_order.py
  • tests/parallel_init_order_test.cpp
  • tests/run_all.py

How it works:

  • Each segment gets an init command buffer, submitted as [init_k, upload_k, cmd_k].
  • An image created on a worker gets its transition in the lowest-index segment still recording.
  • Begin failure: no worker starts, and the command buffer is recorded in order on the replay thread.
  • End failure: the replay waits for its workers, logs, and exits with code 3.

Tested

python -I -B tests/test_parallel_init_order.py --cxx clang++ --headers <Vulkan-Headers include>

Fails on the old code, passes now. On an RX 9070 XT, v2.0.6 plus #1069, validation limit off: 14,151× 09600 → 0, serial 0. The known 04965 shader messages are unrelated and unchanged.

Not covered

  • Hardware checks used v2.0.6 plus #1069, not a current-main binary; the failure paths are tested only with fake Vulkan.
  • An init-end out-of-memory failure now ends the game instead of continuing with invalid GPU state.

🤖 Generated with Claude Code

## What this fixes With `RX_VK_PARALLEL`, a new image's first layout change (UNDEFINED → GENERAL plus its zero clear) went into the upload command buffer of whichever segment worker created it. An earlier segment is submitted first and could already use that image (a re-upload copy or an ASTC/BC3 dispatch) while it was still UNDEFINED (VUID-vkCmdDraw-None-09600). The BC3 scratches' first transitions had the same race. ## Why merge - Removes a stream of parallel-only validation errors. - The GPU no longer writes into images whose layout was never set. - The parallel replay stays opt-in and the serial path is unchanged. ## Change - `gpu/vk/vk_texture.cpp` - `gpu/vk/vk_texture.h` - `gpu/vk/vk_replay.cpp` - `tests/test_parallel_init_order.py` - `tests/parallel_init_order_test.cpp` - `tests/run_all.py` How it works: - Each segment gets an init command buffer, submitted as [init_k, upload_k, cmd_k]. - An image created on a worker gets its transition in the lowest-index segment still recording. - **Begin failure:** no worker starts, and the command buffer is recorded in order on the replay thread. - **End failure:** the replay waits for its workers, logs, and exits with code 3. ## Tested `python -I -B tests/test_parallel_init_order.py --cxx clang++ --headers <Vulkan-Headers include>` Fails on the old code, passes now. On an RX 9070 XT, v2.0.6 plus #1069, validation limit off: 14,151× 09600 → 0, serial 0. The known 04965 shader messages are unrelated and unchanged. ## Not covered - Hardware checks used v2.0.6 plus #1069, not a current-main binary; the failure paths are tested only with fake Vulkan. - An init-end out-of-memory failure now ends the game instead of continuing with invalid GPU state. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Commenting is not possible because the repository is archived.
No description provided.