Start · Sprachen · JavaScript · Referenz · GPUCommandEncoder.popDebugGroup()

GPUCommandEncoder.popDebugGroup()

Methode

Beendet die zuletzt mit <code>pushDebugGroup()</code> geöffnete Debug-Gruppe auf einem <code>GPUCommandEncoder</code>.

seit JavaScript WebGPU – Chrome/Edge 113+, Firefox 141+ (Windows), Kategorie: webapi

Signatur

GPUCommandEncoder.prototype.popDebugGroup()

Beschreibung

Mit popDebugGroup() schließt du die zuletzt geöffnete Debug-Gruppe eines GPUCommandEncoder. Eine solche Gruppe öffnest du mit pushDebugGroup(label). Zusammen legen die beiden Aufrufe eine benannte Klammer um mehrere GPU-Befehle, etwa Render- und Compute-Passes oder Kopiervorgänge. Grafik-Debugger und Profiler wie RenderDoc, PIX, Xcode GPU Frame Capture oder die WebGPU-Werkzeuge im Browser zeigen diese Klammer als Abschnitt an.

Debug-Gruppen haben eine Stapelstruktur und lassen sich beliebig tief verschachteln. Jeder Aufruf von popDebugGroup() schließt immer die innerste offene Gruppe. Für jedes pushDebugGroup() brauchst du genau ein passendes popDebugGroup(), bevor du finish() aufrufst.

Die Methode ändert nichts daran, was die GPU berechnet. Sie dient nur der Diagnose: Du kannst damit Frames in logische Abschnitte gliedern, zum Beispiel „Schatten-Pass“, „Nachbearbeitung“ oder „Partikel-Update“. Eine Fehlermeldung von WebGPU nennt dann oft auch die Debug-Gruppe, in der der Fehler aufgetreten ist.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Einfache Debug-Gruppe um einen Render-Pass

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');
context.configure({ device, format: navigator.gpu.getPreferredCanvasFormat() });

const encoder = device.createCommandEncoder({ label: 'Frame-Encoder' });

encoder.pushDebugGroup('Hintergrund löschen');
const pass = encoder.beginRenderPass({
  colorAttachments: [{
    view: context.getCurrentTexture().createView(),
    clearValue: { r: 0.1, g: 0.1, b: 0.2, a: 1 },
    loadOp: 'clear',
    storeOp: 'store'
  }]
});
pass.end();
encoder.popDebugGroup(); // schließt „Hintergrund löschen“

device.queue.submit([encoder.finish()]);

Verschachtelte Gruppen für Compute und Kopiervorgang

const encoder = device.createCommandEncoder();

encoder.pushDebugGroup('Physik-Update');

  encoder.pushDebugGroup('Partikel simulieren');
  const compute = encoder.beginComputePass();
  compute.setPipeline(particlePipeline);
  compute.setBindGroup(0, particleBindGroup);
  compute.dispatchWorkgroups(Math.ceil(particleCount / 64));
  compute.end();
  encoder.popDebugGroup(); // schließt „Partikel simulieren“

  encoder.pushDebugGroup('Ergebnis zurücklesen');
  encoder.copyBufferToBuffer(particleBuffer, 0, readbackBuffer, 0, particleBuffer.size);
  encoder.popDebugGroup(); // schließt „Ergebnis zurücklesen“

encoder.popDebugGroup(); // schließt „Physik-Update“

device.queue.submit([encoder.finish()]);

Hilfsfunktion, die push/pop immer paarweise aufruft

const withDebugGroup = (encoder, label, fn) => {
  encoder.pushDebugGroup(label);
  try {
    fn();
  } finally {
    encoder.popDebugGroup(); // wird auch bei einer Exception aufgerufen
  }
};

const encoder = device.createCommandEncoder();
withDebugGroup(encoder, 'Nachbearbeitung', () => {
  const pass = encoder.beginRenderPass(postFxPassDescriptor);
  pass.setPipeline(postFxPipeline);
  pass.draw(3);
  pass.end();
});

device.pushErrorScope('validation');
device.queue.submit([encoder.finish()]);
const error = await device.popErrorScope();
console.log(error ? error.message : 'Keine Validierungsfehler');
Keine Validierungsfehler

// Wichtig · Fallstricke

  • Ungleich viele Aufrufe: Rufst du popDebugGroup() auf, obwohl keine Gruppe offen ist, wird der Encoder ungültig. Das Gleiche passiert, wenn beim Aufruf von finish() noch Gruppen offen sind. In beiden Fällen entsteht ein Validierungsfehler, und der erzeugte GPUCommandBuffer ist ungültig. Es wird aber keine JavaScript-Exception geworfen. Solche Fehler findest du nur über device.pushErrorScope()/popErrorScope() oder das Ereignis uncapturederror.
  • Getrennte Stapel: Debug-Gruppen auf dem GPUCommandEncoder sind unabhängig von denen in GPURenderPassEncoder, GPUComputePassEncoder und GPURenderBundleEncoder. Eine Gruppe, die du in einem Pass öffnest, musst du im selben Pass wieder schließen, also vor pass.end(). Den Stapel des Encoders beenden Passes dagegen nicht.
  • Rufst du popDebugGroup() auf dem Command-Encoder auf, während noch ein Pass offen ist, ist der Encoder gesperrt und es entsteht ebenfalls ein Validierungsfehler.
  • Die Leistungseinbußen sind vernachlässigbar. Trotzdem nutzen manche Projekte Debug-Gruppen nur in Entwicklungs-Builds.
  • Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung. Chromium-Browser unterstützen es ab Version 113, Firefox und Safari erst in neueren Versionen und teilweise nur auf bestimmten Plattformen. Prüfe vorher mit if (navigator.gpu), ob die API vorhanden ist.