GPURenderBundleEncoder

Limited availability

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

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 voraufzuzeichnen.

Die Befehlsbündel werden durch Aufrufen der Methoden von GPURenderBundleEncoder kodiert; sobald die gewünschten Befehle kodiert wurden, werden sie mithilfe der GPURenderBundleEncoder.finish()-Methode in eine Instanz eines GPURenderBundle-Objekts aufgenommen. Diese Renderbündel können dann über mehrere Render-Passagen hinweg erneut verwendet werden, indem die GPURenderBundle-Objekte in Aufrufe von GPURenderPassEncoder.executeBundles() übergeben werden.

Im Effekt ist dies wie eine partielle Render-Passage — GPURenderBundleEncoder bieten die gleiche Funktionalität wie GPURenderPassEncoder, mit der Ausnahme, dass sie keine Okklusionsabfragen beginnen und beenden und das Scherrechteck, den Viewport, die Mischkonstante und die Stencil-Referenz nicht festlegen können. Der GPURenderBundle übernimmt alle diese Werte von dem GPURenderPassEncoder, der ihn ausführt.

Hinweis: Derzeitig gesetzte Vertex-Puffer, Index-Puffer, Bind-Gruppen und Pipelines werden alle vor und nach der Ausführung eines Render-Bündels gelöscht.

Das Wiederverwenden von voraufgezeichneten Befehlen kann die App-Performance erheblich verbessern, wenn der JavaScript-Zeichenaufruf-Overhead ein Engpass ist. Render-Bündel sind am effektivsten in Situationen, in denen ein Batch von Objekten in gleicher Weise über mehrere Ansichten oder Frames gezeichnet wird, wobei die einzigen Unterschiede der verwendete Pufferinhalt sind (wie z.B. aktualisierte Matrix-Uniformen). Ein gutes Beispiel dafür ist das VR-Rendering. Das Aufzeichnen der Renderings als Render-Bündel und das anschließende Ändern der Sichtmatrix und das Wiederholen für jedes Auge ist eine effizientere Methode, um Zeichenaufrufe für beide Renderings der Szene auszugeben.

Ein GPURenderBundleEncoder-Objekt wird über die GPUDevice.createRenderBundleEncoder()-Eigenschaft erstellt.

Hinweis: Die Methoden von GPURenderBundleEncoder sind funktional identisch mit ihren Entsprechungen auf GPURenderPassEncoder, mit Ausnahme von GPURenderBundleEncoder.finish(), welches in seiner Funktionalität dem GPUCommandEncoder.finish() ähnelt.

Instanz-Eigenschaften

label

Ein String, der ein Label bereitstellt, das zur Identifizierung des Objekts verwendet werden kann, beispielsweise in GPUError-Meldungen oder Konsolenwarnungen.

Instanzmethoden

draw()

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

drawIndexed()

Zeichnen von indizierten Primitiven basierend auf den durch setVertexBuffer() und setIndexBuffer() bereitgestellten Vertex- und Index-Puffern.

drawIndirect()

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

drawIndexedIndirect()

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

finish()

Beendet die Aufzeichnung der aktuellen Render-Pass-Befehlssequenz.

insertDebugMarker()

Markiert einen bestimmten Punkt in einer Reihe von kodierten Befehlen mit einem Label.

popDebugGroup()

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

pushDebugGroup()

Beginnt eine Debug-Gruppe, die mit einem spezifischen Label markiert wird und alle nachfolgenden kodierten Befehle bis zur Ausführung der Methode popDebugGroup() enthält.

setBindGroup()

Setzt die GPUBindGroup, die für nachfolgende Render-Bündelbefehle an einem bestimmten Index verwendet werden soll.

setIndexBuffer()

Setzt den aktuellen GPUBuffer, der Indexdaten für nachfolgende Zeichnungsbefehle bereitstellt.

setPipeline()

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

setVertexBuffer()

Setzt oder entfernt den aktuellen GPUBuffer, der Vertexdaten für nachfolgende Zeichnungsbefehle bereitstellt.

Beispiele

Im WebGPU-Samples Animometer-Beispiel werden viele ähnliche 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 aufgerufen und das Befehlsbündel in ein GPURenderBundle mit GPURenderBundleEncoder.finish() aufgenommen:

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

GPURenderPassEncoder.executeBundles() wird dann verwendet, um die Arbeit über mehrere Render-Passagen hinweg wiederzuverwenden und die Leistung zu verbessern. Untersuchen Sie den Beispielcode 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