WebGPU'daki (Chrome 121) Yenilikler

François Beaufort
François Beaufort

Android'de WebGPU'yu destekleme

Chrome ekibi, WebGPU'nun artık Android 12 ve sonraki sürümleri çalıştıran ve Qualcomm ile ARM GPU'lar tarafından desteklenen Chrome 121'de varsayılan olarak etkinleştirildiğini duyurmanın heyecanını yaşıyor.

Bu destek, yakında Android 11 çalıştıranlar da dahil olmak üzere daha çeşitli Android cihazları kapsayacak şekilde kademeli olarak genişletilecektir. Bu genişleme, daha geniş bir donanım yapılandırması aralığında sorunsuz bir deneyim sağlamak için daha ayrıntılı testler ve optimizasyona bağlı olacak. Sorun chrome:1497815 bölümüne 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'yi 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. WebGPU daha önce Windows'da gölgelendirici derleme için FXC'yi (FX Derleyici) kullanıyordu. Çalışırken FXC, DXC'deki özellik grubundan ve performans optimizasyonlarından yoksundu.

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

Bilgi işlem ve oluşturma kartlarındaki zaman damgası sorguları

Zaman damgası sorguları, WebGPU uygulamalarının GPU komutlarının işlem ve oluşturma geçişlerini yürütmek için ne kadar zaman aldığını hassas bir şekilde (nanosaniyeye kadar) ölçmesine olanak tanır. Bunlar GPU iş yüklerinin performansı ve davranışı hakkında bilgi edinmek için yaygın olarak kullanılır.

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

  • "timestamp-query" özelliğiyle bir GPUDevice isteyin.
  • "timestamp" türünde 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.
  • resolveQuerySet() ile zaman damgası değerlerini GPUBuffer olarak çözümleyin.
  • Sonuçları GPUBuffer konumundan CPU'ya kopyalayarak zaman damgası değerlerini geri okuyun.
  • Zaman damgası değerlerinin kodunu BigInt64Array olarak çözün.

Aşağıdaki örneği inceleyin ve dawn:1800 sayısını inceleyin.

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ı nedeniyle, zaman damgası sorguları 100 mikrosaniyelik bir çözünürlükle nicelenir, bu da hassasiyet ile 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 konumunda "WebGPU Geliştirici Özellikleri" işaretini etkinleştirerek zaman damgası niceliğini devre dışı bırakabilirsiniz. Daha fazla bilgi edinmek için Zaman damgası sorgularının hesaplanması bölümüne bakın.

GPU'lar zaman damgası sayacını sıfırlayabileceğinden, zaman damgaları arasında negatif delta gibi beklenmedik değerlere neden olabileceğinden aşağıdaki Compute Boids örneğine zaman damgası sorgusu desteği ekleyen git diff değişikliklerini incelemenizi ö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üllerine varsayılan giriş noktaları

Geliştirici deneyimini iyileştirmek için artık işlem veya oluşturma ardışık düzeni oluştururken gölgelendirici modülünüzün entryPoint bölümünü çıkarabilirsiniz. Gölgelendirici kodunda herhangi bir gölgelendirici aşaması için benzersiz bir giriş noktası bulunmazsa GPUValidationError tetiklenir. Aşağıdaki örneği inceleyin ve issue 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 }] },
});

display-p3'ü GPUExternalTexture renk alanı olarak destekleyin

Artık importExternalTexture() ile HDR videolardan GPUExternalTexture içe aktarırken "display-p3" hedef renk alanı ayarlayabilirsiniz. WebGPU'nun renk alanlarını nasıl işlediğine göz atın. Aşağıdaki örneğe bakın ve chromium:1330250 sorununu inceleyin.

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

Bellek yığın bilgileri

Uygulamanızı geliştirirken büyük miktarlar ayırırken bellek sınırlamalarını tahmin etmenize yardımcı olmak için requestAdapterInfo() artık adaptörde bulunan bellek yığınlarının boyutu ve türü gibi memoryHeaps bilgilerini sunuyor. Bu deneysel özelliğe yalnızca chrome://flags/#enable-webgpu-developer-features konumundaki "WebGPU Geliştirici Özellikleri" işareti etkinleştirildiğinde erişilebilir. Aşağıdaki örneği inceleyin ve issue 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)   { /* ... */ }
}
Bağdaştırıcı bilgilerinde bellek yığınları gösteren https://webgpureport.org sayfasının ekran görüntüsü.
https://webgpureport.org adresinde gösterilen bağdaştırıcı bilgileri bellek yığınları.

Dawn ile ilgili güncellemeler

wgpu::Instance web sitesindeki HasWGSLLanguageFeature ve EnumerateWGSLLanguageFeatures yöntemleri, WGSL dil özelliklerini işlemek için eklendi. dawn:2260 sorununu inceleyin.

Standart olmayan wgpu::Feature::BufferMapExtendedUsages özelliği, wgpu::BufferUsage::MapRead veya wgpu::BufferUsage::MapWrite ve diğer wgpu::BufferUsage öğeleri ile GPU arabelleği oluşturmanıza olanak tanır. Aşağıdaki örneği inceleyin ve dawn:2204 sayısını 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);

Şu özellikler belgelenmiştir: ANGLE Doku Paylaşımı, D3D11 çoklu iş parçacığı korumalı, Örtülü Cihaz Senkronizasyonu, Norm16 doku biçimleri, İç Kartlar İçin Zaman Damgası Sorgusu, Pixel Yerel Depolama Alanı, Gölgelendirici Özellikleri ve Çok Düzlemli Biçimler.

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

Burada, öne çıkan özelliklerin yalnızca bir kısmı ele alınıyor. Kayıtların kapsamlı listesine göz atın.

WebGPU'daki Yenilikler

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

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