الميزات الجديدة في WebGPU (الإصدار 121 من Chrome)

François Beaufort
François Beaufort

إتاحة WebGPU على Android

يسرّ فريق Chrome الإعلان عن أنّه تم الآن تفعيل WebGPU تلقائيًا في الإصدار 121 من Chrome على الأجهزة التي تعمل بالإصدار 12 من Android والإصدارات الأحدث والمزوّدة بوحدات معالجة الرسومات من Qualcomm وARM.

سيتوسّع نطاق التوافق تدريجيًا ليشمل مجموعة أكبر من أجهزة Android، بما في ذلك الأجهزة التي تعمل بالإصدار 11 من نظام التشغيل Android في المستقبل القريب. وسيعتمد هذا التوسّع على المزيد من الاختبارات والتحسينات لضمان توفير تجربة سلسة على مجموعة أكبر من إعدادات الأجهزة. اطّلِع على المشكلة chromium:1497815.

لقطة شاشة لعينة WebGPU تعمل على Chrome لنظام التشغيل Android
نموذج WebGPU يعمل على Chrome لنظام التشغيل Android

استخدام DXC بدلاً من FXC لتجميع برنامج التظليل على أجهزة Windows

يستخدم Chrome الآن قوة DXC (برنامج تجميع DirectX) لتجميع برامج التظليل على أجهزة Windows D3D12 المزوّدة بأجهزة رسومات SM6+. في السابق، كانت WebGPU تعتمد على FXC (برنامج تجميع FX) لتجميع برامج التظليل على أجهزة Windows. على الرغم من أنّ FXC كانت تعمل بشكل جيد، إلا أنّها كانت تفتقر إلى مجموعة الميزات وتحسينات الأداء المتوفّرة في DXC.

تُظهر الاختبارات الأولية زيادة متوسطة بنسبة% 20 في سرعة تجميع برنامج تظليل الحساب عند استخدام DXC مقارنةً بـ FXC.

طلبات البحث عن الطوابع الزمنية في عمليات الحساب والعرض

تتيح طلبات الطابع الزمني لتطبيقات WebGPU قياس الوقت الذي تستغرقه أوامر وحدة معالجة الرسومات لتنفيذ عمليات الحوسبة وعمليات العرض بدقة (تصل إلى النانوثانية). ويتم استخدامها بشكل كبير للحصول على إحصاءات حول أداء أحمال عمل وحدة معالجة الرسومات وسلوكها.

عندما تكون ميزة "timestamp-query" متاحة في GPUAdapter، يمكنك الآن إجراء ما يلي:

  • طلب GPUDevice باستخدام ميزة "timestamp-query"
  • أنشئ GPUQuerySet من النوع "timestamp".
  • استخدِم GPUComputePassDescriptor.timestampWrites وGPURenderPassDescriptor.timestampWrites لتحديد موضع كتابة قيم الطابع الزمني في GPUQuerySet.
  • تحويل قيم الطوابع الزمنية إلى GPUBuffer باستخدام resolveQuerySet()
  • اقرأ قيم الطابع الزمني مرة أخرى عن طريق نسخ النتائج من 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، يمكنك إيقاف تحديد الكميات للقيم الزمنية من خلال تفعيل العلامة "ميزات مطوّري WebGPU" في chrome://flags/#enable-webgpu-developer-features أثناء تطوير تطبيقك. يمكنك الاطّلاع على تحديد الكميات لطلبات البحث عن القيم الزمنية لمعرفة المزيد.

بما أنّ وحدات معالجة الرسومات قد تعيد ضبط عدّاد الطابع الزمني من حين لآخر، ما قد يؤدي إلى ظهور قيم غير متوقّعة، مثل الفروق السلبية بين الطوابع الزمنية، أنصحك بالاطّلاع على تغييرات git diff التي تضيف إمكانية طلب الطابع الزمني إلى نموذج Compute Boids التالي.

لقطة شاشة لعينة Compute Boids تتضمّن طلب بحث عن الطابع الزمني
نموذج Compute Boids يتضمّن طلب بحث عن الطابع الزمني.

نقاط الدخول التلقائية إلى وحدات التظليل

لتحسين تجربة المطوّرين، يمكنك الآن حذف entryPoint من وحدة تظليل عند إنشاء مسار حوسبة أو عرض. إذا لم يتم العثور على نقطة دخول فريدة لمرحلة التظليل في رمز التظليل، سيتم تشغيل GPUValidationError. راجِع المثال التالي والمشكلة 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، مثل حجم وأنواع أكوام الذاكرة المتوفّرة على المحوّل. لا يمكن الوصول إلى هذه الميزة التجريبية إلا عند تفعيل العلامة "ميزات مطوّري WebGPU" في 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.

إشعارات الفجر

تمت إضافة الطريقتَين HasWGSLLanguageFeature وEnumerateWGSLLanguageFeatures في wgpu::Instance للتعامل مع ميزات لغة WGSL. اطّلِع على المشكلة 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 والحماية المتعددة الخيوط في D3D11 والمزامنة الضمنية للأجهزة وتنسيقات نسيج Norm16 وطلب الطابع الزمني داخل عمليات المرور ومساحة التخزين المحلية للوحدات بكسل وميزات Shader وتنسيقات متعددة المستويات.

أنشأ فريق Chrome مستودع GitHub رسميًا لـ Dawn.

هذا يشمل بعض النقاط الرئيسية فقط. اطّلِع على القائمة الشاملة لعمليات الإيداع.

الميزات الجديدة في 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