WebGPU 的新变化 (Chrome 128)

François Beaufort
François Beaufort

对子群组进行实验

子群组功能支持 SIMD 级并行处理,让同一组中的线程能够进行通信并执行集体数学运算(例如计算 16 个数字的总和)。这提供了一种高效的跨线程数据共享方式。

子组提案的最小实现可在 chrome://flags/#enable-unsafe-webgpu 的“Unsafe WebGPU Support”(不安全的 WebGPU 支持)标志后面用于本地测试。

您还可以注册参与起源试用,在您的网站上使用真实用户试用子群组。如需了解如何准备网站以使用源代码试用版,请参阅开始使用源代码试用版。源试用将从 Chrome 128 到 Chrome 131 进行(截止时间为 2025 年 2 月 19 日)。请参阅意图实验

GPUAdapter 中提供 "subgroups" 功能时,请请求具有此功能的 GPUDevice,以便在 WGSL 中获得子组支持,并检查其 minSubgroupSizemaxSubgroupSize 限制。

您还需要在 WGSL 代码中使用 enable subgroups; 明确启用此扩展。启用后,您可以使用以下增强功能:

  • subgroup_invocation_id:子组中线程索引的内置值。
  • subgroup_size:用于访问子群组大小的内置值。
  • subgroupBallot(value):返回一组位字段,其中与 subgroup_invocation_id 对应的位为 1,表示相应有效调用的 value 为 true;否则为 0。
  • subgroupBroadcast(value, id):将调用中的 value 广播到子组中的所有调用,其中 subgroup_invocation_idid 匹配。注意:id 必须是编译时常量。

我们日后会添加更多内置函数,例如 subgroupAddsubgroupAllsubgroupElectsubgroupShuffle。请参阅问题 354738715

如需允许在子组运算中使用 f16,请使用 "subgroups""subgroups-f16""shader-f16" 功能请求 GPUDevice,然后使用 enable f16, subgroups, subgroups_f16; 在 WGSL 代码中启用它。

以下代码段提供了一个基础,供您调整和发掘子群组的潜力。

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("subgroups")) {
  throw new Error("Subgroups support is not available");
}
// Explicitly request subgroups support.
const device = await adapter.requestDevice({
  requiredFeatures: ["subgroups"],
});

const shaderModule = device.createShaderModule({ code: `
  enable subgroups;

  var<workgroup> wgmem : u32;

  @group(0) @binding(0)
  var<storage, read> inputs : array<u32>;

  @group(0) @binding(1)
  var<storage, read_write> output : array<u32>;

  @compute @workgroup_size(64)
  fn main(@builtin(subgroup_size) subgroupSize : u32,
          @builtin(subgroup_invocation_id) id : u32,
          @builtin(local_invocation_index) lid : u32) {
    // One thread per workgroup writes the value to workgroup memory.
    if (lid == 0) {
      wgmem = inputs[lid];
    }
    workgroupBarrier();
    var v = 0u;

    // One thread per subgroup reads the value from workgroup memory
    // and shares that value with every other thread in the subgroup
    // to reduce local memory bandwidth.
    if (id == 0) {
      v = wgmem;
    }
    v = subgroupBroadcast(v, 0);
    output[lid] = v;
  }`,
});

// Send the appropriate commands to the GPU...

废弃了为线条和点设置深度偏差的功能

WebGPU 规范变更:如果渲染管道的拓扑为线条或点类型,将 depthBiasdepthBiasSlopeScaledepthBiasClamp 设置为非零值会导致验证错误。为让开发者有足够的时间更新其代码,DevTools 控制台中会显示一条关于即将进行的验证的警告,同时在这种情况下还会强制将值设为 0。请参阅问题 352567424

使用 preventDefault 时,隐藏未捕获的错误开发者工具警告

如果已注册 uncapturederror 的事件监听器,并且在事件监听器回调中调用了事件 preventDefault() 方法,则 DevTools 控制台中将不再显示有关 uncapturederror 事件的警告。此行为与 JavaScript 中的事件处理方式一致。请参阅以下示例和问题 40263619

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

device.addEventListener("uncapturederror", (event) => {
  // Prevents browser warning to show up in the DevTools Console.
  event.preventDefault();

  // TODO: Handle event.error
});

WGSL 会先插值采样,然后执行以下操作之一:

借助 WGSL interpolate 属性,您可以管理用户定义的 IO 数据插值。现在,新的插值采样参数 first(默认)和 either 可让您进行更精细的控制:first 使用基元第一个顶点的值,而 either 允许使用第一个或最后一个顶点。请参阅问题 340278447

Dawn 更新

用于处理异步操作的 Dawn 的 WGPUFuture 实现现已完成。关键概念包括用于机会性事件处理的 wgpuInstanceProcessEvents 和用于定义回调位置的 WGPUCallbackMode。WGPUFuture 表示具有无限生命周期的一次性事件,而 wgpuInstanceWaitAny 会等待任何 Future 完成或超时。请参阅问题 42240932

Surface::GetCapabilities() 现在不会报告 CompositeAlphaMode::Auto 值。它仍然有效,并且等同于 Surface::GetCapabilities().alphaMode[0]。请参阅问题 292

OpenGL 后端现在支持 Surface,并针对每个 Present() 调用执行 y 翻转 blitting。请参阅问题 344814083

Adapter::GetProperties() 方法已被弃用,请改用 Adapter::GetInfo()

外部贡献者 Jaswant 重写了所有 CMake 文件,使其更易于更新,并支持预构建。如需了解如何在 CMake 项目中使用 Dawn,请参阅快速入门指南

本文仅介绍了一些主要亮点。查看详尽的提交内容列表

WebGPU 中的新变化

WebGPU 新变化系列中涵盖的所有内容的列表。

Chrome 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113