← Chrome 148 reference

v148 · webgpu · wgsl · shipped

WebGPU: linear_indexing feature

A WGSL language extension shipping in Chrome 148 that adds two new compute shader built-in values — global_invocation_index and workgroup_index — giving compute shaders a flat linear index without manual 3D-to-1D coordinate math.

at a glance

Shipped inChrome 148 (desktop, Android, WebView)
StatusEnabled by default
Feature detectionnavigator.gpu.wgslLanguageFeatures.has("linear_indexing")
WGSL opt-inrequires linear_indexing;
SpecW3C WGSL specification (PR #5554)
ChromeStatus5071243424432128 — WebGPU: linear_indexing feature (API record)

why it exists

WebGPU compute shaders dispatch work in a 3D grid of workgroups, each containing a 3D grid of invocations. To process a flat buffer — the common case for data-parallel tasks — developers had to compute a linear index from three separate coordinates every time:

// Old pattern — manual linear index calculation
let linear = global_id.z * (workgroup_size.x * workgroup_size.y * num_workgroups.x * num_workgroups.y)
           + global_id.y * (workgroup_size.x * num_workgroups.x)
           + global_id.x;

This is boilerplate that must be repeated in every compute shader that processes linear data, and it's easy to get wrong. linear_indexing moves this calculation into the language itself.

Source: blink-dev Intent to Ship; Chrome for Developers WebGPU (Chrome 147-148); gpuweb issue #5154.

new built-in values

Built-inTypeDescription
global_invocation_index u32 The linear index of this invocation within the entire dispatch grid. Equivalent to computing a 1D offset from global_invocation_id.xyz manually.
workgroup_index u32 The linear index of this invocation's workgroup within the grid of workgroups. All invocations in the same workgroup share the same value.
Source: W3C WGSL specification; gpuweb PR #5554; Chrome for Developers blog.

example

WGSL shader compute invocation with linear indexing:

fn main(@builtin(global_invocation_index) idx: u32) { /* ... */ }

Feature detection and WGSL shader

// JavaScript: detect before using
if (!navigator.gpu.wgslLanguageFeatures.has('linear_indexing')) {
  throw new Error('linear_indexing WGSL extension not available');
}

const shaderCode = `
  requires linear_indexing;

  @group(0) @binding(0) var<storage, read_write> data: array<f32>;

  @compute @workgroup_size(64)
  fn main(@builtin(global_invocation_index) idx: u32) {
    if (idx < arrayLength(&data)) {
      data[idx] = data[idx] * 2.0;
    }
  }
`;

const shaderModule = device.createShaderModule({ code: shaderCode });
// ... create pipeline and dispatch as usual

workgroup_index example

requires linear_indexing;

var<workgroup> workgroup_data: array<f32, 64>;

@compute @workgroup_size(64)
fn accumulate(
  @builtin(workgroup_index) wg_idx: u32,
  @builtin(local_invocation_index) local_idx: u32,
) {
  // wg_idx identifies which workgroup we're in (flat index)
  // useful for indexing per-workgroup output buffers
  workgroup_data[local_idx] = f32(wg_idx);
}
Source: W3C WGSL spec; blink-dev Intent to Ship; Chrome Platform Showcase demo.

browser support

BrowserSupport
Chrome 148+ (desktop, Android, WebView)Enabled by default
FirefoxNo position
SafariNo position
Source: ChromeStatus API record; ChromeStatus milestone=148 listing; WebGPU CTS PR #4595; Mozilla standards-positions #1205; WebKit standards-positions #294; webstatus.dev webgpu; BCD api/GPU.json.

see also