在 Android 上支持 WebGPU
Chrome 团队很高兴地宣布,在搭载 Android 12 及更高版本且由 Qualcomm 和 ARM GPU 提供支持的设备上,Chrome 121 现已默认启用 WebGPU。
支持范围将逐步扩大,以便在不久的将来涵盖更广泛的 Android 设备,包括搭载 Android 11 的设备。此扩展将取决于进一步的测试和优化,以确保在更广泛的硬件配置中获得无缝体验。请参阅问题 chromium:1497815。
在 Windows 上使用 DXC 而非 FXC 进行着色器编译
Chrome 现在使用 DXC (DirectX Compiler) 的强大功能在配备 SM6+ 图形硬件的 Windows D3D12 机器上编译着色器。以前,WebGPU 依赖于 FXC (FX Compiler) 在 Windows 上进行着色器编译。虽然 FXC 功能正常,但缺少 DXC 中提供的特征集和性能优化。
初始测试表明,与 FXC 相比,使用 DXC 时计算着色器编译速度平均提高了 20%。
计算和渲染通道中的时间戳查询
借助时间戳查询,WebGPU 应用可以精确测量(精确到纳秒)其 GPU 命令执行计算和渲染通道所需的时间。它们被广泛用于深入了解 GPU 工作负载的性能和行为。
当 "timestamp-query" 功能在 GPUAdapter 中可用时,您现在可以执行以下操作:
- 请求具有
"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) { /* ... */ }
}
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 纹理格式、通道内时间戳查询、像素本地存储、着色器功能和多平面格式。
Chrome 团队已为 Dawn 创建了一个官方 GitHub 代码库。
这仅涵盖了一些主要亮点。查看提交的详尽列表。
WebGPU 的新变化
WebGPU 新变化系列中涵盖的所有内容的列表。
Chrome 147-148
Chrome 146
Chrome 145
Chrome 144
- WGSL subgroup_id 扩展
- WGSL uniform_buffer_standard_layout 扩展
- Linux 上的 WebGPU
- 更快的 writeBuffer 和 writeTexture
- Dawn 更新
Chrome 143
Chrome 142
Chrome 141
Chrome 140
- 设备请求会占用适配器
- 在使用了纹理视图的情况下使用纹理的简写
- WGSL textureSampleLevel 支持 1D 纹理
- 弃用 bgra8unorm 只读存储纹理使用情况
- 移除 GPUAdapter isFallbackAdapter 属性
- Dawn 更新
Chrome 139
Chrome 138
Chrome 137
- 将纹理视图用于 externalTexture 绑定
- 复制缓冲区时无需指定偏移量和大小
- WGSL workgroupUniformLoad 使用指向原子的指针
- GPUAdapterInfo powerPreference 属性
- 移除 GPURequestAdapterOptions compatibilityMode 属性
- Dawn 更新
Chrome 136
Chrome 135
- 允许使用 null 绑定组布局创建流水线布局
- 允许视口超出渲染目标边界
- 更轻松地访问 Android 上的实验性兼容模式
- 移除 maxInterStageShaderComponents 限制
- Dawn 更新
Chrome 134
Chrome 133
- 额外的 unorm8x4-bgra 和 1 分量顶点格式
- 允许使用未定义的值请求未知限制
- WGSL 对齐规则变更
- 使用 discard 提升 WGSL 性能
- 将 VideoFrame displaySize 用于外部纹理
- 使用 copyExternalImageToTexture 处理具有非默认方向的图片
- 提升开发者体验
- 使用 featureLevel 启用兼容模式
- 实验性子群组功能清理
- 弃用 maxInterStageShaderComponents 限制
- Dawn 更新
Chrome 132
- 纹理视图使用情况
- 32 位浮点纹理混合
- GPUDevice adapterInfo 属性
- 使用无效格式配置画布上下文会抛出 JavaScript 错误
- 对纹理的过滤采样器限制
- 扩展子群组实验
- 提升开发者体验
- 实验性支持 16 位标准化纹理格式
- Dawn 更新
Chrome 131
- WGSL 中的剪辑距离
- GPUCanvasContext getConfiguration()
- 点和线图元不得具有深度偏差
- 子群组的包含扫描内置函数
- 实验性支持多重间接绘制
- 着色器模块编译选项 strict math
- 移除 GPUAdapter requestAdapterInfo()
- Dawn 更新
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
- copyExternalImageToTexture()
copyExternalImageToTexture()中支持 HTMLImageElement 和 ImageData - 实验性支持读写和只读存储纹理
- Dawn 更新
Chrome 117
Chrome 116
- WebCodecs 集成
- GPUAdapter
requestDevice()返回的丢失设备 - 如果调用
importExternalTexture(),则保持视频播放流畅 - 规范一致性
- 提升开发者体验
- Dawn 更新
Chrome 115
Chrome 114
Chrome 113
- 在
importExternalTexture()中使用 WebCodecs VideoFrame 来源