Signatur
Beschreibung
Mit pushDebugGroup() öffnest du auf einem GPUCommandEncoder eine benannte Debug-Gruppe. Alle danach codierten Befehle, etwa Render- oder Compute-Pässe und Kopiervorgänge, gehören zu dieser Gruppe, bis du sie mit popDebugGroup() wieder schließt. Die Gruppen verändern das Rendering nicht. Sie dienen nur der Diagnose.
Nützlich sind sie vor allem in GPU-Debuggern und Profilern wie PIX, RenderDoc, Xcode GPU Frame Capture oder den WebGPU-Werkzeugen der Browser. Dort erscheinen die Befehle als Baum, gegliedert nach den Labels. So lässt sich ein komplexer Frame (z. B. „Schatten-Pass“, „G-Buffer“, „Post-Processing“) leicht untersuchen. Auch Validierungsmeldungen des Browsers können die aktiven Gruppen-Labels nennen.
Du kannst Gruppen verschachteln: Jedes pushDebugGroup() legt eine neue Ebene auf einen Stapel, jedes popDebugGroup() entfernt die oberste. Wenn GPUCommandEncoder.finish() aufgerufen wird, muss der Stapel leer sein, sonst ist der Encoder ungültig. Für einzelne Zeitpunkte ohne Bereich gibt es insertDebugMarker().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $groupLabel Pflicht | string | Der Name der Debug-Gruppe, wie er in Debug-Werkzeugen und Fehlermeldungen erscheint, z. B. "Schatten-Pass". |
Rückgabewert
Beispiele
Einen Render-Pass in eine Debug-Gruppe fassen
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('Hauptszene');
const pass = encoder.beginRenderPass({
colorAttachments: [{
view: context.getCurrentTexture().createView(),
clearValue: { r: 0.1, g: 0.1, b: 0.1, a: 1 },
loadOp: 'clear',
storeOp: 'store'
}]
});
pass.end();
encoder.popDebugGroup();
device.queue.submit([encoder.finish()]);
Verschachtelte Gruppen für einen strukturierten Frame
const encoder = device.createCommandEncoder();
encoder.pushDebugGroup('Frame 42');
encoder.pushDebugGroup('Partikel-Simulation');
const compute = encoder.beginComputePass();
compute.setPipeline(particlePipeline);
compute.setBindGroup(0, particleBindGroup);
compute.dispatchWorkgroups(Math.ceil(particleCount / 64));
compute.end();
encoder.popDebugGroup();
encoder.pushDebugGroup('Daten zurückkopieren');
encoder.copyBufferToBuffer(particleBuffer, 0, readbackBuffer, 0, particleBuffer.size);
encoder.popDebugGroup();
encoder.popDebugGroup(); // 'Frame 42'
device.queue.submit([encoder.finish()]);
Hilfsfunktion, die push/pop sicher paart
const withDebugGroup = (encoder, label, fn) => {
encoder.pushDebugGroup(label);
try {
fn(encoder);
} finally {
encoder.popDebugGroup();
}
};
const encoder = device.createCommandEncoder();
withDebugGroup(encoder, 'Textur-Upload', (enc) => {
enc.copyBufferToTexture(
{ buffer: stagingBuffer, bytesPerRow: 256 * 4 },
{ texture },
[256, 256]
);
});
device.queue.submit([encoder.finish()]);
// Wichtig · Fallstricke
- Ausgewogene Aufrufe: Jedes
pushDebugGroup()braucht ein passendespopDebugGroup()auf demselben Encoder. Ist der Stapel beim Aufruf vonfinish()nicht leer, erzeugt der Browser einen Validierungsfehler und der Command Buffer ist ungültig. EinpopDebugGroup()auf leerem Stapel macht den Encoder ebenfalls ungültig. - Getrennte Stapel:
GPURenderPassEncoder,GPUComputePassEncoderundGPURenderBundleEncoderhaben eigenepushDebugGroup()-Methoden mit eigenem Stapel. Eine Gruppe, die du im Pass öffnest, musst du auch vorpass.end()im Pass schließen. Ein Paar über Encoder-Grenzen hinweg ist nicht erlaubt. - Während ein Pass offen ist, ist der
GPUCommandEncodergesperrt. Ein Aufruf vonpushDebugGroup()in dieser Zeit ist ein Validierungsfehler. - Fehler werden nicht als Exception geworfen, sondern asynchron gemeldet, z. B. über
device.pushErrorScope('validation')oder das Eventuncapturederror. - Kompatibilität: WebGPU gibt es nur in sicheren Kontexten. Die Browser-Unterstützung ist noch nicht vollständig, prüfe daher vorab
navigator.gpu. Die Kosten der Debug-Gruppen sind gering, in Produktionscode kannst du sie aber über ein Debug-Flag abschalten.