GPURenderBundleEncoder

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Experimentell: Dies ist eine experimentelle Technologie
Überprüfen Sie die Browser-Kompatibilitätstabelle sorgfältig vor der Verwendung auf produktiven Webseiten.

Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.

Hinweis: Diese Funktion ist in Web Workers verfügbar.

Die GPURenderBundleEncoder-Schnittstelle der WebGPU API wird verwendet, um Bündel von Befehlen vorab aufzuzeichnen.

Die Befehlsbündel werden durch Aufrufen der Methoden von GPURenderBundleEncoder kodiert; sobald die gewünschten Befehle kodiert wurden, werden sie in eine GPURenderBundle-Objektinstanz mithilfe der Methode GPURenderBundleEncoder.finish() aufgezeichnet. Diese Render-Bündel können dann über mehrere Render-Durchläufe hinweg wiederverwendet werden, indem die GPURenderBundle-Objekte in Aufrufe von GPURenderPassEncoder.executeBundles() übergeben werden.

Im Grunde ist dies wie ein Teil-Render-Durchlauf — GPURenderBundleEncoder hat alle dieselben Funktionalitäten verfügbar wie GPURenderPassEncoders, mit der Ausnahme, dass sie keine Okklusionsabfragen beginnen und beenden können und nicht die Schererekt, den Viewport, die Mischkonstante und die Stencil-Referenz setzen können. Das GPURenderBundle erbt all diese Werte von dem GPURenderPassEncoder, der es ausführt.

Hinweis: Aktuell werden festgelegte Vertex-Puffer, Index-Puffer, Bind-Gruppen und -Pipelines alle gelöscht, bevor ein Render-Bündel ausgeführt wird und nachdem das Render-Bündel die Ausführung beendet hat.

Das Wiederverwenden vorab aufgezeichneter Befehle kann die Leistung einer App erheblich verbessern, insbesondere in Situationen, in denen der JavaScript-Aufruf-Overhead ein Engpass ist. Render-Bündel sind am effektivsten in Situationen, in denen eine Reihe von Objekten auf die gleiche Weise über mehrere Ansichten oder Frames hinweg gezeichnet wird, wobei die einzigen Unterschiede in den verwendeten Pufferinhalten liegen (z. B. aktualisierte Matrix-Uniformen). Ein gutes Beispiel ist das VR-Rendering. Das Aufzeichnen des Renderings als Render-Bündel und dann Anpassen der Ansichts-Matrix und Wiedergeben für jedes Auge ist eine effizientere Möglichkeit, Aufrufbefehle für beide Renderings der Szene zu erteilen.

Eine GPURenderBundleEncoder-Objektinstanz wird über die Eigenschaft GPUDevice.createRenderBundleEncoder() erstellt.

Hinweis: Die Methoden von GPURenderBundleEncoder sind funktional identisch mit ihren Äquivalenten, die auf GPURenderPassEncoder verfügbar sind, mit Ausnahme von GPURenderBundleEncoder.finish(), das in seiner Funktionalität dem GPUCommandEncoder.finish() ähnlich ist.

Instanzeigenschaften

label Experimentell

Ein String, der ein Label bereitstellt, das verwendet werden kann, um das Objekt zu identifizieren, z. B. in GPUError-Meldungen oder Konsolenwarnungen.

Instanzmethoden

draw() Experimentell

Zeichnet Primitiven basierend auf den von setVertexBuffer() bereitgestellten Vertex-Puffern.

drawIndexed() Experimentell

Zeichnet indizierte Primitiven basierend auf den von setVertexBuffer() und setIndexBuffer() bereitgestellten Vertex- und Index-Puffern.

drawIndirect() Experimentell

Zeichnet Primitiven unter Verwendung von Parametern, die aus einem GPUBuffer gelesen werden.

drawIndexedIndirect() Experimentell

Zeichnet indizierte Primitiven unter Verwendung von Parametern, die aus einem GPUBuffer gelesen werden.

finish() Experimentell

Komplette Aufzeichnung der derzeitigen Render-Durchlauf-Befehlssequenz.

insertDebugMarker() Experimentell

Markiert einen spezifischen Punkt in einer Serie kodierter Befehle mit einem Label.

popDebugGroup() Experimentell

Beendet eine Debug-Gruppe, die mit einem Aufruf von pushDebugGroup() begonnen wurde.

pushDebugGroup() Experimentell

Beginnt eine Debug-Gruppe, die mit einem bestimmten Label markiert ist und alle nachfolgenden kodierten Befehle enthalten wird, bis eine popDebugGroup()-Methode aufgerufen wird.

setBindGroup() Experimentell

Setzt die GPUBindGroup zur Verwendung für nachfolgende Render-Bündel-Befehle, für einen gegebenen Index.

setIndexBuffer() Experimentell

Setzt den aktuellen GPUBuffer, der Indexdaten für nachfolgende Zeichenbefehle bereitstellen wird.

setPipeline() Experimentell

Setzt die GPURenderPipeline, die für dieses Render-Bündel verwendet werden soll.

setVertexBuffer() Experimentell

Setzt oder hebt den aktuellen GPUBuffer auf, der Vertex-Daten für nachfolgende Zeichenbefehle bereitstellen wird.

Beispiele

Im WebGPU Samples Animometer-Beispiel werden viele gleiche Operationen gleichzeitig an vielen verschiedenen Objekten durchgeführt. Ein Bündel von Befehlen wird mit der folgenden Funktion kodiert:

js
function recordRenderPass(
  passEncoder: GPURenderBundleEncoder | GPURenderPassEncoder
) {
  if (settings.dynamicOffsets) {
    passEncoder.setPipeline(dynamicPipeline);
  } else {
    passEncoder.setPipeline(pipeline);
  }
  passEncoder.setVertexBuffer(0, vertexBuffer);
  passEncoder.setBindGroup(0, timeBindGroup);
  const dynamicOffsets = [0];
  for (let i = 0; i < numTriangles; ++i) {
    if (settings.dynamicOffsets) {
      dynamicOffsets[0] = i * alignedUniformBytes;
      passEncoder.setBindGroup(1, dynamicBindGroup, dynamicOffsets);
    } else {
      passEncoder.setBindGroup(1, bindGroups[i]);
    }
    passEncoder.draw(3, 1, 0, 0);
  }
}

Später wird ein GPURenderBundleEncoder erstellt, die Funktion wird aufgerufen und das Befehlsbündel wird in eine GPURenderBundle mithilfe von GPURenderBundleEncoder.finish() aufgezeichnet:

js
const renderBundleEncoder = device.createRenderBundleEncoder({
  colorFormats: [presentationFormat],
});
recordRenderPass(renderBundleEncoder);
const renderBundle = renderBundleEncoder.finish();

Es wird dann GPURenderPassEncoder.executeBundles() verwendet, um die Arbeit über mehrere Render-Durchläufe hinweg wiederzuverwenden, um die Leistung zu verbessern. Untersuchen Sie die Beispiel-Codeauflistung für den vollständigen Kontext.

js
// …

return function doDraw(timestamp) {
  if (startTime === undefined) {
    startTime = timestamp;
  }
  uniformTime[0] = (timestamp - startTime) / 1000;
  device.queue.writeBuffer(uniformBuffer, timeOffset, uniformTime.buffer);

  renderPassDescriptor.colorAttachments[0].view = context
    .getCurrentTexture()
    .createView();

  const commandEncoder = device.createCommandEncoder();
  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

  if (settings.renderBundles) {
    passEncoder.executeBundles([renderBundle]);
  } else {
    recordRenderPass(passEncoder);
  }

  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
};

// …

Spezifikationen

Specification
WebGPU
# gpurenderbundle

Browser-Kompatibilität

Siehe auch