ویژگی‌های جدید WebGPU (Chrome 121)

François Beaufort
François Beaufort

پشتیبانی از WebGPU در Android

تیم Chrome با خوشحالی اعلام می‌کند که WebGPU اکنون به‌طور پیش‌فرض در Chrome 121 در دستگاه‌های دارای Android 12 و بالاتر که از GPUهای Qualcomm و ARM استفاده می‌کنند فعال است.

پشتیبانی به‌تدریج گسترش خواهد یافت تا طیف وسیع‌تری از دستگاه‌های Android، ازجمله دستگاه‌های دارای Android 11، را در آینده نزدیک دربر بگیرد. این گسترش به آزمایش و بهینه‌سازی بیشتر بستگی دارد تا از تجربه یکپارچه در طیف وسیع‌تری از پیکربندی‌های سخت‌افزاری اطمینان حاصل شود. issue chromium:1497815 را ببینید.

نماگرفتی از نمونه WebGPU که در Chrome برای Android اجرا می‌شود.
نمونه WebGPU درحال اجرا در Chrome ویژه Android.

برای کامپایل سایه‌زن در Windows، به‌جای FXC از DXC استفاده کنید

‫Chrome اکنون از قدرت DXC (گردآورنده DirectX) برای گردآوری سایه‌زن‌ها در ماشین‌های Windows D3D12 مجهز به سخت‌افزار گرافیکی SM6+ استفاده می‌کند. قبلاً، WebGPU برای ترجمه سایه‌زن در Windows به FXC (FX Compiler) متکی بود. FXC با وجود اینکه عملکردی بود، مجموعه ویژگی‌ها و بهینه‌سازی‌های عملکردی موجود در DXC را نداشت.

آزمایش‌های اولیه نشان می‌دهد که هنگام استفاده از DXC در مقایسه با FXC، سرعت کامپایل سایه‌زن محاسباتی به‌طور میانگین ۲۰٪ افزایش می‌یابد.

پُرسمان‌های مُهر زمان در گذرگاه‌های محاسباتی و رندر

پُرسمان‌های مُهر زمان به برنامه‌های WebGPU اجازه می‌دهند دقیقاً (تا نانوثانیه) اندازه‌گیری کنند که دستورات GPU آن‌ها چقدر زمان می‌برد تا گذرگاه‌های محاسباتی و رندر را اجرا کند. از آن‌ها به‌طور گسترده‌ای برای کسب اطلاعات آماری درباره عملکرد و رفتار بارهای کاری GPU استفاده می‌شود.

وقتی ویژگی "timestamp-query" در GPUAdapter دردسترس باشد، اکنون می‌توانید کارهای زیر را انجام دهید:

  • با ویژگی "timestamp-query"، درخواست GPUDevice کنید.
  • ‫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();

به‌دلیل نگرانی‌های مربوط به حمله زمان‌بندی، پُرسمان‌های مُهر زمان با وضوح ۱۰۰ میکروثانیه کمّی‌سازی می‌شوند که سازش خوبی بین دقت و امنیت ارائه می‌دهد. در مرورگر Chrome، می‌توانید با فعال کردن پرچم «ویژگی‌های توسعه‌دهنده WebGPU» در chrome://flags/#enable-webgpu-developer-features درطول توسعه برنامه، کمّی‌سازی مُهر زمان را غیرفعال کنید. برای کسب اطلاعات بیشتر، کمّی‌سازی پُرسمان‌های مُهر زمان را ببینید.

ازآنجایی‌که ممکن است شمارنده مُهر زمان GPU گاهی بازنشانی شود و این امر می‌تواند منجر به مقادیر غیرمنتظره‌ای مانند دلتاهای منفی بین مُهرهای زمان شود، توصیه می‌کنم تغییرات git diff را که پشتیبانی از پُرسمان مُهر زمان را به نمونه 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

اکنون می‌توانید هنگام وارد کردن GPUExternalTexture از ویدیوهای HDR با importExternalTexture()، فضای رنگ مقصد "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 را مثل اندازه و نوع پشته‌های حافظه دردسترس در آداپتور آشکار می‌کند. این ویژگی آزمایشی فقط زمانی دردسترس است که پرچم «ویژگی‌های توسعه‌دهنده WebGPU» در chrome://flags/#enable-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 نشان داده می‌شود.

به‌روزرسانی‌های سپیده‌دم

روش‌های HasWGSLLanguageFeature و EnumerateWGSLLanguageFeatures در wgpu::Instance برای مدیریت ویژگی‌های زبان WGSL اضافه شده است. مشکل dawn:2260 را ببینید.

ویژگی غیراستاندارد wgpu::Feature::BufferMapExtendedUsages به شما امکان می‌دهد با wgpu::BufferUsage::MapRead یا wgpu::BufferUsage::MapWrite و هر wgpu::BufferUsage دیگری بافر GPU ایجاد کنید. به مثال زیر و مشکل 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 یک مخزن رسمی GitHub برای Dawn ایجاد کرده است.

این فقط برخی‌از نکات برجسته کلیدی را پوشش می‌دهد. فهرست کامل تعهدات را بررسی کنید.

ویژگی‌های جدید WebGPU

فهرستی از همه مواردی که در مجموعه ویژگی‌های جدید WebGPU پوشش داده شده است.

‫۱۵۵-۱۵۶ Chrome

‫۱۵۳-۱۵۴ Chrome

Chrome 151-152

‫۱۴۹-۱۵۰ Chrome

‫۱۴۷-۱۴۸ Chrome

‫۱۴۶ Chrome

‫Chrome 145

‫۱۴۴ Chrome

‫۱۴۳ Chrome

‫۱۴۲ Chrome

Chrome 141

‫۱۴۰ Chrome

Chrome 139

‫Chrome 138

Chrome 137

‫Chrome 136

‫۱۳۵ Chrome

‫۱۳۴ Chrome

‫Chrome 133

‫۱۳۲ Chrome

‫۱۳۱ Chrome

‫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