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

François Beaufort
François Beaufort

รองรับ WebGPU ใน Android

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

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

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

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

ตอนนี้ Chrome ใช้ความสามารถของ DXC (DirectX Compiler) เพื่อคอมไพล์เชดเดอร์ในเครื่อง Windows D3D12 ที่มีฮาร์ดแวร์กราฟิก SM6 ขึ้นไป ก่อนหน้านี้ WebGPU อาศัย FXC (FX Compiler) สำหรับการคอมไพล์ shader ใน 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 คุณสามารถปิดใช้การปันส่วนการประทับเวลาได้โดยเปิดใช้Flag "ฟีเจอร์สำหรับนักพัฒนาซอฟต์แวร์ WebGPU" ที่ chrome://flags/#enable-webgpu-developer-features ในระหว่างการพัฒนาแอป ดูข้อมูลเพิ่มเติมที่การปันส่วนการค้นหาการประทับเวลา

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

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

จุดเข้าเริ่มต้นไปยังโมดูล Shader

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

ตอนนี้คุณตั้งค่า"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 เช่น ขนาดและประเภทของกองหน่วยความจำที่มีอยู่ในอะแดปเตอร์ เพื่อช่วยให้คุณคาดการณ์ข้อจำกัดของหน่วยความจำเมื่อจัดสรรหน่วยความจำจำนวนมากในระหว่างการพัฒนาแอป ฟีเจอร์ทดลองนี้เข้าถึงได้เมื่อเปิดใช้Flag "WebGPU Developer Features" ที่ chrome://flags/#enable-webgpu-developer-features เท่านั้น โปรดดูตัวอย่างต่อไปนี้และปัญหา 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

การอัปเดต 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, การค้นหาการประทับเวลาภายในพาส, พื้นที่เก็บข้อมูลในอุปกรณ์ของพิกเซล, ฟีเจอร์ Shader และรูปแบบหลายระนาบ

ทีม Chrome ได้สร้างที่เก็บ GitHub อย่างเป็นทางการสำหรับ 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