demo · v139

Cross-Platform Renderer

Request two WebGPU adapters — one standard, one with featureLevel: 'compatibility' — and render the same triangle to side-by-side canvases. Inspect adapter info, backend name, and the feature restrictions that compat mode imposes.

WebGPU required. If unavailable, the adapter info panels still render with explanatory text and the feature diff table is pre-filled with the known compat mode restrictions.
Click "Request adapters & render" to begin.
Standard Mode standard

adapter:

backend:

compat:

features:

Compat Mode compat

adapter:

backend:

compat:

features:

feature diff: standard vs compat

capabilitystandardcompat mode
Storage textures in vertex shaders yes no — removed
bgra8unorm storage textures yes (with feature) no
Non-zero firstInstance in draws yes (with feature) no
Cube array textures yes no
Separate depth/stencil aspects yes no
MSAA render-to-texture yes limited — no auto-resolve
Texture format reinterpretation (view formats) yes no
provoking vertex convention last vertex undefined (driver decides)

platform coverage

Compat mode specifically targets hardware where Vulkan or Metal are unavailable. Standard mode already covers most modern devices.

Windows

D3D12 / Vulkan

standard ✓
compat ✓

macOS

Metal

standard ✓
compat ✓

Android (new)

Vulkan

standard ✓
compat ✓

Android (old)

OpenGL ES 3.1

standard ✗
compat ✓

Linux

Vulkan / GL

standard ✓
compat ✓

ChromeOS (old)

OpenGL ES

standard ✗
compat ✓

who should use compat mode?

▸ Does your app need to run on Android devices older than 2019?

yes →

▸ Does your app use storage textures in vertex shaders, cube arrays, or MSAA auto-resolve?

yes → Refactor those features; then enable compat mode for the broader device reach.

no → Use compat mode. You get OpenGL ES 3.1 coverage with zero code changes.

no →

▸ Do you need maximum GPU feature access (ray tracing, advanced formats, etc.)?

yes → Use standard mode only.

no → Either works. Compat is a safe default for forward compatibility.

the code

// Standard adapter
const stdAdapter = await navigator.gpu.requestAdapter();

// Compatibility mode adapter (Chrome 139)
const cmpAdapter = await navigator.gpu.requestAdapter({
  featureLevel: 'compatibility',
});

const stdDevice = await stdAdapter.requestDevice();
const cmpDevice = await cmpAdapter.requestDevice();

// Check which mode you got
console.log(stdDevice.features.has('core-features-and-limits')); // true for core
console.log(cmpDevice.features.has('core-features-and-limits')); // false for compat subset

// Render normally — same pipeline code works on both
function render(device, canvas) {
  const ctx = canvas.getContext('webgpu');
  ctx.configure({ device, format: navigator.gpu.getPreferredCanvasFormat() });
  // … create pipeline, draw …
}

see also