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

GPUComputePassEncoder.popDebugGroup()

Methode

Beendet die zuletzt mit <code>pushDebugGroup()</code> geöffnete Debug-Gruppe eines Compute-Passes.

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

Signatur

GPUComputePassEncoder.prototype.popDebugGroup()

Beschreibung

Die Methode popDebugGroup() der Schnittstelle GPUComputePassEncoder schließt die zuletzt geöffnete Debug-Gruppe. Eine solche Gruppe wird mit pushDebugGroup(label) begonnen. Sie fasst mehrere Befehle, etwa setPipeline(), setBindGroup() und dispatchWorkgroups(), unter einem Namen zusammen.

Debug-Gruppen ändern nichts an der Ausführung auf der GPU. Sie helfen aber beim Debuggen und Profiling: Werkzeuge wie PIX, RenderDoc, Xcode GPU Frame Capture oder die Fehlermeldungen des Browsers zeigen die Befehle dann als benannte Hierarchie an. Gerade in großen Compute-Pipelines, zum Beispiel bei Partikelsimulationen, Postprocessing-Ketten oder ML-Inferenz, findet man so schneller, welcher Abschnitt einen Validierungsfehler auslöst.

Gruppen lassen sich verschachteln. Jedes pushDebugGroup() braucht innerhalb desselben Passes genau ein passendes popDebugGroup(), bevor end() aufgerufen wird. Die Gruppen arbeiten nach dem Stapelprinzip (LIFO): popDebugGroup() schließt immer die innerste offene Gruppe.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Einfache Debug-Gruppe um einen Dispatch

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

const module = device.createShaderModule({
  code: `
    @group(0) @binding(0) var<storage, read_write> data: array<f32>;
    @compute @workgroup_size(64)
    fn main(@builtin(global_invocation_id) id: vec3u) {
      data[id.x] = data[id.x] * 2.0;
    }
  `
});

const pipeline = device.createComputePipeline({
  layout: 'auto',
  compute: { module, entryPoint: 'main' }
});

const buffer = device.createBuffer({
  size: 1024 * 4,
  usage: GPUBufferUsage.STORAGE
});

const bindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [{ binding: 0, resource: { buffer } }]
});

const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass({ label: 'Verdopplungs-Pass' });

pass.pushDebugGroup('Werte verdoppeln');
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(1024 / 64);
pass.popDebugGroup(); // schließt 'Werte verdoppeln'

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

Verschachtelte Gruppen für mehrstufige Simulation

// Annahme: device, pipelines und bindGroups existieren bereits
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();

pass.pushDebugGroup('Partikel-Simulation');

  pass.pushDebugGroup('Kräfte berechnen');
  pass.setPipeline(forcePipeline);
  pass.setBindGroup(0, particleBindGroup);
  pass.dispatchWorkgroups(Math.ceil(particleCount / 64));
  pass.popDebugGroup(); // Ende 'Kräfte berechnen'

  pass.pushDebugGroup('Positionen integrieren');
  pass.setPipeline(integratePipeline);
  pass.dispatchWorkgroups(Math.ceil(particleCount / 64));
  pass.popDebugGroup(); // Ende 'Positionen integrieren'

pass.popDebugGroup(); // Ende 'Partikel-Simulation'

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

Ausgeglichene Push/Pop-Aufrufe per Hilfsfunktion sicherstellen

// Führt die Befehle in einer benannten Gruppe aus; pop wird auch bei Exceptions aufgerufen
const withDebugGroup = (pass, label, fn) => {
  pass.pushDebugGroup(label);
  try {
    fn(pass);
  } finally {
    pass.popDebugGroup();
  }
};

const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();

withDebugGroup(pass, 'Blur horizontal', (p) => {
  p.setPipeline(blurHPipeline);
  p.setBindGroup(0, blurBindGroup);
  p.dispatchWorkgroups(width / 8, height / 8);
});

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

// Wichtig · Fallstricke

  • Validierung: Wird popDebugGroup() aufgerufen, obwohl keine Gruppe offen ist, wird der Encoder ungültig. Dasselbe gilt, wenn beim Aufruf von end() noch Gruppen offen sind. Die Methode wirft dabei keine Exception. Der Fehler zeigt sich erst bei encoder.finish() bzw. queue.submit() als GPUValidationError. Abfangen lässt er sich mit device.pushErrorScope('validation') oder dem Ereignis uncapturederror.
  • Debug-Gruppen gelten nur innerhalb eines einzelnen Passes. Eine Gruppe, die im Compute-Pass geöffnet wurde, kann nicht auf dem GPUCommandEncoder oder in einem anderen Pass geschlossen werden. Umgekehrt gilt das ebenso.
  • Die Methode kostet in Produktionscode praktisch keine Leistung. Wenn du ganz sicher gehen willst, kannst du die Aufrufe für Release-Builds trotzdem über ein Debug-Flag abschalten.
  • Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung und wird noch nicht überall unterstützt. Prüfe die Verfügbarkeit vorher mit if (!navigator.gpu) { … }.