能力 · API
WebGPU API
发布于 更新于
WebGPU 通过 navigator.gpu 把系统 GPU 交给页面做渲染和通用计算:requestAdapter() 选出一块物理或软件适配器,requestDevice() 把它变成用来创建缓冲区、纹理、管线和命令编码器的 GPUDevice,着色器用 WGSL 而不是 WebGL 的 GLSL 编写。整个 API 带 [SecureContext],并同时暴露在 WorkerNavigator 上,所以专用 Worker 可以独自持有设备。
支持情况按操作系统而非仅按浏览器版本划分(BCD api.GPU)。Chrome 113 在 ChromeOS、macOS 和 Windows 上发布;Chrome 144 为 Intel Gen12 及更新的 GPU 加入 Linux;Chrome 121 覆盖 Android。Firefox 141 只在 Windows 上发布,Apple 芯片 macOS 随后在 Firefox 145(macOS Tahoe)和 147(更早的 macOS)加入,不支持 Intel Mac(bug 2004105)、不支持 Linux(bug 2006676)、不支持 Service Worker 上下文(bug 1942431);Android 版 Firefox 没有实现。Safari 26 在 macOS、iOS、iPadOS 和 visionOS 上发布。
navigator.gpu.requestAdapter()navigator.gpu.requestAdapter(options)
adapter.requestDevice()adapter.requestDevice(descriptor)
navigator.gpu.getPreferredCanvasFormat()canvas.getContext("webgpu")requestAdapter() 返回 Promise<GPUAdapter?>:浏览器没有满足 options 的适配器时以 null 兑现而不是拒绝。requestDevice() 返回 Promise<GPUDevice> 并消耗掉适配器;对同一个 GPUAdapter 再调用一次会被拒绝。getPreferredCanvasFormat() 返回当前系统上 canvas 上下文应配置的 GPUTextureFormat("bgra8unorm" 或 "rgba8unorm")。
requestAdapter() 接受可选的 GPURequestAdapterOptions 字典;requestDevice() 接受可选的 GPUDeviceDescriptor。两者每个成员都有默认值,不带参数的调用是合法的。
| 成员 | 类型 | 必填 | 说明 |
|---|---|---|---|
options.featureLevel |
DOMString |
否 | "core"(默认)或 "compatibility"。请求至少支持该级别限制与特性的适配器;不支持的级别以 null 兑现。未实现兼容模式的浏览器按 "core" 处理。 |
options.powerPreference |
GPUPowerPreference |
否 | "low-power" 或 "high-performance",仅为提示。Windows 上的 Chrome 忽略它,复用浏览器已经分配的那块适配器(crbug.com/369219127)。 |
options.forceFallbackAdapter |
boolean |
否 | 默认 false。为 true 时只允许返回软件(回退)适配器;没有则为 null。 |
options.xrCompatible |
boolean |
否 | 默认 false。请求能向 WebXR 会话呈现的适配器。 |
descriptor.requiredFeatures |
sequence<GPUFeatureName> |
否 | 默认 []。设备必须暴露的特性名;设备上启用的恰好就是这个集合,所以漏列的可选特性即使适配器有也不可用。 |
descriptor.requiredLimits |
record<DOMString, GPUSize64 or undefined> |
否 | 默认 {}。设备必须满足的限制;每个键必须是受支持的限制名,值不得超过适配器自身的值。设备上的校验按这些确切限制进行,而不是按适配器的。 |
descriptor.defaultQueue |
GPUQueueDescriptor |
否 | 默认 {}。只带 device.queue 的 label。 |
descriptor.label |
USVString |
否 | 继承自 GPUObjectDescriptorBase;出现在错误消息和 DevTools 中。 |
requestAdapter() 没有因缺少 GPU 而拒绝的路径:没有适配器或适配器不合适都以 null 兑现。requestDevice() 以两种名称拒绝,顺序即规范的检查顺序(GPUAdapter.requestDevice()(w3.org))。
| 异常 | 条件 |
|---|---|
TypeError |
requiredFeatures 不是 adapter.features 的子集。规范有意让「浏览器根本不认识这个名字」和「这块适配器没有它」报同一个错误。 |
OperationError |
适配器已被更早的 requestDevice() 消耗;或 requiredLimits 的某个键不是受支持的限制;或某个值优于适配器的限制;或对齐类限制不是小于 2^32 的 2 的幂。 |
有两种失败不是拒绝。适配器已过期或浏览器无法满足请求时,requestDevice() 仍然兑现,只是给出的设备已经丢失:device.lost 在 requestDevice() 的 Promise 兑现之前就以 reason 为 "unknown" 的 GPUDeviceLostInfo 兑现。使用过程中的校验错误、显存不足和内部错误以 GPUValidationError、GPUOutOfMemoryError、GPUInternalError 对象的形式经 device.popErrorScope() 或 uncapturederror 事件到达,从不以抛出异常的方式出现。
每个示例都先检查 navigator.gpu,再处理 null 适配器,因为两种情况在已发布的浏览器上都会出现:Android 版 Firefox 没有 navigator.gpu,Intel Mac 上的 Firefox 有 navigator.gpu 却拿不到适配器。
检测支持并回退到 WebGL2
Section titled “检测支持并回退到 WebGL2”特性检测分两步:属性存在,以及确实返回了适配器。两种失败同样处理,把 canvas 交给 WebGL2 渲染器,Chrome 56、Firefox 51 和 Safari 15 都提供 WebGL2。
async function createRenderer(canvas) { if (!("gpu" in navigator)) { return createWebGL2Renderer(canvas); } const adapter = await navigator.gpu.requestAdapter(); if (!adapter) { return createWebGL2Renderer(canvas); } const device = await adapter.requestDevice(); const context = canvas.getContext("webgpu"); context.configure({ device, format: navigator.gpu.getPreferredCanvasFormat() }); return createWebGPURenderer(device, context);}
function createWebGL2Renderer(canvas) { const gl = canvas.getContext("webgl2"); if (!gl) throw new Error("WebGPU 与 WebGL2 都不可用"); return { kind: "webgl2", gl };}对已经持有 2D 或 WebGL 上下文的 canvas 调用 getContext("webgpu") 返回 null,所以要在任何回退代码碰到同一个元素之前先创建 WebGPU 上下文。
请求可选特性与限制而不让设备请求失败
Section titled “请求可选特性与限制而不让设备请求失败”先问适配器有什么,再只请求它给得了的。列出缺失的特性会以 TypeError 拒绝;请求高于适配器的限制会以 OperationError 拒绝,所以要按 adapter.limits 收紧而不是写死数值。
async function requestCapableDevice(adapter) { const requiredFeatures = []; for (const name of ["timestamp-query", "texture-compression-bc", "shader-f16"]) { if (adapter.features.has(name)) requiredFeatures.push(name); } const wanted = 1024 * 1024 * 1024; // 1 GiB 存储缓冲区 const requiredLimits = { maxStorageBufferBindingSize: Math.min(wanted, adapter.limits.maxStorageBufferBindingSize), }; try { return await adapter.requestDevice({ requiredFeatures, requiredLimits }); } catch (err) { if (err.name === "OperationError") { return adapter.requestDevice(); // 被拒绝后适配器仍未被消耗 } throw err; }}被拒绝的 requestDevice() 不会消耗适配器,所以用默认参数重试可以在同一个 GPUAdapter 上进行。
从设备丢失中恢复
Section titled “从设备丢失中恢复”device.lost 是每个设备只会落定一次的 Promise:你自己调用 device.destroy() 后 reason 为 "destroyed",其他情况(驱动重置、GPU 进程崩溃、内存紧张的手机把标签页切到后台)为 "unknown"。由丢失设备创建的每个 GPUBuffer、GPUTexture 和管线都已失效,恢复要从 requestAdapter() 重新开始。
async function initGpu(canvas, onLost) { const adapter = await navigator.gpu.requestAdapter(); if (!adapter) return null; const device = await adapter.requestDevice();
device.lost.then((info) => { console.warn(`GPU 设备丢失(${info.reason}):${info.message}`); if (info.reason !== "destroyed") onLost(); // 重新执行 initGpu 并重建资源 });
device.addEventListener("uncapturederror", (event) => { console.error(event.error.message); }); return device;}uncapturederror 监听器接住没有被 pushErrorScope()/popErrorScope() 包住的校验失败;没有它时 Chrome 只在 DevTools 控制台里报告这些错误。
- WebCodecs,其
VideoFrame对象可作为 WebGPU 外部纹理导入 - PWA 的 Core Web Vitals,主线程上的 GPU 工作会体现为 INP
- 离线策略,缓存 WebGPU 应用下载的 WGSL 与模型资源
- WebGPU: GPU.requestAdapter()(w3.org)
- WebGPU: GPUAdapter.requestDevice()(w3.org)
- WebGPU implementation status(github.com)
- Chrome ships WebGPU(developer.chrome.com)
- News from WWDC25: web technology coming this fall in Safari 26 beta(webkit.org)
规范
| 规范 | 状态 |
|---|---|
| WebGPU | W3C |
| WebGPU: GPU.requestAdapter() | W3C |
| WebGPU: GPUAdapter.requestDevice() | W3C |
| WebGPU Shading Language | W3C |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop) | 部分支持 | 113 → 144 | 高 | 来源 | 12 |
| Chrome (Android) | 支持 | 121 | 高 | 来源 | — |
| Edge (Desktop) | 部分支持 | 113 → 144 | 高 | 来源 | 345 |
| Firefox (Desktop) | 部分支持 | 141 | 高 | 来源 | 67891011 |
| Firefox (Android) | 不支持 | — | 高 | 来源 | 12 |
| Safari (macOS) | 支持 | 26 | 高 | 来源 | — |
| Safari (iOS) | 支持 | 26 | 高 | 来源 | 13 |
| Samsung Internet | 支持 | 25.0 | 高 | 来源 | 14 |
| WebView (Android) | 支持 | 121 | 高 | 来源 | 15 |
- 支持 ChromeOS、macOS、Windows 和 Linux(Linux 仅限 Intel Gen12 及以上 GPU)。
- 支持 ChromeOS、macOS 和 Windows。
- 支持 ChromeOS、macOS、Windows 和 Linux(Linux 仅限 Intel Gen12 及以上 GPU)。
- 支持 ChromeOS、macOS 和 Windows。
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 支持除 Service Worker 之外的所有上下文。见 bug 1942431(https://bugzil.la/1942431)。
- 自 Firefox 141 起支持 Windows。见 bug 1972486(https://bugzil.la/1972486)。
- 自 Firefox 145 起支持 Apple 芯片上的 macOS Tahoe。见 bug 1992212(https://bugzil.la/1992212)。
- 自 Firefox 147 起支持 Apple 芯片上更早的 macOS 版本。见 bug 1993341(https://bugzil.la/1993341)。
- 不支持 Intel CPU 上的 macOS。见 bug 2004105(https://bugzil.la/2004105)。
- 不支持 Linux。见 bug 2006676(https://bugzil.la/2006676)。
- browser-compat-data 未记录 Firefox for Android 的支持。
- 由 browser-compat-data 镜像自 Safari 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。