D892 - A group of waves meets at the workgroup barrier where no branch crosses it

Status: decided Date: 2026-10-19

A guest compute dispatch whose thread group is more than one wave and whose program waits at s_barrier or uses the local data share runs as D858 runs any group of waves: a workgroup of one invocation per wave. The waves share the local data share, which is the workgroup's storage. They meet at s_barrier through the workgroup's barrier.

The dispatch loop (D098) is cut into one loop for each run of blocks ending at an s_barrier, and the last run ends at the program's end. Each loop runs while the program counter is within its own blocks. The workgroup's barrier stands between two loops at the function's top level, so every invocation reaches it once each time, as every wave reaches its s_barrier once. A wave that has ended holds the exit value, past every run, so it runs none of the later loops and still passes each barrier.

A program with a branch from one run into another is refused by name. That is a branch over an s_barrier, or a loop around one, so one wave would meet the others a different number of times. A dispatch run one invocation per lane (D880) still refuses a group of waves that meets: its waves are then separate workgroups, which share nothing. A group of one wave is translated as before, one loop, byte for byte.

Why: Grand Theft Auto V's scene compute program reduces through the local data share in groups of 256 threads, four waves, with eight s_barriers at the top of its program. It has no branch back, and none of its branches crosses a barrier. D858 rejected the workgroup barrier because a barrier inside the dispatch loop is reached on only some paths of that loop, which Vulkan leaves undefined. Between the cut loops it is reached in uniform control flow. A device test runs a group of two waves in which each thread writes its id to the share, waits, and stores the word of thread id ^ 64, the other wave's. Every word is the one the other wave wrote.

Rejected: