支持 Android 上的 WebGPU
Chrome 团队非常高兴地宣布,在搭载 Android 12 及更高版本且由 Qualcomm 和 ARM GPU 提供支持的设备上,Chrome 121 中现已默认启用 WebGPU。
我们将逐步扩大支持范围,涵盖更多 Android 设备,包括在不久的将来搭载 Android 11 的设备。此扩展将取决于进一步的测试和优化,以确保在更广泛的硬件配置中提供流畅的体验。请参阅问题 chromium:1497815。
在 Windows 上使用 DXC 而非 FXC 进行着色器编译
Chrome 现在使用强大的 DXC(DirectX 编译器)在配备 SM6+ 图形硬件的 Windows D3D12 计算机上编译着色器。以前,WebGPU 在 Windows 上依赖 FXC(FX 编译器)进行着色器编译。FXC 虽然可以正常运行,但缺少 DXC 中的功能集和性能优化。
初步测试表明,与使用 FXC 相比,使用 DXC 时计算着色器编译速度平均提高了 20%。
计算和渲染通道中的时间戳查询
借助时间戳查询,WebGPU 应用可以精确地(精确到纳秒)衡量其 GPU 命令执行计算和渲染传递所需的时间。它们大量用于深入了解 GPU 工作负载的性能和行为。
当 GPUAdapter
中提供 "timestamp-query"
功能时,您现在可以执行以下操作:
- 请求具有
"timestamp-query"
功能的GPUDevice
。 - 创建一个类型为
"timestamp"
的GPUQuerySet
。 - 使用
GPUComputePassDescriptor.timestampWrites
和GPURenderPassDescriptor.timestampWrites
定义在GPUQuerySet
中的什么位置写入时间戳值。 - 使用
resolveQuerySet()
将时间戳值解析为GPUBuffer
。 - 通过将结果从
GPUBuffer
复制到 CPU,读回时间戳值。 - 将时间戳值解码为
BigInt64Array
。
请参阅以下示例和问题 dawn:1800。
const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("timestamp-query")) {
throw new Error("Timestamp query feature is not available");
}
// Explicitly request timestamp query feature.
const device = await adapter.requestDevice({
requiredFeatures: ["timestamp-query"],
});
const commandEncoder = device.createCommandEncoder();
// Create a GPUQuerySet which holds 2 timestamp query results: one for the
// beginning and one for the end of compute pass execution.
const querySet = device.createQuerySet({ type: "timestamp", count: 2 });
const timestampWrites = {
querySet,
beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
};
const passEncoder = commandEncoder.beginComputePass({ timestampWrites });
// TODO: Set pipeline, bind group, and dispatch work to be performed.
passEncoder.end();
// Resolve timestamps in nanoseconds as a 64-bit unsigned integer into a GPUBuffer.
const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
const resolveBuffer = device.createBuffer({
size,
usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
});
commandEncoder.resolveQuerySet(querySet, 0, 2, resolveBuffer, 0);
// Read GPUBuffer memory.
const resultBuffer = device.createBuffer({
size,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
commandEncoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size);
// Submit commands to the GPU.
device.queue.submit([commandEncoder.finish()]);
// Log compute pass duration in nanoseconds.
await resultBuffer.mapAsync(GPUMapMode.READ);
const times = new BigInt64Array(resultBuffer.getMappedRange());
console.log(`Compute pass duration: ${Number(times[1] - times[0])}ns`);
resultBuffer.unmap();
由于存在计时攻击问题,时间戳查询采用 100 微秒的分辨率进行量化,因此可在精度和安全性之间实现很好的折衷。在 Chrome 浏览器中,您可以在应用开发期间通过在 chrome://flags/#enable-webgpu-developer-features
中启用“WebGPU 开发者功能”标志来停用时间戳量化。如需了解详情,请参阅时间戳查询量化。
由于 GPU 可能会偶尔重置时间戳计数器,从而导致出现意外的值(例如时间戳之间的负增量),因此建议您查看 git diff 变更,该变更为以下 Compute Boids 示例添加了时间戳查询支持。
着色器模块的默认入口点
为了改善开发者体验,您现在可以在创建计算或渲染管道时省略着色器模块的 entryPoint
。如果在着色器代码中找不到着色器阶段的唯一入口点,系统会触发 GPUValidationError。请参阅以下示例和issue dawn:2254。
const code = `
@vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
@builtin(position) vec4f {
const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
return vec4f(pos[i], 0, 1);
}
@fragment fn fragmentMain() -> @location(0) vec4f {
return vec4f(1, 0, 0, 1);
}`;
const module = myDevice.createShaderModule({ code });
const format = navigator.gpu.getPreferredCanvasFormat();
const pipeline = await myDevice.createRenderPipelineAsync({
layout: "auto",
vertex: { module, entryPoint: "vertexMain" },
fragment: { module, entryPoint: "fragmentMain", targets: [{ format }] },
vertex: { module },
fragment: { module, targets: [{ format }] },
});
支持 display-p3 作为 GPUExternalTexture 颜色空间
现在,您可以使用 importExternalTexture()
从 HDR 视频导入 GPUExternalTexture 时设置 "display-p3"
目标色彩空间。了解 WebGPU 如何处理色彩空间。请参阅以下示例和问题 chromium:1330250。
// Create texture from HDR video.
const video = document.querySelector("video");
const texture = myDevice.importExternalTexture({
source: video,
colorSpace: "display-p3",
});
内存堆信息
为了帮助您在应用开发过程中预测内存限制,requestAdapterInfo()
现在公开了 memoryHeaps
信息,例如适配器上可用内存堆的大小和类型。只有在 chrome://flags/#enable-webgpu-developer-features
中启用“WebGPU 开发者功能”标志后,才能使用此实验性功能。请参阅以下示例和问题 dawn:2249。
const adapter = await navigator.gpu.requestAdapter();
const adapterInfo = await adapter.requestAdapterInfo();
for (const { size, properties } of adapterInfo.memoryHeaps) {
console.log(size); // memory heap size in bytes
if (properties & GPUHeapProperty.DEVICE_LOCAL) { /* ... */ }
if (properties & GPUHeapProperty.HOST_VISIBLE) { /* ... */ }
if (properties & GPUHeapProperty.HOST_COHERENT) { /* ... */ }
if (properties & GPUHeapProperty.HOST_UNCACHED) { /* ... */ }
if (properties & GPUHeapProperty.HOST_CACHED) { /* ... */ }
}
Dawn 更新
添加了 wgpu::Instance
上的 HasWGSLLanguageFeature
和 EnumerateWGSLLanguageFeatures
方法,以处理 WGSL 语言功能。请参阅问题 dawn:2260。
借助非标准 wgpu::Feature::BufferMapExtendedUsages
功能,您可以使用 wgpu::BufferUsage::MapRead
或 wgpu::BufferUsage::MapWrite
以及任何其他 wgpu::BufferUsage
创建 GPU 缓冲区。请参阅以下示例并问题 dawn:2204。
wgpu::BufferDescriptor descriptor = {
.size = 128,
.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Uniform
};
wgpu::Buffer uniformBuffer = device.CreateBuffer(&descriptor);
uniformBuffer.MapAsync(wgpu::MapMode::Write, 0, 128,
[](WGPUBufferMapAsyncStatus status, void* userdata)
{
wgpu::Buffer* buffer = static_cast<wgpu::Buffer*>(userdata);
memcpy(buffer->GetMappedRange(), data, sizeof(data));
},
&uniformBuffer);
已记录以下功能:ANGLE 纹理共享、D3D11 多线程保护、隐式设备同步、Norm16 纹理格式、Pass 内的时间戳查询、像素本地存储、着色器功能和多平面格式。
Chrome 团队为 Dawn 创建了一个官方的 GitHub 代码库。
本指南仅涵盖部分重要内容。查看详尽的提交内容列表。
WebGPU 中的新变化
WebGPU 新变化系列中涵盖的所有内容的列表。
Chrome 130
Chrome 129
Chrome 128
Chrome 127
Chrome 126
Chrome 125
Chrome 124
Chrome 123
Chrome 122
Chrome 121
- 支持 Android 上的 WebGPU
- 在 Windows 上使用 DXC 而非 FXC 进行着色器编译
- 计算和渲染通道中的时间戳查询
- 着色器模块的默认入口点
- 支持将 display-p3 用作 GPUExternalTexture 色彩空间
- 内存堆信息
- Dawn 更新
Chrome 120
Chrome 119
Chrome 118
Chrome 117
Chrome 116
- WebCodecs 集成
- GPUAdapter 返回的设备丢失
requestDevice()
- 如果调用
importExternalTexture()
,则保持视频播放流畅 - 规范合规性
- 改善开发者体验
- Dawn 更新