在 Android 上支持 WebGPU
Chrome 团队很高兴地宣布,在搭载 Android 12 及更高版本的设备上,由 Qualcomm GPU 和 ARM GPU 提供支持,在 Chrome 121 中,WebGPU 现在默认处于启用状态。
支持将逐步扩大,以涵盖更广泛的 Android 设备,包括在不久的将来运行 Android 11 的设备。此次扩展将有赖于进一步的测试和优化,以确保跨更广泛的硬件配置提供顺畅的体验。请参阅问题 chromium:1497815。
在 Windows 上使用 DXC(而非 FXC)进行着色器编译
现在,Chrome 利用强大的 DXC(DirectX 编译器)在配备 SM6+ 图形硬件的 Windows D3D12 计算机上编译着色器。以前,WebGPU 依靠 FXC(FX 编译器)在 Windows 上进行着色器编译。尽管可正常运行,但 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。请参阅以下示例并问题 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) { /* ... */ }
}
黎明动态
添加了 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 纹理格式、时间戳查询 - 通道内、Pixel 本地存储、着色器功能以及多平面格式{/15。
Chrome 团队为 Dawn 创建了一个官方 GitHub 代码库。
这仅涵盖了部分重要的亮点。查看详尽的提交内容列表。
WebGPU 的新变化
WebGPU 的新变化系列中涵盖的所有内容的列表。
Chrome 125
Chrome 124
Chrome 123
Chrome 122
Chrome 121
- 在 Android 上支持 WebGPU
- 在 Windows 上使用 DXC(而非 FXC)进行着色器编译
- 计算和渲染通道中的时间戳查询
- 着色器模块的默认入口点
- 支持将 display-p3 作为 GPUExternalTexture 颜色空间
- 内存堆信息
- 黎明动态
Chrome 120
Chrome 119
Chrome 118
Chrome 117
Chrome 116
- WebCodecs 集成
- GPUAdapter 返回的设备
requestDevice()
- 在调用
importExternalTexture()
时确保视频播放流畅 - 规范一致性
- 改善开发者体验
- 黎明动态