Novità di WebGPU (Chrome 131)

François Beaufort
François Beaufort

Distanze dei clip in WGSL

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

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

  • Una distanza di clip pari a 0 indica 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 del clip (il lato che vuoi eliminare).

Consulta lo snippet seguente, la voce di chromestatus 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() ti consente di controllare la configurazione del contesto della tela. Sono inclusi i membri device, format, usage, viewFormats, colorSpace, toneMapping e alphaMode. Questo è utile per attività come verificare se il browser supporta la tela HDR, come mostrato nel Sample Particelle (HDR). Consulta lo snippet seguente, la voce di chromestatus 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.
}

Le primitive di punti e linee non devono avere bias di profondità

Come annunciato in precedenza, le specifiche WebGPU ora considerano 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 il problema 352567424.

Funzioni integrate di scansione inclusiva per i sottogruppi

Nell'ambito dell'esperimento sui sottogruppi, le seguenti funzioni predefinite dei sottogruppi sono state aggiunte nel problema 361330160:

  • subgroupInclusiveAdd(value): restituisce la sommatoria della scansione inclusiva di tutte le invocazioni attive value nel sottogruppo.
  • subgroupInclusiveMul(value): restituisce la moltiplicazione della scansione inclusiva di tutte le invocazioni attive value nel sottogruppo.

Supporto sperimentale per l'indirizzamento multi-draw

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

Fino a quando questa funzionalità sperimentale non sarà standardizzata, attiva il flag "Supporto WebGPU non sicuro" in 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à. Quindi crea un GPUBuffer con l'utilizzo GPUBufferUsage.INDIRECT per memorizzare le chiamate draw. Puoi utilizzarlo in un secondo momento nei nuovi metodi GPURenderPassEncoder multiDrawIndirect() e multiDrawIndexedIndirect() per emettere chiamate draw all'interno di un passaggio di rendering. Consulta 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 matematica rigorosa

A GPUShaderModuleDescriptor è stata aggiunta un'opzione di sviluppatore booleana strictMath per consentirti di attivare o disattivare la matematica rigorosa durante la compilazione del modulo shader. È disponibile dietro il flag "Funzionalità per sviluppatori WebGPU" in chrome://flags/#enable-webgpu-developer-features, il che significa che è una funzionalità pensata solo per l'utilizzo durante lo sviluppo. Vedi issue 42241455.

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

  • Ignorando la possibilità di valori NaN e Infinity.
  • Trattare -0 come +0.
  • Sostituzione della divisione con la moltiplicazione più rapida per il reciproco.
  • Riordinare le 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 });

Rimuovi requestAdapterInfo() di GPUAdapter

Il metodo asincrono GPUAdapter requestAdapterInfo() è ridondante perché puoi già ottenere GPUAdapterInfo in modo sincrono utilizzando l'attributo GPUAdapter info. Di conseguenza, il metodo non standard GPUAdapter requestAdapterInfo() è stato rimosso. Consulta l'intenzione di rimozione.

Aggiornamenti di Dawn

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

Sono riportati solo alcuni dei punti salienti. Consulta l'elenco completo dei commit.

Novità di WebGPU

Un elenco di tutto ciò che è stato trattato nella serie Novità di 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