Neuerungen bei der WebGPU (Chrome 131)

François Beaufort
François Beaufort

Entfernungen in WGSL beschneiden

Mit Clip-Abständen können Sie das Clip-Volume von Primitives mit benutzerdefinierten Halbräumen in der Ausgabe der Vertex-Phase einschränken. Wenn Sie eigene Clipping-Ebenen definieren, haben Sie mehr Kontrolle darüber, was in Ihren WebGPU-Szenen sichtbar ist. Diese Technik ist besonders nützlich für Anwendungen wie CAD-Software, bei denen eine präzise Steuerung der Visualisierung entscheidend ist.

Wenn die "clip-distances"-Funktion in einem GPUAdapter verfügbar ist, fordern Sie ein GPUDevice mit dieser Funktion an, um die Unterstützung von Clip-Entfernungen in WGSL zu erhalten, und aktivieren Sie diese Erweiterung explizit in Ihrem WGSL-Code mit enable clip_distances;. Nach der Aktivierung können Sie das integrierte clip_distances-Array in Ihrem Vertex-Shader verwenden. Dieses Array enthält die Entfernungen zu einer benutzerdefinierten Clipping-Ebene:

  • Ein Clip-Abstand von 0 bedeutet, dass der Knoten auf der Ebene liegt.
  • Ein positiver Abstand bedeutet, dass sich der Knotenpunkt im Halbraum des Clips befindet (die Seite, die Sie behalten möchten).
  • Ein negativer Abstand bedeutet, dass sich der Knotenpunkt außerhalb des Halbraums befindet, der abgeschnitten werden soll.

Weitere Informationen finden Sie im folgenden Snippet, im chromestatus-Eintrag und in Problem 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()

Nachdem GPUCanvasContext configure() mit einem Konfigurations-Dictionary aufgerufen wurde, können Sie mit der Methode GPUCanvasContext getConfiguration() die Canvas-Konfiguration prüfen. Dazu gehören die Mitglieder device, format, usage, viewFormats, colorSpace, toneMapping und alphaMode. Das ist nützlich für Aufgaben wie das Prüfen, ob der Browser HDR-Canvas unterstützt, wie im Beispiel für Partikel (HDR) gezeigt. Weitere Informationen finden Sie im folgenden Snippet, im Chrome-Status-Eintrag und in Problem 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.
}

Punkt- und Linienprimitive dürfen keine Tiefenabweichung haben

Wie bereits angekündigt, ist es in der WebGPU-Spezifikation jetzt ein Validierungsfehler, depthBias, depthBiasSlopeScale und depthBiasClamp auf einen Wert ungleich null zu setzen, wenn die Topologie für eine Rendering-Pipeline ein Linien- oder Punkt-Typ ist. Siehe Problem 352567424.

Integrierte Funktionen für inklusive Scans für Untergruppen

Im Rahmen der Untergruppen-Tests wurden die folgenden integrierten Untergruppenfunktionen in Problem 361330160 hinzugefügt:

  • subgroupInclusiveAdd(value): Gibt die inklusive Scan-Summierung aller aktiven Aufrufe values in der Untergruppe zurück.
  • subgroupInclusiveMul(value): Gibt das inklusive Scan-Produkt aller aktiven Aufrufe values in der Untergruppe zurück.

Experimentelle Unterstützung für indirekte Multi-Draw-Funktion

Mit der GPU-Funktion „Multi-Draw Indirect“ können Sie mehrere Zeichenaufrufe mit einem einzigen GPU-Befehl ausgeben. Das ist besonders nützlich, wenn eine große Anzahl von Objekten gerendert werden muss, z. B. bei Partikelsystemen, Instanziierung und großen Szenen. Mit den drawIndirect()- und drawIndexedIndirect()-Methoden von GPURenderPassEncoder kann jeweils nur ein Draw-Aufruf aus einem bestimmten Bereich eines GPU-Puffers ausgegeben werden.

Bis diese experimentelle Funktion standardisiert ist, müssen Sie das Flag „Unsafe WebGPU Support“ unter chrome://flags/#enable-unsafe-webgpu aktivieren, damit sie in Chrome verfügbar ist.

Fordern Sie mit der nicht standardmäßigen GPU-Funktion "chromium-experimental-multi-draw-indirect", die in einem GPUAdapter verfügbar ist, ein GPUDevice mit dieser Funktion an. Erstellen Sie dann einen GPUBuffer mit der Verwendung GPUBufferUsage.INDIRECT, um die Zeichenaufrufe zu speichern. Sie können sie später in den neuen multiDrawIndirect()- und multiDrawIndexedIndirect()-GPURenderPassEncoder-Methoden verwenden, um Draw-Aufrufe innerhalb eines Render-Passes auszugeben. Sehen Sie sich das folgende Snippet und Problem 356461286 an.

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();

Kompilierungsoption für Shadermodule: „strict math“

Der GPUShaderModuleDescriptor wurde eine boolesche strictMath-Entwickleroption hinzugefügt, mit der Sie die strikte Mathematik während der Shader-Modul-Kompilierung aktivieren oder deaktivieren können. Sie ist hinter dem Flag „WebGPU Developer Features“ unter chrome://flags/#enable-webgpu-developer-features verfügbar und ist daher nur für die Entwicklung vorgesehen. Siehe Problem 42241455.

Diese Option wird derzeit für Metal und Direct3D unterstützt. Wenn „Strict Math“ deaktiviert ist, kann der Compiler Ihre Shader optimieren, indem er:

  • Die Möglichkeit von NaN- und Unendlich-Werten wird ignoriert.
  • Behandlung von -0 als +0.
  • Ersetzen der Division durch eine schnellere Multiplikation mit dem Kehrwert.
  • Operationen basierend auf assoziativen und distributiven Eigenschaften neu anordnen.
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 });

Entfernung von „GPUAdapter.requestAdapterInfo()“

Die asynchrone Methode „requestAdapterInfo()“ von GPUAdapter ist redundant, da Sie GPUAdapterInfo bereits synchron über das GPUAdapter-Attribut „info“ abrufen können. Daher wurde die nicht standardmäßige GPUAdapter-Methode „requestAdapterInfo()“ entfernt. Weitere Informationen

Dawn-Updates

Mit der ausführbaren Datei tint_benchmark werden die Kosten für die Übersetzung von Shadern von WGSL in die jeweilige Backend-Sprache gemessen. Weitere Informationen finden Sie in der neuen Dokumentation.

Dies sind nur einige der wichtigsten Neuerungen. Vollständige Liste der Commits

Neues zu WebGPU

Eine Liste mit allen Themen, die in der Reihe Neu in WebGPU behandelt wurden.

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

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