Repository navigation
perf(vk): build Intel compute programs that cannot see their lanes without the 32-lane pin - #2564
thomas-montano wants to merge 1 commit into
Conversation
ea34279 to
d238ae0
Compare
…thout the 32-lane pin On an Iris Xe a game compute program's first build took 5-26 s at 32 lanes, one at a time, while the effects it draws stayed missing. NVN's programs are translated for 32 lanes and every compute stage is pinned to that size, which Mesa's compiler for Intel GPUs builds slowly (register allocation at SIMD32). A program whose SPIR-V declares no subgroup capability (GroupNonUniform*, the KHR ballot and vote, Groups, cooperative matrices) does the same at any lane count, so on Intel it is now built without the pin and the driver picks its width (spirv_uses_subgroups, Stage::subgroups, pin_compute). One with shared memory and at most 32 invocations keeps the pin: NVIDIA's compiler may drop the barriers a single-warp workgroup does not need. The networks and the mesh fallback's programs use subgroup operations and stay pinned. RX_VK_PIN_ALL=1 pins every program as before; =0 does this on any GPU. Tested on an Iris Xe (Mesa ANV 26.2.4), headless at the Deku Tree, with the serial queue's escape: 9790303532c0c309, 76b54f5bb0d7ce97, 37d9fd3069f0e5e4 and 0fe7f6c474c57be5 built in under 0.2 s each against 5.5, 26.4, 14.7 and 14.5 s pinned; the picture and the frame rate are the same as with RX_VK_PIN_ALL=1 (9.2 against 9.1 fps). tests/test_compute_pin.py checks the scan, the decision and that every game compute pipeline goes through pin_compute; tests/test_program_cache_cleanup.py compiles the scan with the cache loader. Not tested: other Intel GPUs, Windows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d238ae0 to
1ef2a29
Compare
Joey-Magnus
left a comment
There was a problem hiding this comment.
I merged this into current main. tests/test_compute_pin.py, test_program_cache_cleanup.py and test_env_on.py pass. test_precompile_compute_guard.py needs Windows SEH, so it skipped here, but CI ran it green. The capability scan is correct, and anything it can't parse counts as subgroup-using. Other vendors keep the pin by default. The 5.5–26 s first builds against under 0.2 s on the Iris Xe are a measurement worth having.
One risk I'd like you to address or rule out. vk_draw.cpp:198 keeps the pin for shared-memory programs only when they have at most 32 invocations. Guest code written for Maxwell can also be warp-synchronous inside a larger workgroup. The classic case is a reduction tail through shared memory without BAR for the last 32 lanes. That needs no subgroup capability in the SPIR-V. It was safe at SIMD32, and on ANV's SIMD8/16 it can read stale values. Could you check whether the four slow programs use shared memory at all? If they don't, keeping every shared-memory program pinned costs nothing and removes the question. The picture matching RX_VK_PIN_ALL=1 at the Deku Tree is good, but it is a single scene.
On Intel/Mesa, game compute programs are required to run at 32 lanes even when they cannot see their subgroup. On an Iris Xe that makes some first builds take 5-26 seconds, leaving the effects they draw missing while the player waits.
Part of #1001
What changed
spirv_uses_subgroupsreads the SPIR-V's declared capabilities: GroupNonUniform*, the KHR ballot and vote, Groups and cooperative matrices mean the lane count matters. Unknown or malformed SPIR-V is treated as subgroup-using.pin_computeleaves a compute program without those capabilities unpinned, so the driver chooses its width. A program with shared memory and at most 32 invocations stays pinned: a compiler may drop barriers a single-warp workgroup does not need.pin_compute.RX_VK_PIN_ALL=1pins every program as before;=0enables the selective rule on any GPU.This complements #2513: that change reduces the SPIR-V for table-heavy programs; this one removes the SIMD32 requirement only from programs that cannot observe their subgroup.
Checks
tests/test_compute_pin.pychecks the capability scan, the pin decision, the shared-memory exception and every game compute pipeline's use ofpin_compute.tests/test_program_cache_cleanup.pycompiles the scan with the cache loader.tests/test_precompile_compute_guard.pycompiles the precompile's compute arm with apin_computestand-in; which programs are pinned is left totests/test_compute_pin.py.Tested in the game
Iris Xe (Raptor Lake-P, i9-13900H, 32 GB), Mesa ANV 26.2.4, Bazzite. Headless at the Deku Tree, with the serial queue's escape:
9790303532c0c309,76b54f5bb0d7ce97,37d9fd3069f0e5e4and0fe7f6c474c57be5each built in under 0.2 s without the pin, against 5.5, 26.4, 14.7 and 14.5 s pinned.RX_VK_PIN_ALL=1(9.2 against 9.1 fps).Not tested: other Intel GPUs, Windows.