WebGPU'daki (Chrome 121) Yenilikler

François Beaufort
François Beaufort

Android'de WebGPU desteği

Chrome Ekibi olarak, WebGPU'nun artık Qualcomm ve ARM GPU'lar tarafından desteklenen Android 12 ve sonraki sürümleri çalıştıran cihazlarda Chrome 121'de varsayılan olarak etkinleştirildiğini duyurmaktan mutluluk duyuyoruz.

Destek, yakın gelecekte Android 11 çalıştıranlar da dahil olmak üzere daha geniş bir Android cihaz yelpazesini kapsayacak şekilde kademeli olarak genişletilecektir. Bu genişleme, 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. chromium:1497815 numaralı soruna bakı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 derlemesi için FXC yerine DXC kullanma

Chrome artık SM6+ grafik donanımına sahip Windows D3D12 makinelerinde gölgelendiricileri derlemek için DXC'nin (DirectX Derleyici) gücünü kullanıyor. Daha önce WebGPU, Windows'ta gölgelendirici derlemesi için FXC'ye (FX Derleyici) dayanıyordu. FXC işlevsel olsa da DXC'deki özellik grubuna ve performans optimizasyonlarına sahip değildi.

İlk testler, DXC kullanıldığında 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 zaman damgası sorguları

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 hassas bir şekilde ölçmesine olanak tanır. GPU iş yüklerinin performansı ve davranışı hakkında bilgi edinmek için yoğun şekilde kullanılırlar.

"timestamp-query" özelliği bir GPUAdapter'ta kullanıma sunulduğunda aşağıdakileri yapabilirsiniz:

  • "timestamp-query" özelliğine sahip bir GPUDevice isteyin.
  • "timestamp" türüne sahip bir GPUQuerySet oluşturun.
  • GPUQuerySet öğesinde 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 olarak çözün.
  • Sonuçları GPUBuffer'ten CPU'ya kopyalayarak zaman damgası değerlerini geri okuyun.
  • Zaman damgası değerlerinin kodunu BigInt64Array olarak çözme.

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

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 mikrosaniyelik bir çözünürlükle kesirli hale getirilir. Bu, hassasiyet ve güvenlik arasında iyi bir uzlaşma sağlar. Chrome tarayıcıda, uygulamanızın geliştirilmesi sırasında chrome://flags/#enable-webgpu-developer-features adresinde "WebGPU Geliştirici Özellikleri" işaretini etkinleştirerek zaman damgası kesme işlemini devre dışı bırakabilirsiniz. Daha fazla bilgi için Zaman damgası sorguları kesme bölümüne bakın.

GPU'lar zaman damgası sayacını zaman zaman sıfırlayabilir. Bu da zaman damgalarının arasındaki negatif değişimler gibi beklenmedik değerlere neden olabilir. Aşağıdaki Compute Boids örneğine zaman damgası sorgu desteği ekleyen git diff değişikliklerine göz atmanızı öneririz.

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

Gölgelendirici modüllerinin varsayılan giriş noktaları

Geliştirici deneyimini iyileştirmek için artık bir hesaplama veya oluşturma ardışık düzeni oluştururken gölgelendirici modülünüzün entryPoint öğesini atlayabilirsiniz. Gölgelendirici kodunda gölgelendirici aşaması için benzersiz bir giriş noktası bulunamazsa GPUValidationError tetiklenir. Aşağıdaki örneği ve sayı dawn:2254'ü 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 desteği

Artık importExternalTexture() ile HDR videolardan GPUExternalTexture içe aktarırken "display-p3" hedef renk alanını ayarlayabilirsiniz. WebGPU'nin renk alanlarını nasıl işlediğine göz atın. 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 miktarlar ayırırken bellek sınırlamalarını tahmin etmenize yardımcı olmak için requestAdapterInfo() artık bağdaştırıcının kullanılabilir bellek yığınlarının boyutu ve türü gibi memoryHeaps bilgilerini gösterir. Bu deneysel özelliğe yalnızca chrome://flags/#enable-webgpu-developer-features adresindeki "WebGPU Geliştirici Özellikleri" işareti etkinleştirildiğinde erişilebilir. Aşağıdaki örneği ve sorun dawn:2249'u inceleyin.

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)   { /* ... */ }
}
Adaptör bilgilerinde bellek yığınlarını gösteren https://webgpureport.org ekran görüntüsü.
https://webgpureport.org adresinde gösterilen bağdaştırıcılar bilgileri bellek yığınları.

Şafak güncellemeleri

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

Standart olmayan wgpu::Feature::BufferMapExtendedUsages özelliği, wgpu::BufferUsage::MapRead veya wgpu::BufferUsage::MapWrite ve başka bir wgpu::BufferUsage ile GPU arabelleği oluşturmanıza olanak tanır. Aşağıdaki örneği ve dawn:2204 sorununu inceleyin.

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 Doku Paylaşımı, D3D11 çoklu iş parçacıklı korumalı, Dolaysız Cihaz Senkronizasyonu, Norm16 doku biçimleri, Geçiş İçinde Zaman Damgası Sorgusu, Piksel Yerel Depolama, Gölgelendirici Özellikleri ve Çok Düzlemli Biçimler.

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

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

WebGPU'daki Yenilikler

WebGPU'daki Yenilikler serisinde ele alınan tüm konuların listesi.

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