v153 · enabled by default · webgpu · wgsl
WebGPU: buffer_view feature
A WGSL language feature that lets a shader reinterpret the bytes of a single uniform, storage, or workgroup variable as several different types — dividing one buffer variable into multiple logical variables, or type-punning its contents — through a new opaque buffer type and three new built-in functions (bufferView, bufferArrayView, bufferLength). It adds no JavaScript API surface of its own.
The buffer_view language extension is tagged ["dawn"] in dawn.json — it is a Dawn-track extension, and the wgslLanguageFeatures detection string could in principle change before broader standardization. Vendor positions on the record are “No signal” (Firefox) and “Closed Without a Position” (Safari), so treat this as Chromium-only for now and always feature-detect via navigator.gpu.wgslLanguageFeatures (see detection). The JS-side validation contract for buffer-typed bindings (minBindingSize interaction) is still a spec TODO with no normative text — this page documents the shader-side rules only (see specifications).
at a glance
| What it is | The buffer_view WGSL language extension: opaque buffer<N> / buffer types plus built-ins that reinterpret buffer memory as another host-shareable type at a byte offset |
|---|---|
| Milestone listing | Chrome 153 — Enabled by default (listing, verified 2026-07-29) |
| Applies to | WGSL shader source compiled through WebGPU (GPUDevice.createShaderModule); no new JS interfaces, methods, or dictionaries — the WebGPU specification contains no buffer_view text (checked 2026-07-29) |
| Feature detection | navigator.gpu.wgslLanguageFeatures contains "buffer_view" when supported (see feature detection) |
| Opt-in | None required — language extensions are automatically available when the implementation supports them; a requires buffer_view; directive documents the dependency and makes unsupported implementations fail with a shader-creation error (see the extension mechanics) |
| Spec status | Merged into the WGSL specification via gpuweb/gpuweb PR #6291 on 2026-07-14: §6.3 Buffer Types and §17.14 Buffer View Built-in Functions |
| Implementation | Dawn/Tint: WGSL language extension buffer_view in dawn.json (value 9, Dawn-tagged); tracking bug crbug.com/tint/506523198 |
| Tests | WebGPU CTS execution + validation suites for all three built-ins (see test coverage); no upstream WPT directory tests |
| ChromeStatus | 5094091886034944 — WebGPU: buffer_view feature (blink component Blink>WebGPU, owner alanbaker@google.com) |
why it exists
WGSL variables have a single static type: the value stored in a variable cannot be reinterpreted as another type before a memory access occurs. Two practical problems follow, both from the proposal (created 2025-10-20, issue #5338):
- Type punning. The data of a uniform, storage, or workgroup variable sometimes needs to be read as more than one type within a program (for example a buffer whose first word is a
u32count and whose tail is an array off32). - Sub-division. WGSL allows only one runtime-sized array in a storage buffer interface, so heterogeneous data (say
indices : array<u32>andvertices : array<f32>) needs either twoGPUBufferbindings or one buffer split at an offset aligned tominStorageBufferOffsetAlignment(typically 256 bytes) — wasting memory and complicating bind groups. Withbuffer_viewthe two logical arrays can live tightly packed in a single binding and be viewed separately in the shader.
For safety and implementation simplicity the type is opaque: it cannot be read, written, or assigned directly — only the new built-in functions can reinterpret its contents (see the ChromeStatus record motivation).
Source: buffer-view proposal — motivation; ChromeStatus API record; webgpu-samples PR #568 (the wireframe scenario the example derives from)the buffer types
The feature adds two related opaque types (WGSL §6.3). A buffer value denotes memory whose contents can be interpreted as another host-shareable type; buffer values are otherwise opaque and are not constructible — they cannot appear in assignments, and an expression must not evaluate to a buffer type. The only way to interact with them is through the built-in functions (possibly via pointers).
| Type | Meaning | Instantiation rules |
|---|---|---|
buffer<N> | Fixed-size buffer with N bytes of storage. N must be an override-expression | Only as the store type of a variable in the storage, uniform, or workgroup address spaces; in storage and uniform the size must further be a const-expression |
buffer | Runtime-sized buffer; its byte size comes from the bound GPUBuffer (see bufferLength) | Only as the store type of a variable in the storage address space |
Validation of the size parameter N:
- If
Nis not greater than 0: a shader-creation error whenNis a const-expression, otherwise a pipeline-creation error. - If the
f16extension is enabled andNis not evenly divisible by 2: shader-creation error (const-expression) / pipeline-creation error (otherwise). - If
f16is not enabled andNis not evenly divisible by 4: shader-creation error (const-expression) / pipeline-creation error (otherwise).
Two buffer types are the same type if and only if: both are runtime-sized; or both are fixed-size with a creation-fixed footprint and equal-valued sizes (signed and unsigned sizes compare equal here because sizes are always positive); or both are fixed-size with sizes specified as identifiers resolving to the same pipeline-overridable constant declaration.
Source: WGSL §6.3 Buffer Types (rules quoted and paraphrased from the merged text, fetched 2026-07-29)the language extension mechanics
buffer_view is a WGSL language extension (WGSL §4.1.2): it is automatically available whenever the implementation supports it — the program does not request it with an enable directive, and there is no chrome://flags entry or Blink runtime flag (the flag is false on the ChromeStatus record; the feature lives in Dawn/Tint, not Blink). The extension index describes it as: “Enables the use of buffer types and the buffer_view built-in functions.”
A requires directive documents the program's use of the extension and turns absence into a hard failure:
requires buffer_view;
@group(0) @binding(0) var<storage> data : buffer;
If the implementation does not support a required extension, shader creation fails with a shader-creation error — so requires buffer_view; both signals non-portability to tooling and guarantees a clean diagnostic instead of a parse error on the buffer type.
feature detection (the JavaScript side)
There is no new JavaScript API: the only JS-observable surface is the pre-existing GPU.wgslLanguageFeatures set-like object, which lists the WGSL language extensions the implementation supports. In Dawn the extension is registered as 'buffer_view' (dawn.json, WGSL language-extension value 9):
const supported = navigator.gpu.wgslLanguageFeatures.has("buffer_view");
if (!supported) {
// Fall back to multiple bindings or statically-typed buffers.
}
Pair the detection with a requires buffer_view; directive in shaders that use the feature: detection tells you whether to select such a shader; the directive makes an unsupported implementation reject it deterministically.
buffer_view coverage, verified 2026-07-29); dawn.json
the built-in functions
All three functions operate on a pointer to a buffer and are annotated @must_use. Two helper definitions drive their validation (WGSL §17.14):
ArrayOffset(T)=OffsetOfMember(T, lastMemberIndex)whenTis a structure whose last member is a runtime-sized array;0otherwise.MinTypeSize(T)=SizeOf(T)whenThas a fixed footprint;StrideOf(T)whenTis a runtime-sized array;ArrayOffset(T) + StrideOf(array<E>)whenTis a structure ending in a runtime-sized array.
offset bytes into p as type T (fixed or runtime-sized); the result pointer covers [offset, bufferLength(p))
bufferArrayView<T>(p, offset, size) — the same, but with an explicit byte size; T must not have a fixed footprint (must contain a runtime-sized array); the result covers [offset, offset+size)
bufferLength(p) — the buffer's byte size: the minimum size encountered through the call stack (interprocedural analysis), N for sized buffers, or the GPUBuffer size
Common validation contract (details on each member page): AS ∈ {storage, uniform, workgroup}; AM must be a valid access mode for AS; T must be host-shareable, must not be or contain an atomic or buffer type (MSL cannot cast non-atomic to atomic), and must satisfy the address-space layout constraints for AS. Out-of-contract offsets produce an invalid memory reference / invalid pointer at runtime, a shader-creation error for const-expressions, or a pipeline-creation error for override-expressions.
buffer pointers as function parameters
Buffer values cannot be passed to functions (they are not constructible and no expression may evaluate to one), but buffer pointers can. Because the parameter address spaces involved exceed the default pointer-parameter rules, this requires the unrestricted_pointer_parameters extension as well as buffer_view. Two feasible automatic conversions then relax type matching (WGSL conversion-rank table):
| Argument (source) | Parameter (destination) | Rank | Effect |
|---|---|---|---|
ptr<AS, buffer<N1>, AM> | ptr<AS, buffer<N2>, AM> (both const-expressions) | 1 if N2 < N1, infinity otherwise | A fixed-size buffer pointer argument converts to a smaller fixed-size pointer parameter |
ptr<AS, buffer<N>, AM> | ptr<AS, buffer, AM> | 1 | A fixed-size buffer pointer argument converts to a runtime-sized buffer pointer parameter |
No other automatic conversions apply. Buffer sizes cannot be grown through a call: the buffer size any built-in sees is the minimum of the originating variable's size and the smallest fixed-size formal parameter on the call stack — implementations use interprocedural analysis for both validation and bufferLength. When unrestricted_pointer_parameters is not supported, the root identifier of a built-in's argument must be the originating variable.
requires buffer_view;
requires unrestricted_pointer_parameters;
@group(0) @binding(0) var<storage> big : buffer<2048>;
// Accepts any storage buffer pointer: buffer<2048> converts to buffer (rank 1).
fn helper(p : ptr<storage, buffer>) -> u32 {
return bufferLength(p); // sees the minimum size on the call stack
}
fn caller() -> u32 {
return helper(&big);
}
Source: WGSL — feasible automatic conversions; WGSL §17.14 introductory rules
examples
Sub-dividing one storage binding into two logical arrays (derived from the proposal's wireframe scenario — buffer layout | indices size | indices | vertices |, tightly packed in a single GPUBuffer):
requires buffer_view;
@group(0) @binding(0) var<storage> indices_and_vertices : buffer;
fn foo() {
let indices_size = *bufferView<u32>(&indices_and_vertices, 0);
let indices_ptr = bufferArrayView<array<u32>>(&indices_and_vertices, 4, indices_size);
let vertices_ptr = bufferView<array<f32>>(&indices_and_vertices, indices_size + 4);
// Use indices_ptr and vertices_ptr like separate indices/vertices variables.
}
The matching JavaScript side binds one tightly-packed buffer — no 256-byte alignment gap between the two regions (contrast the two-binding layout that minStorageBufferOffsetAlignment forces without this feature):
const total = 4 + indices_size + vertices_size;
const buffer = device.createBuffer({ size: total, usage: GPUBufferUsage.STORAGE });
const bg = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [{ binding: 0, resource: buffer }],
});
The Chrome Platform Showcase has no route for this feature yet (both slug spellings 404, checked 2026-07-29); the upstream sample is the open webgpu-samples PR #568 (“Add a buffer_view variant option to wireframe sample”, open at fetch time).
Source: proposal — motivating example; webgpu-samples PR #568error and edge behavior
| Situation | Behavior |
|---|---|
Implementation lacks the extension and shader uses buffer types | Parse/validation failure; with requires buffer_view; it is a defined shader-creation error |
N ≤ 0, or N not divisible by 4 (by 2 when f16 is enabled) | Shader-creation error if N is a const-expression; pipeline-creation error otherwise |
bufferView/bufferArrayView with T atomic, containing an atomic, or a buffer type | Validation error (precondition failure) — reinterpretation is single-shot and non-atomic only |
Negative offset/size (i32 overloads) | Shader-creation error (const-expression < 0); pipeline-creation error (override-expression < 0); otherwise an indeterminate value may be used |
Out-of-range reinterpretation (MinTypeSize(T) + offset > bufferLength(p), or offset + size > bufferLength(p), or MinTypeSize(T) > size) | An invalid memory reference / invalid pointer is returned at runtime; statically-known cases are shader-creation or pipeline-creation errors |
Misaligned offset (offset % RequiredAlignOf(T, AS) != 0) | Shader-creation error (const-expression) / pipeline-creation error (override-expression); otherwise the implementation rounds down to offset & ~(RequiredAlignOf(T, AS) - 1) |
| Structuring a declaration of buffer type outside storage/uniform/workgroup, or assigning a buffer value | Validation error — the type is opaque and not constructible |
test coverage
The WebGPU Conformance Test Suite (CTS) covers all three built-ins with execution and validation suites:
- execution/…/bufferView.spec.ts · validation/…/bufferView.spec.ts
- execution/…/bufferArrayView.spec.ts · validation/…/bufferArrayView.spec.ts
- execution/…/bufferLength.spec.ts · validation/…/bufferLength.spec.ts
There are no upstream WPT webgpu directory tests for this feature (the directory holds only metadata files, checked 2026-07-29); the ChromeStatus record marks wpt: true — the CTS is the executable conformance story for WebGPU. Per-run pass counts are not inventoried here.
browser compatibility
Interim table. BCD has no buffer_view key (the feature is a WGSL extension, not JS API surface; BCD api/GPU.json checked 2026-07-29) and webstatus.dev has no entry, so rows are compiled from the linked primary sources. The detection mechanism (GPU.wgslLanguageFeatures) does have BCD data, shown in the second table.
| Browser | buffer_view support | Evidence |
|---|---|---|
| Chrome | Enabled by default 153 (desktop, Android, WebView) | milestone=153 listing; record (desktop/android/webview 153, flag: false) |
| Edge | Not separately reported | Chromium-based; no separate position on the record |
| Firefox | No signal | mozilla/standards-positions #1205 (per the record's views link) |
| Safari | Closed without a position | WebKit/standards-positions #294 (per the record's views link) |
Detection API support (BCD api.GPU.wgslLanguageFeatures):
| Browser | GPU.wgslLanguageFeatures |
|---|---|
| Chrome | 144 (full; ChromeOS, macOS, Windows, Linux Intel Gen12+); 115–143 partial (ChromeOS, macOS, Windows) |
| Chrome Android | 121 |
| Edge | Mirrors Chrome |
| Firefox | 141 (partial — all contexts except service workers, bug 1942431) |
| Safari | 26 |
security and privacy
- Memory safety is preserved by construction. The buffer type is opaque and not constructible; the only access path is the three built-ins, whose out-of-contract reinterpretations yield an invalid memory reference (WebGPU's standard out-of-bounds behavior) rather than raw memory access. Type-punning stays inside the shader's own binding.
- Single-shot reinterpretation.
Tcannot be or contain a buffer type, so views cannot be chained;Tcannot be or contain an atomic type (MSL cannot cast non-atomic to atomic), keeping atomicity guarantees intact. - Static checking where possible. Const-expression violations are shader-creation errors and override-expression violations are pipeline-creation errors; only genuinely runtime-dependent bounds fall through to invalid-reference behavior.
- No new JS surface or data flow. The WebGPU API is unchanged (no
buffer_viewtext in the WebGPU spec); the feature exposes no new storage, network, or fingerprinting surface beyond thewgslLanguageFeaturesstring that all WGSL extensions already share.
specifications
Documents fetched 2026-07-29; each row links the artifact directly.
| Document | Status |
|---|---|
| WGSL — §6.3 Buffer Types and §17.14 Buffer View Built-in Functions | Editor's Draft text merged via PR #6291 (merged 2026-07-14) |
| buffer-view proposal | Status “Merged”; created 2025-10-20; tracks issue #5338 (closed) |
| WebGPU API specification | Unchanged by this feature (no buffer_view content, checked 2026-07-29) — detection rides the existing wgslLanguageFeatures member |
see also
- Chrome Platform Status — WebGPU: buffer_view feature (API record)
- Tint tracking bug 506523198
- dawn.json — WGSL language extensions (
buffer_view, value 9) - webgpu-samples PR #568 — wireframe buffer_view variant (open)
- MDN — GPU.wgslLanguageFeatures (the detection API; MDN does not cover the
buffer_viewfeature itself — search and page grep returned no coverage, 2026-07-29) - webstatus.dev — webgpu feature (Baseline limited)
- WebGPU CTS — built-in execution tests