v146 · Web APIs · Compatibility Limits

Compatibility Limits

What is restricted in WebGPU compatibility mode compared to core WebGPU, why each restriction exists (OpenGL ES constraints), and how to write portable shaders that work in both modes.

Compatibility mode maps WebGPU to OpenGL ES 3.1+ and OpenGL 4.4+. These APIs lack certain features that Vulkan, Metal, and D3D12 provide. The restrictions listed here are the minimum set of compromises needed to support these older graphics APIs.

feature availability

Feature Core WebGPU Compatibility mode Reason for restriction
Basic rendering, compute, textures Yes Yes Supported in GLES 3.1
Cube array textures Yes No Not in GLES 3.1 core
Separate depth/stencil aspects Yes No GL doesn't support separate views of depth/stencil
Multi-draw-indirect Yes No Not universally available in GLES 3.1
WGSL sample_mask built-in Yes No GL sample mask limited in GLES
Texture array layers (2D) Yes Yes Supported in GLES 3.0+
Compute shaders Yes Yes Required by GLES 3.1
Storage buffers and textures Yes Yes Supported in GLES 3.1

writing portable WGSL

// ✓ Works in both core and compatibility mode
@group(0) @binding(0) var myTex: texture_2d<f32>;
@group(0) @binding(1) var myArr: texture_2d_array<f32>;

@fragment fn fs(
  @location(0) uv: vec2f,
  @location(1) layer: f32,
) -> @location(0) vec4f {
  let c = textureSample(myTex, mySampler, uv);
  let a = textureSampleLevel(myArr, mySampler, uv, layer, 0.0);
  return c + a * 0.5;
}

// ✗ Core only — avoid in code that needs compat mode:
// texture_cube_array — not available in compat
// @builtin(sample_mask) — not available in compat
// Separate depth/stencil views — not available in compat

detecting the mode

const adapter = await navigator.gpu.requestAdapter({
  featureLevel: 'compatibility',
});

if (!adapter) {
  // Even compat mode not available
  useFallback();
  return;
}

const isCompat = adapter.featureLevel === 'compatibility';

if (isCompat) {
  // Avoid cube arrays, sample_mask, etc.
  loadCompatShaders();
} else {
  loadCoreShaders();
}

see also