Skip to content

Thread Coordinates

When launching a compute shader, execution is divided into a three-level hierarchy: Invocations (Threads), Workgroups, and the Grid.

Understanding the coordinates of each executing thread is critical for GPGPU programming. WGSL provides several built-in input variables to locate an invocation within this hierarchy.

Thread Coordinates Built-ins

Every execution thread has access to the following built-ins in its entry point:

  1. @builtin(global_invocation_id) (vec3<u32>): The unique 3D coordinate of the current thread across the entire dispatch grid.
  2. @builtin(local_invocation_id) (vec3<u32>): The 3D coordinate of the thread within its parent workgroup.
  3. @builtin(workgroup_id) (vec3<u32>): The 3D coordinate of the workgroup within the dispatch grid.
  4. @builtin(local_invocation_index) (u32): A linearized (1D) index of the thread within its workgroup, starting at 0 and ending at (size_x * size_y * size_z) - 1.

Mathematical Coordination Mapping

The relationship between these coordinates is given by:

\[ \text{global_invocation_id} = \text{workgroup_id} \times \text{workgroup_size} + \text{local_invocation_id} \]

Or in WGSL component form:

let global_x = workgroup_id.x * workgroup_size_x + local_id.x;

Similarly, the linearized index local_invocation_index is computed from the 3D local coordinate as:

\[ \text{local_invocation_index} = \text{local_id.z} \times (\text{size_x} \times \text{size_y}) + \text{local_id.y} \times \text{size_x} + \text{local_id.x} \]

Inspecting Coordinates

In the shader code on the right, we capture these coordinate values. The visualizer evaluates them to show the layout mappings!