Signatur
Beschreibung
Mit popDebugGroup() schließt du die innerste Debug-Gruppe, die du vorher im selben GPURenderPassEncoder mit pushDebugGroup(label) geöffnet hast. Debug-Gruppen sind reine Markierungen: Sie ändern nichts am Rendering. Sie fassen aber zusammengehörige Befehle, etwa alle Draw-Calls für Schatten, UI oder ein bestimmtes Mesh, zu benannten Abschnitten zusammen.
Diese Abschnitte zeigen Grafik-Debugger und Profiler wie PIX, RenderDoc, Xcode GPU Frame Capture oder die WebGPU-Entwicklerwerkzeuge im Browser als Baum an. Auch in Validierungsfehlern tauchen die Gruppennamen auf, sodass du Fehler schneller der richtigen Stelle im Code zuordnen kannst.
Gruppen lassen sich beliebig verschachteln und funktionieren wie ein Stapel: Jedes popDebugGroup() schließt die zuletzt geöffnete Gruppe. Auf jedes pushDebugGroup() muss vor end() genau ein popDebugGroup() im selben Renderpass folgen.
Rückgabewert
Beispiele
Draw-Calls in einer Debug-Gruppe zusammenfassen
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const context = document.querySelector('canvas').getContext('webgpu');
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format });
const module = device.createShaderModule({
code: `
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
let p = array(vec2f(0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
return vec4f(p[i], 0, 1);
}
@fragment fn fs() -> @location(0) vec4f { return vec4f(1, 0.4, 0, 1); }
`
});
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: { module, entryPoint: 'vs' },
fragment: { module, entryPoint: 'fs', targets: [{ format }] }
});
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
colorAttachments: [{
view: context.getCurrentTexture().createView(),
clearValue: { r: 0, g: 0, b: 0, a: 1 },
loadOp: 'clear',
storeOp: 'store'
}]
});
pass.pushDebugGroup('Dreieck zeichnen');
pass.setPipeline(pipeline);
pass.draw(3);
pass.popDebugGroup(); // schließt „Dreieck zeichnen“
pass.end();
device.queue.submit([encoder.finish()]);
Verschachtelte Gruppen für Szene-Abschnitte
// pass ist ein GPURenderPassEncoder, die Pipelines existieren bereits
const drawScene = (pass, { opaquePipeline, uiPipeline }) => {
pass.pushDebugGroup('Szene');
pass.pushDebugGroup('Opake Geometrie');
pass.setPipeline(opaquePipeline);
pass.draw(36);
pass.popDebugGroup(); // Ende „Opake Geometrie“
pass.pushDebugGroup('UI-Overlay');
pass.setPipeline(uiPipeline);
pass.draw(6);
pass.popDebugGroup(); // Ende „UI-Overlay“
pass.popDebugGroup(); // Ende „Szene“
};
Push/Pop mit try/finally sicher paaren
const withDebugGroup = (pass, label, fn) => {
pass.pushDebugGroup(label);
try {
fn();
} finally {
pass.popDebugGroup(); // wird auch bei einer Exception ausgeführt
}
};
withDebugGroup(pass, 'Schatten', () => {
pass.setPipeline(shadowPipeline);
pass.draw(vertexCount);
});
// Wichtig · Fallstricke
- Stapel muss ausgeglichen sein: Rufst du
popDebugGroup()auf, obwohl keine Gruppe offen ist, wird der Encoder ungültig. Dasselbe passiert, wenn beiend()noch Gruppen offen sind. Der Fehler zeigt sich dann meist erst beimfinish()odersubmit()als Validierungsfehler. Mitdevice.pushErrorScope('validation')kannst du ihn abfangen. - Keine Gruppen über Pass-Grenzen: Eine im Renderpass geöffnete Gruppe muss auch in diesem Renderpass geschlossen werden. Du kannst sie nicht nach
end()überGPUCommandEncoder.popDebugGroup()schließen. Das gilt auch umgekehrt. - Debug-Gruppen haben keinen Einfluss auf das Ergebnis und kosten kaum Leistung. Eigene Debug-Werkzeuge wie Label-Stapel oder Wrapper-Funktionen schaltest du in Produktionsbuilds aber besser ab.
- Auch
GPURenderBundleEncoder,GPUComputePassEncoderundGPUCommandEncoderhaben diese Methode. Sie funktioniert dort genauso. - Kompatibilität: WebGPU gibt es nur in sicheren Kontexten (HTTPS). Chromium-Browser unterstützen es stabil ab Version 113. Firefox und Safari haben es erst später und nur teilweise eingeführt. Prüfe die Unterstützung vorher mit
if (!navigator.gpu) { … }.