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

François Beaufort
François Beaufort

إتاحة استخدام WebGPU على Android

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

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

لقطة شاشة لنموذج WebGPU الذي يتم تشغيله على متصفِّح Chrome لنظام التشغيل Android
نموذج WebGPU قيد التشغيل على متصفِّح Chrome لنظام التشغيل Android

استخدام DXC بدلاً من FXC لتجميع أدوات التظليل على Windows

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

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

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

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

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

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

بما أنّ وحدات معالجة الرسومات قد تعيد ضبط عدّاد الطابع الزمني من حين لآخر، ما قد يؤدي إلى ظهور قيم غير متوقّعة، مثل دلتا سالبة بين الطوابع الزمنية، أنصحك بالاطّلاع على تغييرات git diff التي تتيح إتاحة طلبات البحث عن الطابع الزمني لعيّنة 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 }] },
});

إتاحة استخدام 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". تم تفعيل flag في 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، والبطاقات الداخلية لطلب البحث باستخدام الطابع الزمني، ومساحة التخزين المحلية على Pixel، وميزات Shader، وأشكال متعدّدة المستويات.

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

يتناول هذا فقط بعض النقاط الرئيسية. يمكنك الاطّلاع على قائمة الالتزامات الشاملة.

الميزات الجديدة في WebGPU

قائمة بكل ما تم تناوله في سلسلة الميزات الجديدة في WebGPU.

الإصدار 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 من Chrome