Novità di WebGPU (Chrome 131)

François Beaufort
François Beaufort

Ritagliare le distanze in WGSL

Le distanze di ritaglio consentono di limitare il volume di ritaglio delle primitive con spazi intermedi definiti dall'utente nell'output della fase dei vertici. La definizione di piani di ritaglio personalizzati offre un maggiore controllo su ciò che è visibile nelle scene WebGPU. Questa tecnica è particolarmente utile per applicazioni come i software CAD, in cui il controllo preciso della visualizzazione è fondamentale.

Quando la funzionalità "clip-distances" è disponibile in un GPUAdapter, richiedi un GPUDevice con questa funzionalità per ottenere il supporto delle distanze di ritaglio in WGSL e attiva esplicitamente questa estensione nel codice WGSL con enable clip_distances;. Una volta abilitato, puoi utilizzare l'array clip_distances integrato nello shader dei vertici. Questo array contiene le distanze da un piano di taglio definito dall'utente:

  • Una distanza di ritaglio pari a 0 significa che il vertice si trova sul piano.
  • Una distanza positiva indica che il vertice si trova all'interno del semispazio del clip (il lato che vuoi conservare).
  • Una distanza negativa indica che il vertice si trova al di fuori del semispazio di ritaglio (il lato da scartare).

Consulta il seguente snippet, la voce di Chrome Status e il problema 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()

Una volta chiamato GPUCanvasContext configure() con un dizionario di configurazione, il metodo GPUCanvasContext getConfiguration() consente di controllare la configurazione del contesto del canvas. Include i membri device, format, usage, viewFormats, colorSpace, toneMapping e alphaMode. Ciò è utile per attività come verificare se il browser supporta il canvas HDR, come mostrato nell'esempio Particelle (HDR). Consulta il seguente snippet, la voce di Chrome Status e il problema 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.
}

I primitivi punto e linea non devono avere distorsione della profondità

Come annunciato in precedenza, la specifica WebGPU ora considera un errore di convalida l'impostazione di depthBias, depthBiasSlopeScale e depthBiasClamp su un valore diverso da zero quando la topologia di una pipeline di rendering è di tipo linea o punto. Vedi problema 352567424.

Funzioni integrate di scansione inclusiva per i sottogruppi

Nell'ambito dell'esperimento sui sottogruppi, sono state aggiunte le seguenti funzioni integrate per i sottogruppi nel problema 361330160:

  • subgroupInclusiveAdd(value): restituisce la somma inclusiva delle scansioni di tutte le chiamate attive value nel sottogruppo.
  • subgroupInclusiveMul(value): restituisce la moltiplicazione inclusiva delle scansioni di tutte le chiamate attive value nel sottogruppo.

Supporto sperimentale per l'estrazione indiretta multipla

La funzionalità GPU indiretta multi-draw consente di emettere più chiamate di disegno con un singolo comando GPU. Ciò è particolarmente utile in situazioni in cui è necessario eseguire il rendering di un numero elevato di oggetti, ad esempio sistemi di particelle, istanze e scene di grandi dimensioni. I metodi drawIndirect() e drawIndexedIndirect() GPURenderPassEncoder possono emettere una sola chiamata di disegno alla volta da una determinata regione di un buffer GPU.

Finché questa funzionalità sperimentale non sarà standardizzata, attiva il flag "Unsafe WebGPU Support" (Supporto WebGPU non sicuro) all'indirizzo chrome://flags/#enable-unsafe-webgpu per renderla disponibile in Chrome.

Con la funzionalità GPU non standard "chromium-experimental-multi-draw-indirect" disponibile in un GPUAdapter, richiedi un GPUDevice con questa funzionalità. Poi crea un GPUBuffer con l'utilizzo GPUBufferUsage.INDIRECT per archiviare le chiamate di disegno. Puoi utilizzarlo in un secondo momento nei nuovi metodi multiDrawIndirect() e multiDrawIndexedIndirect() GPURenderPassEncoder per emettere chiamate di disegno all'interno di un render pass. Vedi lo snippet seguente e il problema 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();

Opzione di compilazione del modulo shader strict math

È stata aggiunta un'opzione sviluppatore booleana strictMath a GPUShaderModuleDescriptor per consentire di attivare o disattivare la matematica rigorosa durante la compilazione del modulo shader. È disponibile dietro il flag "Funzionalità per sviluppatori WebGPU" all'indirizzo chrome://flags/#enable-webgpu-developer-features, il che significa che è una funzionalità destinata esclusivamente all'uso durante lo sviluppo. Vedi problema 42241455.

Questa opzione è attualmente supportata su Metal e Direct3D. Quando la matematica rigorosa è disattivata, il compilatore può ottimizzare gli shader:

  • Ignorando la possibilità di valori NaN e Infinity.
  • Trattamento di -0 come +0.
  • Sostituzione della divisione con una moltiplicazione più rapida per il reciproco.
  • Riarrangiamento delle operazioni in base alle proprietà associative e distributive.
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 });

Rimozione di requestAdapterInfo() di GPUAdapter

Il metodo asincrono GPUAdapter requestAdapterInfo() è ridondante, in quanto puoi già ottenere GPUAdapterInfo in modo sincrono utilizzando l'attributo GPUAdapter info. Pertanto, il metodo GPUAdapter requestAdapterInfo() non standard è stato rimosso. Consulta la comunicazione di rimozione.

Aggiornamenti all'alba

L'eseguibile tint_benchmark misura il costo della traduzione degli shader da WGSL a ogni linguaggio di backend. Per saperne di più, consulta la nuova documentazione.

Questi sono solo alcuni dei punti salienti. Consulta l'elenco completo dei commit.

Novità di WebGPU

Un elenco di tutti gli argomenti trattati nella serie Novità di WebGPU.

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