WebGPU (Chrome→121) में नया क्या है

François Beaufort
François Beaufort

Android पर WebGPU की सुविधा उपलब्ध कराना

Chrome टीम को यह बताते हुए खुशी हो रही है कि Android 12 और उसके बाद के वर्शन पर काम करने वाले डिवाइसों में, Chrome 121 में WebGPU को डिफ़ॉल्ट रूप से चालू कर दिया गया है. ये डिवाइस, Qualcomm और ARM GPU पर काम करते हैं.

यह सुविधा, धीरे-धीरे Android के ज़्यादा डिवाइसों के लिए उपलब्ध कराई जाएगी. इसमें Android 11 पर काम करने वाले डिवाइस भी शामिल हैं. इस सुविधा को ज़्यादा डिवाइसों पर उपलब्ध कराने के लिए, हमें इसकी टेस्टिंग और ऑप्टिमाइज़ेशन करना होगा. इससे यह पक्का किया जा सकेगा कि अलग-अलग हार्डवेयर कॉन्फ़िगरेशन वाले डिवाइसों पर भी यह सुविधा आसानी से काम करे. issue chromium:1497815 देखें.

Android के लिए Chrome पर चल रहे WebGPU सैंपल का स्क्रीनशॉट.
Android के लिए Chrome पर WebGPU का सैंपल चल रहा है.

Windows पर शेडर कंपाइलेशन के लिए, FXC के बजाय DXC का इस्तेमाल करें

Chrome अब Windows D3D12 मशीनों पर शेडर कंपाइल करने के लिए, DXC (DirectX कंपाइलर) की सुविधा का इस्तेमाल करता है. इन मशीनों में SM6+ ग्राफ़िक्स हार्डवेयर होता है. इससे पहले, Windows पर शेडर कंपाइल करने के लिए, WebGPU, FXC (FX कंपाइलर) पर निर्भर करता था. FXC काम तो करता था, लेकिन इसमें DXC में मौजूद सुविधाओं और परफ़ॉर्मेंस ऑप्टिमाइज़ेशन की कमी थी.

शुरुआती टेस्टिंग से पता चला है कि FXC की तुलना में DXC का इस्तेमाल करने पर, कंप्यूट शेडर कंपाइलेशन की स्पीड में औसतन 20% की बढ़ोतरी होती है.

कंप्यूट और रेंडर पास में टाइमस्टैंप क्वेरी

टाइमस्टैंप क्वेरी की मदद से, WebGPU ऐप्लिकेशन यह सटीक तरीके से (नैनोसेकंड तक) मेज़र कर सकते हैं कि उनकी जीपीयू कमांड को कंप्यूट और रेंडर पास को पूरा करने में कितना समय लगता है. इनका इस्तेमाल, जीपीयू वर्कलोड की परफ़ॉर्मेंस और व्यवहार के बारे में अहम जानकारी पाने के लिए किया जाता है.

अगर किसी GPUAdapter में "timestamp-query" सुविधा उपलब्ध है, तो अब ये काम किए जा सकते हैं:

  • "timestamp-query" सुविधा के साथ GPUDevice का अनुरोध करें.
  • "timestamp" टाइप का GPUQuerySet बनाएं.
  • GPUQuerySet में टाइमस्टैंप की वैल्यू कहां लिखनी हैं, यह तय करने के लिए GPUComputePassDescriptor.timestampWrites और GPURenderPassDescriptor.timestampWrites का इस्तेमाल करें.
  • टाइमस्टैंप वैल्यू को resolveQuerySet() के साथ GPUBuffer में बदलें.
  • GPUBuffer से सीपीयू पर नतीजे कॉपी करके, टाइमस्टैंप की वैल्यू वापस पढ़ें.
  • टाइमस्टैंप वैल्यू को 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 ब्राउज़र में, अपने ऐप्लिकेशन को डेवलप करते समय chrome://flags/#enable-webgpu-developer-features पर "WebGPU Developer Features" फ़्लैग को चालू करके, टाइमस्टैंप क्वांटाइज़ेशन को बंद किया जा सकता है. ज़्यादा जानने के लिए, टाइमस्टैंप क्वेरी का क्वांटाइज़ेशन देखें.

ऐसा हो सकता है कि जीपीयू कभी-कभी टाइमस्टैंप काउंटर को रीसेट कर दें. इससे टाइमस्टैंप के बीच नेगेटिव डेल्टा जैसी अनचाही वैल्यू मिल सकती हैं. इसलिए, हम आपको git diff changes देखने का सुझाव देते हैं. इससे आपको Compute Boids के इस सैंपल में टाइमस्टैंप क्वेरी के लिए सहायता मिल सकती है.

टाइमस्टैंप क्वेरी की सुविधा वाला Compute Boids का सैंपल दिखाने वाला स्क्रीनशॉट.
टाइमस्टैंप क्वेरी की सुविधा वाला Compute Boids का सैंपल.

शेडर मॉड्यूल के डिफ़ॉल्ट एंट्री पॉइंट

डेवलपर के अनुभव को बेहतर बनाने के लिए, अब कंप्यूट या रेंडर पाइपलाइन बनाते समय, अपने शेडर मॉड्यूल के entryPoint को हटाया जा सकता है. अगर शेडर कोड में, शेडर स्टेज के लिए कोई यूनीक एंट्री पॉइंट नहीं मिलता है, तो 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 }] },
});

GPUExternalTexture के कलर स्पेस के तौर पर display-p3 को सपोर्ट करना

अब importExternalTexture() वाले एचडीआर वीडियो से GPUExternalTexture इंपोर्ट करते समय, "display-p3" डेस्टिनेशन कलर स्पेस सेट किया जा सकता है. देखें कि WebGPU, कलर स्पेस को कैसे मैनेज करता है. यहां दिया गया उदाहरण और समस्या chromium:1330250 देखें.

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

मेमोरी हीप की जानकारी

ऐप्लिकेशन डेवलप करते समय, ज़्यादा मेमोरी इस्तेमाल करने पर होने वाली समस्याओं का अनुमान लगाने में आपकी मदद करने के लिए, requestAdapterInfo() अब memoryHeaps जानकारी दिखाता है. जैसे, अडैप्टर पर उपलब्ध मेमोरी हीप का साइज़ और टाइप. यह एक्सपेरिमेंटल सुविधा सिर्फ़ तब ऐक्सेस की जा सकती है, जब chrome://flags/#enable-webgpu-developer-features पर मौजूद "WebGPU Developer Features" फ़्लैग चालू हो. यहां दिया गया उदाहरण और issue 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 पर, अडैप्टर की जानकारी में मेमोरी हीप दिखाए गए हैं.

सुबह के अपडेट

WGSL भाषा की सुविधाओं को मैनेज करने के लिए, wgpu::Instance में HasWGSLLanguageFeature और EnumerateWGSLLanguageFeatures तरीके जोड़े गए हैं. समस्या dawn:2260 देखें.

नॉन-स्टैंडर्ड wgpu::Feature::BufferMapExtendedUsages सुविधा की मदद से, 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 Texture Sharing, D3D11 multithread protected, Implicit Device Synchronization, Norm16 texture formats, Timestamp Query Inside Passes, Pixel Local Storage, Shader Features, और Multi Planar Formats.

Chrome टीम ने Dawn के लिए आधिकारिक GitHub डेटाबेस बनाया है.

इसमें सिर्फ़ कुछ मुख्य हाइलाइट शामिल हैं. कमिट की पूरी सूची देखें.

WebGPU में नया क्या है

WebGPU में नया क्या है सीरीज़ में शामिल सभी विषयों की सूची.

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