מה חדש ב-WebGPU (Chrome 121)

François Beaufort
François Beaufort

תמיכה ב-WebGPU ב-Android

צוות Chrome שמח להודיע שעכשיו WebGPU מופעל כברירת מחדל ב-Chrome 121 במכשירים עם Android מגרסה 12 ואילך, שמופעלים על ידי מעבדי GPU Qualcomm ו-ARM.

התמיכה תורחב בהדרגה כך שהיא תקיף מגוון רחב יותר של מכשירי Android, כולל מכשירים שפועלים עם Android 11 בעתיד הקרוב. ההרחבה תלויה בבדיקות ובאופטימיזציה נוספות כדי להבטיח חוויה חלקה במגוון רחב יותר של תצורות חומרה. ראו בעיה ב-chromium:1497815.

צילום מסך של דוגמת WebGPU שפועלת ב-Chrome ל-Android.
דוגמה של WebGPU פועלת ב-Chrome ל-Android.

שימוש ב-DXC במקום ב-FXC להידור של תוכנת ההצללה ב-Windows

ב-Chrome נעשה עכשיו שימוש בעוצמה של DXC (DirectX Compiler) כדי להדר תוכנות הצללה במכונות Windows D3D12 שכוללות חומרה גרפית מסוג SM6 ואילך. בעבר, WebGPU הסתמך על FXC (FX Compiler) להידור של תוכנת הצללה ב-Windows. בזמן שה-FXC פועל, ל-FXC לא היו את ערכת התכונות והאופטימיזציות של הביצועים שקיימות ב-DXC.

בבדיקה הראשונית נמצא עלייה ממוצעת של 20% במהירות ההידור של תוכנת ההצללה למחשוב בזמן השימוש ב-DXC, בהשוואה ל-FXC.

שאילתות חותמות זמן באישורי מחשוב ועיבוד

שאילתות חותמת זמן מאפשרות לאפליקציות WebGPU למדוד במדויק (עד ננו-שנייה) את משך הזמן שלוקח לפקודות ה-GPU להפעיל מחשוב ולעבד כרטיסים. אנחנו משתמשים בהם במידה רבה כדי לקבל תובנות לגבי הביצועים וההתנהגות של עומסי העבודה של GPU.

כשהתכונה "timestamp-query" זמינה ב-GPUAdapter, אפשר עכשיו לבצע את הפעולות הבאות:

  • מבקשים GPUDevice עם התכונה "timestamp-query".
  • צריך ליצור GPUQuerySet מסוג "timestamp".
  • כדי להגדיר איפה לכתוב ערכי חותמות זמן ב-GPUQuerySet אפשר להשתמש ב-GPUComputePassDescriptor.timestampWrites וב-GPURenderPassDescriptor.timestampWrites.
  • פותרים את הערכים של חותמות הזמן ב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 Developer Features (תכונות למפתחים של WebGPU) סימון ב-chrome://flags/#enable-webgpu-developer-features במהלך פיתוח האפליקציה. מידע נוסף זמין במאמר כימות שאילתות חותמות זמן.

מעבדי GPU עשויים לאפס את מונה חותמת הזמן מדי פעם, דבר שעלול לגרום לערכים לא צפויים כמו הפרשות שליליות בין חותמות זמן. לכן, מומלץ לבדוק את השינויים ב-git diff שנוספים תמיכה בשאילתות בחותמת זמן לדוגמה הבאה של Compute Boids.

צילום מסך של דוגמת Compute Boids, הכוללת שאילתה של חותמת זמן.
דוגמה של Compute Boids עם שאילתה של חותמת זמן.

נקודות כניסה שמוגדרות כברירת מחדל למודולים של תוכנת ההצללה

כדי לשפר את חוויית הפיתוח, עכשיו אפשר להשמיט את entryPoint של מודול ההצללה בזמן יצירת צינור עיבוד נתונים של מחשוב או רינדור. אם לא נמצאת נקודת כניסה ייחודית לשלב של תוכנת ההצללה (shader), תופעל 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 מאפשרת ליצור מאגר נתונים זמני של GPU עם 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 Multithread עדכונים, סנכרון של מכשירים מרומזים, פורמטים של טקסטורה Norm16, שליחת חותמת זמן בתוך הכרטיסים, אחסון מקומי ב-Pixel, תכונות צד שלישי ופורמטים מישוריים{/15

צוות Chrome יצר מאגר רשמי של GitHub עבור Dawn.

זה כולל רק חלק מהעדכונים העיקריים. אתם מוזמנים לעיין ברשימה המלאה של ההתחייבויות.

מה חדש ב-WebGPU

רשימה של כל מה שדיברנו עליו בסדרה מה חדש ב-WebGPU.

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