wave_read_first
Reads a value from the first active lane in the wave.
Test wave_read_first in a live shader
Open the playground, start from a visual preset, and wire wave_read_first into the fragment stage to see how it behaves with real values.
Open PlaygroundLive Demo Pending
The wave_read_first function returns the value from the first (lowest-indexed) active lane to all lanes in the wave.
Signature
wave_read_first :: (T x) -> T {...}
Where T can be float, float2, float3, float4, int, or uint.
Parameters
| Parameter | Type | Description |
|---|---|---|
x | T | Value to read from first active lane |
Return Value
Returns the value of x from the first active lane to all lanes.
Example
pipeline DivergentBroadcast {
pass "Main" {
compute "Main" [64, 1, 1] {
// Some lanes might be inactive due to divergence
if (condition) {
// Within divergent code, get value from first active lane
float myValue = computeValue(input.local_index);
float firstValue = wave_read_first(myValue);
// All active lanes have first active lane's value
processWithReference(myValue, firstValue);
}
}
}
}Common Use Cases
Divergent Code Broadcast
// Broadcast within divergent control flow
if (needsProcessing) {
float computed = expensiveComputation();
float reference = wave_read_first(computed);
// Use reference for comparisons
}Dynamic Leader Selection
// First active lane becomes leader
float leaderValue = wave_read_first(myValue);
bool isLeader = (myValue == leaderValue); // Note: may have tiesSparse Data Access
// Read from first lane that has valid data
if (hasValidData) {
float data = loadData(dataIndex);
float sharedData = wave_read_first(data);
// All active lanes get the first valid data
}Representative Sample
// Get one representative value from active lanes
float3 position = getPosition(input.local_index);
float3 representativePos = wave_read_first(position);Batch Processing
// Get first item to define batch parameters
int batchId = wave_read_first(itemBatchId);
// Process all items with same batch parameters
if (itemBatchId == batchId) {
processItem();
}First Active Lane
Unlike wave_broadcast, this function automatically selects the first active lane, making it safe to use in divergent code paths.
Use Cases
Prefer wave_read_first over wave_broadcast(x, 0) when:
- Code might be divergent
- Lane 0 might be inactive
- You don't care which lane provides the value
Active Lane Set
The "first" lane is the lowest-indexed lane in the current active set, which changes with control flow divergence.
Compiled Output
When compiled to GLSL:
// Requires GL_KHR_shader_subgroup_ballot
subgroupBroadcastFirst(x)
When compiled to HLSL:
WaveReadLaneFirst(x)
When compiled to SPIR-V:
Uses OpGroupNonUniformBroadcastFirst instruction.
See Also
- wave_broadcast - Broadcast from specific lane
- wave_any - Check if any lane is true
- wave_all - Check if all lanes are true