מה חדש ב-WebGPU (גרסה 131 של Chrome)

François Beaufort
François Beaufort

מרחקי קליפים ב-WGSL

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

כשהתכונה "clip-distances" זמינה ב-GPUAdapter, מבקשים GPUDevice עם התכונה הזו כדי לקבל תמיכה במרחקי חיתוך ב-WGSL, ומפעילים את התוסף הזה באופן מפורש בקוד WGSL באמצעות enable clip_distances;. אחרי ההפעלה, תוכלו להשתמש במערך המובנה clip_distances בשדה הקוד של ה-vertex shader. המערך הזה מכיל מרחקים ל-clip plane שהוגדר על ידי המשתמש:

  • אם מרחק החיתוך הוא 0, המשמעות היא שהקודקוד נמצא במישור.
  • מרחק חיובי מציין שהקודקוד נמצא בתוך חצי המרחב של הקליפ (הצד שרוצים לשמור).
  • אם המרחק שלילי, הקודקוד נמצא מחוץ למרחב החצי של החיתוך (הצד שרוצים להשליך).

אפשר לעיין בקטע הקוד הבא, ברשומה ב-chromestatus ובבעיה 358408571.

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("clip-distances")) {
  throw new Error("Clip distances support is not available");
}
// Explicitly request clip distances support.
const device = await adapter.requestDevice({
  requiredFeatures: ["clip-distances"],
});

const vertexShaderModule = device.createShaderModule({ code: `
  enable clip_distances;

  struct VertexOut {
    @builtin(clip_distances) my_clip_distances : array<f32, 1>,
    @builtin(position) my_position : vec4f,
  }
  @vertex fn main() -> VertexOut {
    var output : VertexOut;
    output.my_clip_distances[0] = 1;
    output.my_position = vec4f(0, 0, 0, 1);
    return output;
  }
`,
});

// Send the appropriate commands to the GPU...

GPUCanvasContext getConfiguration()‎

אחרי שמפעילים את configure() של GPUCanvasContext עם מילון תצורה, אפשר להשתמש בשיטה getConfiguration() של GPUCanvasContext כדי לבדוק את הגדרת ההקשר של הקנבס. הוא כולל את החברים device, format, usage, viewFormats, colorSpace, toneMapping ו-alphaMode. אפשר להשתמש באפשרות הזו למשימות כמו בדיקה אם הדפדפן תומך בבד HDR, כפי שמתואר בדוגמה 'חלקיקים (HDR)'. אפשר לעיין בקטע הקוד הבא, ברשומה ב-chromestatus ובבעיה 370109829.

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const canvas = document.querySelector("canvas");
const context = canvas.getContext("webgpu");

// Configure the canvas for HDR.
context.configure({
  device,
  format: "rgba16float",
  toneMapping: { mode: "extended" },
});

const configuration = context.getConfiguration();
if (configuration.toneMapping.mode === "extended") {
  // The browser supports HDR canvas.
  // Warning! The user still needs a HDR display to enjoy HDR content.
}

אסור שתהיה הטיה לעומק בפרימיטיבים של קווים ונקודות

כפי שהודענו בעבר, במפרט WebGPU, הגדרת הערכים depthBias, ‏ depthBiasSlopeScale ו-depthBiasClamp לערך שאינו אפס כשהטופוגרפיה של צינור עיבוד הנתונים לעיבוד תמונה היא מסוג קו או נקודה נחשבת עכשיו לשגיאת אימות. בעיה מס' 352567424

פונקציות מובנות של סריקה כוללת לקבוצות משנה

כחלק מהניסוי בקבוצות משנה, הפונקציות המובנות הבאות של קבוצות משנה נוספו בבעיה 361330160:

  • subgroupInclusiveAdd(value): הפונקציה מחזירה את הסכום הכולל של כל הקריאות הפעילות value בקבוצת המשנה.
  • subgroupInclusiveMul(value): הפונקציה מחזירה את המכפלה של כל הקריאות הפעילות value בקבוצת המשנה.

תמיכה ניסיונית ב-multi-draw indirect

התכונה 'GPU עקיף עם מספר משיכות' מאפשרת להנפיק מספר קריאות לציור באמצעות פקודה אחת של GPU. האפשרות הזו שימושית במיוחד במצבים שבהם צריך ליצור רינדור של מספר גדול של אובייקטים, כמו מערכות של חלקיקים, יצירה של מכונות וסביבות גדולות. השיטות drawIndirect() ו-drawIndexedIndirect() של GPURenderPassEncoder יכולות להנפיק רק קריאה אחת לציור בכל פעם מאזור מסוים במאגר של GPU.

עד שהתכונה הניסיונית הזו תוגדר כתקן, צריך להפעיל את הדגל 'תמיכה ב-WebGPU לא מאובטח' בקובץ chrome://flags/#enable-unsafe-webgpu כדי שהיא תהיה זמינה ב-Chrome.

אם התכונה הלא סטנדרטית "chromium-experimental-multi-draw-indirect" של GPU זמינה ב-GPUAdapter, מבקשים GPUDevice עם התכונה הזו. לאחר מכן יוצרים GPUBuffer עם השימוש GPUBufferUsage.INDIRECT כדי לאחסן את קריאות הציור. תוכלו להשתמש בו מאוחר יותר בשיטות החדשות multiDrawIndirect() ו-multiDrawIndexedIndirect() של GPURenderPassEncoder כדי להנפיק קריאות ציור בתוך שלב עיבוד (pass) של עיבוד. אפשר לעיין בקטע הקוד הבא ובבעיה 356461286.

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("chromium-experimental-multi-draw-indirect")) {
  throw new Error("Experimental multi-draw indirect support is not available");
}
// Explicitly request experimental multi-draw indirect support.
const device = await adapter.requestDevice({
  requiredFeatures: ["chromium-experimental-multi-draw-indirect"],
});

// Draw call have vertexCount, instanceCount, firstVertex, and firstInstance parameters.
const drawData = new Uint32Array([
  3, 1, 0, 0, // First draw call
  3, 1, 3, 0, // Second draw call
]);
// Create a buffer to store the draw calls.
const drawBuffer = device.createBuffer({
  size: drawData.byteLength,
  usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(drawBuffer, 0, drawData);

// Create a render pipeline, a vertex buffer, and a render pass encoder...

// Inside a render pass, issue the draw calls.
myPassEncoder.setPipeline(myPipeline);
myPassEncoder.setVertexBuffer(0, myVertexBuffer);
myPassEncoder.multiDrawIndirect(drawBuffer, /*offset=*/ 0, /*maxDrawCount=*/ 2);
myPassEncoder.end();

אפשרות הידור של מודול Shader: מתמטיקה קפדנית

נוספה אפשרות למפתחים מסוג strictMath ב-GPUShaderModuleDescriptor, שמאפשרת להפעיל או להשבית מתמטיקה קפדנית במהלך הידור מודול שדה האפקטים. התכונה הזו זמינה באמצעות הדגל 'WebGPU Developer Features' (תכונות למפתחים של WebGPU) ב-chrome://flags/#enable-webgpu-developer-features, כלומר היא מיועדת לשימוש רק במהלך הפיתוח. בעיה מס' 42241455

האפשרות הזו נתמכת כרגע ב-Metal וב-Direct3D. כשהחשבון המחמיר מושבת, המהדר יכול לבצע אופטימיזציה של השיזרים באמצעות:

  • מתעלמים מהאפשרות של ערכים NaN ו-Infinity.
  • התייחסות ל--0 כאל +0.
  • החלפת חלוקה במכפלה מהירה יותר בחזקה ההפוכה.
  • סידור מחדש של פעולות על סמך מאפיינים אסוסיטיביים וחלופיים.
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const code = `
  // Examines the bit pattern of the floating-point number to
  // determine if it represents a NaN according to the IEEE 754 standard.
  fn isNan(x : f32) -> bool {
    bool ones_exp = (bitcast<u32>(x) & 0x7f8) == 0x7f8;
    bool non_zero_sig = (bitcast<u32>(x) & 0x7ffff) != 0;
    return ones_exp && non_zero_sig;
  }
  // ...
`;

// Enable strict math during shader compilation.
const shaderModule = device.createShaderModule({ code, strictMath: true });

הסרת השיטה requestAdapterInfo()‎ של GPUAdapter

השיטה האסינכרונית requestAdapterInfo() של GPUAdapter היא מיותרת, כי כבר אפשר לקבל את GPUAdapterInfo באופן סינכרוני באמצעות המאפיין info של GPUAdapter. לכן, השיטה הלא סטנדרטית requestAdapterInfo() של GPUAdapter הוסרה. כוונת ההסרה

עדכונים של Dawn

קובץ ההפעלה tint_benchmark מודד את העלות של תרגום שגיאות מ-WGSL לכל שפת קצה עורפי. בתיעוד החדש תוכלו לקרוא מידע נוסף על הנושא.

כאן מפורטות רק חלק מהנקודות העיקריות. רשימת ההצהרות המלאה

מה חדש ב-WebGPU

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

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