Intrinsics2 min read

wave_read_first

Reads a value from the first active lane in the wave.

Reading Time
2 min
Word Count
194
Sections
12
Try It Live

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 Playground

Live Demo Pending

This intrinsic does not yet have a self-contained interactive preview. Compute-only and external-resource intrinsics need a different demo path than the current fragment and 3D showcases.

The wave_read_first function returns the value from the first (lowest-indexed) active lane to all lanes in the wave.

Signature

bwsl
wave_read_first :: (T x) -> T {...}

Where T can be float, float2, float3, float4, int, or uint.

Parameters

ParameterTypeDescription
xTValue to read from first active lane

Return Value

Returns the value of x from the first active lane to all lanes.

Example

bwsl
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

bwsl
// Broadcast within divergent control flow
if (needsProcessing) {
float computed = expensiveComputation();
float reference = wave_read_first(computed);
// Use reference for comparisons
}

Dynamic Leader Selection

bwsl
// First active lane becomes leader
float leaderValue = wave_read_first(myValue);
bool isLeader = (myValue == leaderValue); // Note: may have ties

Sparse Data Access

bwsl
// 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

bwsl
// Get one representative value from active lanes
float3 position = getPosition(input.local_index);
float3 representativePos = wave_read_first(position);

Batch Processing

bwsl
// 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:

glsl
// Requires GL_KHR_shader_subgroup_ballot
subgroupBroadcastFirst(x)

When compiled to HLSL:

hlsl
WaveReadLaneFirst(x)

When compiled to SPIR-V:

Uses OpGroupNonUniformBroadcastFirst instruction.

See Also