WebGPU 新功能's (Chrome 約 121)

François Beaufort
François Beaufort

在 Android 上支援 WebGPU

Chrome 團隊很高興在此宣布,在搭載 Android 12 以上版本的裝置 (搭載 Android 12 以上版本) 中,WebGPU 現已預設啟用 (搭載 Qualcomm 和 ARM GPU)。

這項功能會逐步擴大支援範圍,在不久後將支援更多 Android 裝置,包括搭載 Android 11 的裝置。這項擴充功能將根據進一步的測試與最佳化調整,以確保各種硬體配置都能提供順暢的體驗。請參閱問題 chromium:1497815

在 Android 版 Chrome 上執行的 WebGPU 範例螢幕截圖。
在 Android 版 Google Chrome 上執行的 WebGPU 範例。

在 Windows 上使用 DXC (而非 FXC) 進行著色器編譯

Chrome 現在運用 DXC (DirectX 編譯器) 的強大功能,在配備 SM6 以上圖形硬體的 Windows D3D12 機器上編譯著色器。WebGPU 原先是依賴 FXC (FX 編譯器) 在 Windows 上進行著色器編譯。雖然可正常運作,但 FXC 缺乏 DXC 中的功能集和效能最佳化。

初始測試顯示,使用 DXC 時,運算著色器編譯速度平均可提高 20% (與 FXC 相比)。

運算和轉譯傳遞中的時間戳記查詢

時間戳記查詢可讓 WebGPU 應用程式準確測量 (最小單位為奈秒) 執行運算和算繪傳遞所需的時間。經常用於深入瞭解 GPU 工作負載的效能和行為。

GPUAdapter 提供 "timestamp-query" 功能時,您現在可以執行下列操作:

請參考下列範例並發出 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 changes,瞭解如何將時間戳記查詢支援加入以下的 Compute Boids 範例。

顯示時間戳記查詢的 Compute Boids 範例螢幕截圖。
採用時間戳記查詢的 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 開發人員功能」旗標啟用時,才能使用這項實驗功能。請參閱以下範例和問題發生時間: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)   { /* ... */ }
}
https://webgpureport.org 的螢幕截圖,其中顯示轉接器資訊中的記憶體堆積。
https://webgpureport.org 中顯示的轉接器資訊記憶體堆積。

黎明更新

新增了 wgpu::Instance 上的 HasWGSLLanguageFeatureEnumerateWGSLLanguageFeatures 方法以處理 WGSL 語言功能。請參閱問題 dawn:2260

非標準 wgpu::Feature::BufferMapExtendedUsages 功能可讓您使用 wgpu::BufferUsage::MapReadwgpu::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 本機儲存空間著色器功能著色器功能

Chrome 團隊已打造 Dawn 的官方 GitHub 存放區

這僅涵蓋部分重點功能。查看完整的修訂版本清單

WebGPU 的新功能

WebGPU 新功能」系列中已說明的所有功能清單。

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