SV_DispatchThreadID in DirectX Compute Shaders
This article provides an overview of how
SV_DispatchThreadID operates within DirectX compute shaders
to provide unique, global 3D coordinates across execution threads. In
GPU compute pipelines, thousands of threads execute concurrently across
distributed thread groups. SV_DispatchThreadID acts as a
built-in HLSL system-value semantic that automatically calculates each
thread’s absolute spatial position across the entire dispatch grid,
eliminating the need for manual coordinate reconstruction when
processing 3D data such as volumes, voxels, and spatial simulations.
Understanding the Execution Hierarchy
DirectX compute shaders organize execution into a two-level grid:
- Thread Groups (Dispatch Grid): Defined on the CPU
via the
Dispatch(X, Y, Z)API call, specifying the number of thread groups across three dimensions. - Threads within a Group: Defined in HLSL using the
[numthreads(X, Y, Z)]attribute, specifying the dimensions of individual threads inside each group.
Because of this nested structure, each thread has both a local position within its specific group and a global position across all launched groups.
The Mathematical Function of SV_DispatchThreadID
SV_DispatchThreadID provides a uint3 vector
containing the global coordinates (x, y, z) of the
executing thread across the entire dispatch call.
HLSL computes this value behind the scenes using the following vector formula:
SV_DispatchThreadID = (SV_GroupID * numthreads) + SV_GroupThreadID
Where:
SV_GroupID: The 3D index of the current thread group within the dispatch call.numthreads: The static dimensions of the thread group specified in the shader attribute.SV_GroupThreadID: The 3D index of the thread relative only to its local group.
By applying this calculation across the X, Y, and Z axes simultaneously, DirectX gives every thread a distinct, non-overlapping coordinate within the global 3D domain.
Direct Indexing into 3D Resources
The primary function of SV_DispatchThreadID in 3D
compute tasks is providing a direct, 1:1 index for reading and writing
to 3D spatial resources, such as volumetric textures
(RWTexture3D) or 3D structured buffers.
RWTexture3D<float4> OutputVolume : register(u0);
cbuffer VolumeConstants : register(b0)
{
uint3 VolumeDimensions;
};
[numthreads(8, 8, 8)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
// Prevent out-of-bounds writes when volume dimensions are not multiples of group size
if (id.x >= VolumeDimensions.x || id.y >= VolumeDimensions.y || id.z >= VolumeDimensions.z)
{
return;
}
// Directly use the 3D coordinate
OutputVolume[id] = float4(id.x / (float)VolumeDimensions.x,
id.y / (float)VolumeDimensions.y,
id.z / (float)VolumeDimensions.z,
1.0f);
}
Linearizing 3D Coordinates
When writing to a flat 1D buffer (such as a structured or
byte-address buffer) representing a 3D grid,
SV_DispatchThreadID provides the base components needed to
calculate a linear index:
uint linearIndex = id.x +
(id.y * VolumeDimensions.x) +
(id.z * VolumeDimensions.x * VolumeDimensions.y);
Using SV_DispatchThreadID ensures that hardware dispatch
mechanics remain decoupled from memory access logic, providing a clean
and efficient coordinate space for spatial GPU workloads.