WebGPU 新功能's (Chrome 約 121)

François Beaufort
François Beaufort

在 Android 上支援 WebGPU

Chrome 團隊很高興在此宣布,在搭載 Android 12 以上版本、採用 Qualcomm 和 ARM GPU 的裝置上,Chrome 121 預設會啟用 WebGPU。

我們會陸續擴大支援範圍,納入更多 Android 裝置,包括不久後搭載 Android 11 的裝置。隨著這項拓展計畫需要進一步的測試和最佳化,才能確保使用更廣泛的硬體配置都能享有流暢的體驗。請參閱問題 chromium:1497815

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

在 Windows 上使用 DXC 而非 FXC 編譯著色器

Chrome 現在會使用 DXC (DirectX Compiler) 的強大功能,在搭載 SM6+ 圖形硬體的 Windows D3D12 電腦上編譯著色器。WebGPU 先前必須使用 FXC (FX 編譯器) 在 Windows 上進行著色器編譯。雖然可正常運作,但 FXC 缺少 DXC 中的功能集和效能最佳化。

與 FXC 相比,初始測試顯示使用 DXC 時的運算著色器編譯速度平均增加 20%。

計算和轉譯票證時的時間戳記

透過時間戳記查詢,WebGPU 應用程式可以精確測量 GPU 指令執行運算和轉譯傳遞作業所需的時間。想要深入瞭解 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 瀏覽器中,您可以啟用「WebGPU 開發人員功能」來停用時間戳記量化功能在開發應用程式期間,標記chrome://flags/#enable-webgpu-developer-features。詳情請參閱「時間戳記查詢量化」。

GPU 偶爾會重設時間戳記計數器,這可能會導致時間戳記之間出現負差異 (例如負差異),因此建議您參考 git diff 變更,讓下列 Compute Boids 範例支援時間戳記查詢功能。

含有時間戳記查詢的 Compute Boids 範例螢幕截圖。
含有時間戳記查詢的 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 資訊,例如轉接器可用的記憶體堆積大小和類型。這項實驗功能僅適用於「WebGPU 開發人員功能」chrome://flags/#enable-webgpu-developer-featuresflag 參數已啟用。請參考以下範例和問題 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)   { /* ... */ }
}
https://webgpureport.org 螢幕截圖,內含轉接程式資訊中的記憶體堆積。
https://webgpureport.org 上顯示的轉接器資訊記憶體堆積。

日出最新消息

已新增 wgpu::InstanceHasWGSLLanguageFeatureEnumerateWGSLLanguageFeatures 方法,以處理 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 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