WebGPU'daki (Chrome 121) Yenilikler

François Beaufort
François Beaufort

Android'de WebGPU'yu destekleme

Chrome Ekibi, Qualcomm ve ARM GPU'lar tarafından desteklenen Android 12 ve sonraki sürümlerin yüklü olduğu cihazlarda Chrome 121'de WebGPU'nun varsayılan olarak etkinleştirildiğini duyurmaktan heyecan duyuyor.

Destek, yakın gelecekte Android 11'de çalışanlar da dahil olmak üzere daha geniş bir Android cihaz yelpazesini kapsayacak şekilde kademeli olarak genişletilecektir. Bu genişletme, daha geniş bir donanım yapılandırması yelpazesinde sorunsuz bir deneyim sağlamak için daha fazla test ve optimizasyona bağlı olacaktır. issue chromium:1497815 başlıklı makaleye göz atın.

Android için Chrome'da çalışan WebGPU örneğinin ekran görüntüsü.
Android için Chrome'da çalışan WebGPU örneği.

Windows'da gölgelendirici derleme için FXC yerine DXC kullanma

Chrome artık SM6+ grafik donanımıyla donatılmış Windows D3D12 makinelerindeki gölgelendiricileri derlemek için DXC'nin (DirectX Compiler) gücünden yararlanıyor. Daha önce WebGPU, Windows'da gölgelendirici derlemesi için FXC'ye (FX Compiler) dayanıyordu. FXC işlevsel olsa da DXC'de bulunan özellik grubuna ve performans optimizasyonlarına sahip değildi.

İlk testler, DXC kullanılırken FXC'ye kıyasla hesaplama gölgelendirici derleme hızında ortalama% 20 artış olduğunu gösteriyor.

Bilgi işlem ve oluşturma geçişlerinde sorgulara zaman damgası ekleme

Zaman damgası sorguları, WebGPU uygulamalarının GPU komutlarının hesaplama ve oluşturma geçişlerini yürütmesinin ne kadar sürdüğünü nanosaniyeye kadar hassasiyetle ölçmesine olanak tanır. Bu metrikler, GPU iş yüklerinin performansı ve davranışı hakkında bilgi edinmek için yoğun bir şekilde kullanılır.

"timestamp-query" özelliği GPUAdapter içinde kullanılabildiğinde artık şunları yapabilirsiniz:

  • "timestamp-query" özelliğiyle GPUDevice isteğinde bulunun.
  • "timestamp" türünde bir GPUQuerySet oluşturun.
  • GPUQuerySet içinde zaman damgası değerlerinin nereye yazılacağını tanımlamak için GPUComputePassDescriptor.timestampWrites ve GPURenderPassDescriptor.timestampWrites öğelerini kullanın.
  • Zaman damgası değerlerini resolveQuerySet() ile GPUBuffer biçimine dönüştürün.
  • GPUBuffer sonuçlarını CPU'ya kopyalayarak zaman damgası değerlerini geri okuyun.
  • Zaman damgası değerlerini BigInt64Array olarak kod çözün.

Aşağıdaki örneğe bakın ve dawn:1800 sorununu bildirin.

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();

Zamanlama saldırısı endişeleri nedeniyle, zaman damgası sorguları 100 mikrosaniye çözünürlükle nicelleştirilir. Bu, hassasiyet ve güvenlik arasında iyi bir denge sağlar. Chrome tarayıcıda, uygulamanızın geliştirilmesi sırasında chrome://flags/#enable-webgpu-developer-features adresinde "WebGPU Developer Features" işaretini etkinleştirerek zaman damgası nicemlemesini devre dışı bırakabilirsiniz. Daha fazla bilgi için Zaman damgası sorgularının nicemlenmesi başlıklı makaleyi inceleyin.

GPU'lar zaman damgası sayacını zaman zaman sıfırlayabileceğinden bu durum, zaman damgaları arasında negatif delta gibi beklenmedik değerlere yol açabilir. Bu nedenle, aşağıdaki Compute Boids örneğine zaman damgası sorgu desteği ekleyen git diff değişikliklerini incelemenizi öneririz.

Zaman damgası sorgusu içeren Compute Boids örneğinin ekran görüntüsü.
Zaman damgası sorgusu içeren Compute Boids örneği.

Shader modüllerine varsayılan giriş noktaları

Geliştirici deneyimini iyileştirmek için artık bir işlem veya oluşturma hattı oluştururken gölgelendirici modülünüzün entryPoint kısmını atlayabilirsiniz. Shader kodunda shader aşaması için benzersiz bir giriş noktası bulunamazsa GPUValidationError tetiklenir. Aşağıdaki örneği ve dawn:2254 sorununu inceleyin.

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 }] },
});

GPUExternalTexture renk alanı olarak display-p3'ü destekleme

Artık importExternalTexture() ile HDR videolardan GPUExternalTexture içe aktarırken "display-p3" hedef renk alanını ayarlayabilirsiniz. WebGPU'nun renk uzaylarını nasıl işlediğini öğrenin. Aşağıdaki örneğe ve chromium:1330250 sorununa bakın.

// Create texture from HDR video.
const video = document.querySelector("video");
const texture = myDevice.importExternalTexture({
  source: video,
  colorSpace: "display-p3",
});

Bellek yığınları bilgileri

Uygulamanızın geliştirilmesi sırasında büyük miktarlarda bellek ayırırken bellek sınırlamalarını tahmin etmenize yardımcı olmak için requestAdapterInfo() artık bağdaştırıcıda bulunan bellek yığınlarının boyutu ve türü gibi memoryHeaps bilgilerini gösteriyor. Bu deneysel özelliğe yalnızca chrome://flags/#enable-webgpu-developer-features adresindeki "WebGPU Developer Features" işareti etkinleştirildiğinde erişilebilir. Aşağıdaki örneğe ve dawn:2249 sorununa bakın.

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 adresinin, adaptör bilgilerinde bellek yığınlarını gösteren ekran görüntüsü.
https://webgpureport.org adresinde gösterilen bağdaştırıcı bilgisi bellek yığınları.

Dawn güncellemeleri

WGSL dil özelliklerini işlemek için wgpu::Instance üzerindeki HasWGSLLanguageFeature ve EnumerateWGSLLanguageFeatures yöntemleri eklendi. dawn:2260 numaralı soruna bakın.

Standart olmayan wgpu::Feature::BufferMapExtendedUsages özelliği, wgpu::BufferUsage::MapRead veya wgpu::BufferUsage::MapWrite ile diğer wgpu::BufferUsage'leri kullanarak GPU arabelleği oluşturmanıza olanak tanır. Aşağıdaki örneğe ve dawn:2204 sorununa bakın.

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);

Aşağıdaki özellikler belgelenmiştir: ANGLE Texture Sharing, D3D11 multithread protected, Implicit Device Synchronization, Norm16 texture formats, Timestamp Query Inside Passes, Pixel Local Storage, Shader Features ve Multi Planar Formats.

Chrome Ekibi, Dawn için resmi bir GitHub deposu oluşturdu.

Bu özet yalnızca önemli noktalardan bazılarını kapsar. Kapsamlı commit listesine göz atın.

WebGPU'daki yenilikler

WebGPU'daki Yenilikler serisinde ele alınan her şeyin listesi.

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

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