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

François Beaufort
François Beaufort

תמיכה ב-WebGPU ב-Android

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

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

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

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

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

בדיקות ראשוניות מראות עלייה ממוצעת של 20% במהירות הידור של תוכנת ההצללה (shader) בעת שימוש ב-DXC, בהשוואה ל-FXC.

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

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

כשהתכונה "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' ב-chrome://flags/#enable-webgpu-developer-features במהלך פיתוח האפליקציה. מידע נוסף זמין במאמר יצירת קונטיזציה של שאילתות בחותמות זמן.

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

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

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

כדי לשפר את חוויית הפיתוח, עכשיו אפשר להשמיט את entryPoint של מודול ההצללה (shader) כשיוצרים צינור עיבוד נתונים של מחשוב או עיבוד. אם לא נמצאה נקודת כניסה ייחודית לשלב של ההצללה (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 מופעל. בדוגמה הבאה אפשר לראות את שחר: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 Texture Share, מוגן באמצעות ריבוי שרשורים של D3D11, Implicit Device Synchronization, פורמטים של מרקם מסוג Norm16, פרמטרים של שאילתת חותמת זמן בתוך כרטיסים, אחסון מקומי של Pixel, תכונות Shader API ו-Multi Planar Formats.

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

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

מה חדש ב-WebGPU

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

Chrome 125

Chrome 124

Chrome 123

גרסה 122 של Chrome

גרסה 121 של Chrome

Chrome 120

גרסה 119 של Chrome

גרסה 118 של Chrome

גרסה 117 של Chrome

גרסה 116 של Chrome

Chrome 115

Chrome 114

גרסה 113 של Chrome