มีอะไรใหม่ใน WebGPU (Chrome 121)

François Beaufort
François Beaufort

รองรับ WebGPU ใน Android

ทีม Chrome ยินดีที่จะประกาศว่าขณะนี้ WebGPU จะเปิดใช้งานโดยค่าเริ่มต้นใน Chrome 121 ในอุปกรณ์ที่ใช้ Android 12 ขึ้นไป ซึ่งขับเคลื่อนโดย Qualcomm และ ARM GPU

เราจะทยอยขยายการรองรับให้ครอบคลุมอุปกรณ์ Android หลากหลายรุ่นมากขึ้น รวมถึงอุปกรณ์ Android 11 ในอนาคตอันใกล้ การขยายตัวนี้จะขึ้นอยู่กับการทดสอบและการเพิ่มประสิทธิภาพเพิ่มเติม เพื่อให้มั่นใจว่าผู้ใช้จะได้รับประสบการณ์การใช้งานที่ราบรื่นไม่ว่าจะใช้การกำหนดค่าฮาร์ดแวร์แบบใด ดูปัญหา chromium:1497815

ภาพหน้าจอของตัวอย่าง WebGPU ที่ทำงานใน Chrome สำหรับ Android
ตัวอย่าง WebGPU ที่ทำงานบน Chrome สำหรับ Android

ใช้ DXC แทน FXC สำหรับการคอมไพล์ตัวปรับแสงเงาบน Windows

ปัจจุบัน Chrome ใช้ศักยภาพของ DXC (DirectX Compiler) เพื่อคอมไพล์ตัวปรับแสงเงาในเครื่อง Windows D3D12 ที่ติดตั้งฮาร์ดแวร์กราฟิก SM6+ ก่อนหน้านี้ WebGPU ต้องใช้ FXC (FX Compiler) ในการคอมไพล์ตัวปรับแสงเงาบน Windows ขณะทำงาน แต่ FXC ไม่มีชุดฟีเจอร์และการเพิ่มประสิทธิภาพที่มีอยู่ใน DXC

การทดสอบเริ่มต้นแสดงให้เห็นว่าความเร็วในการคอมไพล์ตัวปรับแสงเงาสำหรับการประมวลผลเพิ่มขึ้นเฉลี่ย 20% เมื่อใช้ DXC เทียบกับ FXC

การค้นหาการประทับเวลาในการประมวลผลและแสดงผลบัตร

การค้นหาการประทับเวลาช่วยให้แอปพลิเคชัน WebGPU วัดระยะเวลาที่คำสั่ง GPU ใช้ในการประมวลผลและแสดงผลบัตรได้อย่างแม่นยํา (จนถึงระดับนาโนวินาที) มีการใช้ข้อมูลเชิงลึกเหล่านี้เป็นอย่างมากเพื่อรับข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพและลักษณะการทำงานของภาระงาน GPU

เมื่อฟีเจอร์ "timestamp-query" พร้อมใช้งานใน GPUAdapter ตอนนี้คุณจะทำสิ่งต่อไปนี้ได้

  • ขอรับ GPUDevice ด้วยฟีเจอร์ "timestamp-query"
  • สร้าง GPUQuerySet ประเภท "timestamp"
  • ใช้ GPUComputePassDescriptor.timestampWrites และ GPURenderPassDescriptor.timestampWrites เพื่อระบุตำแหน่งที่จะเขียนค่าการประทับเวลาใน GPUQuerySet
  • แก้ค่าการประทับเวลาเป็น GPUBuffer ด้วย resolveQuerySet()
  • อ่านค่าการประทับเวลากลับมาโดยคัดลอกผลลัพธ์จาก 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 คุณสามารถปิดใช้การวัดปริมาณการประทับเวลาได้โดยการเปิดใช้ธง "ฟีเจอร์สำหรับนักพัฒนาซอฟต์แวร์ WebGPU" ที่ chrome://flags/#enable-webgpu-developer-features ระหว่างการพัฒนาแอป ดูการวัดปริมาณของคำค้นหาการประทับเวลาเพื่อดูข้อมูลเพิ่มเติม

เนื่องจาก GPU อาจรีเซ็ตตัวนับการประทับเวลาเป็นครั้งคราว ซึ่งอาจทำให้เกิดค่าที่ไม่คาดคิด เช่น เดลต้าเป็นลบระหว่างการประทับเวลา เราจึงขอแนะนำให้คุณดูการเปลี่ยนแปลงความแตกต่างของ git ที่เพิ่มการสนับสนุนการค้นหาการประทับเวลาลงในตัวอย่าง Compute Boids ต่อไปนี้

ภาพหน้าจอของตัวอย่าง Compute Boids ที่มีการค้นหาการประทับเวลา
ตัวอย่าง Compute Boids ที่มีการค้นหาการประทับเวลา

จุดแรกเข้าเริ่มต้นของโมดูลตัวปรับแสงเงา

เพื่อปรับปรุงประสบการณ์ของนักพัฒนาแอป ตอนนี้คุณสามารถละเว้น entryPoint ของโมดูลตัวปรับแสงเงาเมื่อสร้างไปป์ไลน์การประมวลผลหรือแสดงผล หากไม่พบจุดแรกเข้าที่ไม่ซ้ำกันสำหรับขั้นตอนตัวปรับแสงเงาในโค้ดตัวปรับแสงเงา ระบบจะทริกเกอร์ GPUValidationError ดูตัวอย่างต่อไปนี้และปัญหารุ่งเช้า: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

ตอนนี้คุณสามารถกำหนดพื้นที่สีปลายทาง "display-p3" ได้เมื่อนำเข้า GPUExternalTexture จากวิดีโอ HDR ด้วย importExternalTexture() ดูวิธีที่ 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-features เท่านั้น ดูตัวอย่างต่อไปนี้และปัญหารุ่งเช้า: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

ข้อมูลอัปเดตเกี่ยวกับ Dawn

เพิ่มเมธอด HasWGSLLanguageFeature และ EnumerateWGSLLanguageFeatures ใน wgpu::Instance เพื่อจัดการฟีเจอร์ภาษา WGSL ดูปัญหา dawn:2260

ฟีเจอร์ wgpu::Feature::BufferMapExtendedUsages ที่ไม่ใช่แบบมาตรฐานช่วยให้คุณสร้างบัฟเฟอร์ GPU ด้วย wgpu::BufferUsage::MapRead หรือ wgpu::BufferUsage::MapWrite และ wgpu::BufferUsage อื่นๆ ได้ ดูตัวอย่างและปัญหา 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, Timestamp Query Inside Passes, Pixel Local Storage, ฟีเจอร์ Shader และรูปแบบ Multi Planar{/15 Multi Planar

ทีม Chrome ได้สร้างที่เก็บ GitHub อย่างเป็นทางการสำหรับ Dawn แล้ว

ทั้งหมดนี้พูดถึงไฮไลต์สำคัญเพียงบางส่วน ดูรายการสัญญาผูกมัดอย่างละเอียด

มีอะไรใหม่ใน 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