What's New in WebGPU (Chrome 155-156)

WGSL fragment_depth extension

In geometry-intensive render passes, early-Z optimizations are developers' best friend. They provide a massive performance boost by letting the GPU discard hidden pixels before running expensive fragment shaders. If a rasterized depth fails the depth test, the GPU skips the fragment shader entirely, provided the shader doesn't have other side effects.

If you want to read into how hardware handles this, MJP has an excellent write-up on When Does Early-Z Have to be Disabled?.

While custom depth manipulation is useful, doing it in your fragment shader comes with a hidden tax. Writing to @builtin(frag_depth) inside a fragment shader typically forces drivers to disable these early-Z optimizations for the entire draw call. This happens because driver heuristics can't guarantee that the shader's calculated output depth matches the depth interpolated by the rasterizer.

To address this performance penalty, the WGSL extension fragment_depth lets you specify a less or greater depth mode name on @builtin(frag_depth) to explicitly state how the written depth compares to the interpolated depth, enabling the GPU to safely apply early-Z optimizations.

This language extension can be feature-detected in JavaScript using navigator.gpu.wgslLanguageFeatures. It's recommended to use a requires-directive to signal the potential for non-portability with requires fragment_depth; at the top of your WGSL shader code. See the following example and intent to ship.

if (!navigator.gpu.wgslLanguageFeatures.has("fragment_depth")) {
  throw new Error(`WGSL fragment depth is not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires fragment_depth;

  @fragment
  fn main() -> @builtin(frag_depth, less) f32 {
    // Explicitly states that the output fragment depth is less than early-Z depth,
    // allowing the GPU to safely preserve early-Z optimizations.
    return 0.0f;
  }`,
});

Texture compression unaligned

The "texture-compression-unaligned" GPU feature enables the creation of compressed textures with dimensions that aren't integer multiples of the block size (such as 4x4 for BC, ETC2, and ASTC formats). Previously, WebGPU strictly required texture sizes to align with these block boundaries. By removing the need to pad or scale textures to fit block alignments, this feature preserves original compression fidelity without introducing scaling distortion. See the intent to ship.

The following code snippet checks if the adapter supports texture compression unaligned and, if available, requests a device with it.

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("texture-compression-unaligned")) {
  throw new Error("Texture compression unaligned support is not available");
}
// Explicitly request texture compression unaligned support.
const device = await adapter.requestDevice({
  requiredFeatures: ["texture-compression-unaligned"],
});

Many thanks to external contributor Ignacio Castaño of spark.js for driving this feature, spec and CTS work!

srgb-linear and display-p3-linear color spaces

With the addition of the "srgb-linear" and "display-p3-linear" predefined color spaces, the WebGPU canvas context can now render directly into extended-range linear color spaces to support wide-gamut displays. These color spaces maintain a linear relationship between pixel values and physical luminance. This makes them ideal for physical light rendering in games as well as spatial processing tasks like anti-aliasing, interpolation, and decimation. See the intent to ship and the Particles (HDR) sample PR #574.

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const canvas = document.querySelector("canvas");
const context = canvas.getContext("webgpu");

context.configure({
  device,
  format: "rgba16float",
  colorSpace: "display-p3-linear",
});

Additional snorm10-10-10-2 vertex format

The "snorm10-10-10-2" vertex format is a packed 32-bit format holding four signed normalized values: three 10-bit components (r, g, b) and one 2-bit component (a). With this format, you can efficiently store attributes, like 3D normal vectors with an extra 2-bit scalar, or alignment flag while saving memory bandwidth. See spec PR 6491.

f16 support on Linux for NVIDIA

The optional "shader-f16" feature, which provides support for 16-bit floating-point values in WGSL, is now supported on Linux for recent NVIDIA GPU drivers. See issue chromium:42251215.

Dawn updates

You can now query the LUID of the underlying DXGIAdapter for a given GPU adapter using the WGPUAdapterPropertiesD3D struct. See issue chromium:562849566.

This covers some of the key highlights. Check out the exhaustive list of commits.

What's New in WebGPU

A list of everything that has been covered in the What's New in WebGPU series.

Chrome 155-156

Chrome 153-154

Chrome 151-152

Chrome 149-150

Chrome 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

Chrome 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113