Signatur
Beschreibung
Mit pushDebugGroup() öffnen Sie im GPURenderBundleEncoder eine Debug-Gruppe mit einem frei wählbaren Namen. Alle danach aufgezeichneten Befehle wie setPipeline(), setBindGroup(), setVertexBuffer() oder draw() gehören zu dieser Gruppe, bis Sie sie mit popDebugGroup() wieder schließen.
Debug-Gruppen ändern nichts am Rendering. Sie dienen nur der Diagnose: Werkzeuge wie PIX, RenderDoc, Xcode GPU Frame Capture oder die WebGPU-Fehlermeldungen des Browsers zeigen die Namen an. So finden Sie schnell heraus, welcher Teil eines Render-Bundles einen Validierungsfehler ausgelöst hat oder Zeit kostet.
Gruppen lassen sich verschachteln. Jedes pushDebugGroup() braucht ein passendes popDebugGroup(), und zwar im selben Encoder, bevor Sie finish() aufrufen. Einzelne Zeitpunkte ohne Bereich markieren Sie mit insertDebugMarker().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $groupLabel Pflicht | string | Name der Debug-Gruppe. Werkzeuge und Fehlermeldungen zeigen ihn an, z. B. "Szene: Bäume". |
Rückgabewert
Beispiele
Zeichenbefehle eines Render-Bundles gruppieren
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const format = navigator.gpu.getPreferredCanvasFormat();
const module = device.createShaderModule({
code: `
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
var p = array(vec2f(0.0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
return vec4f(p[i], 0.0, 1.0);
}
@fragment fn fs() -> @location(0) vec4f { return vec4f(1.0, 0.4, 0.0, 1.0); }
`
});
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: { module, entryPoint: 'vs' },
fragment: { module, entryPoint: 'fs', targets: [{ format }] }
});
const bundleEncoder = device.createRenderBundleEncoder({ colorFormats: [format] });
bundleEncoder.pushDebugGroup('Dreieck zeichnen');
bundleEncoder.setPipeline(pipeline);
bundleEncoder.draw(3);
bundleEncoder.popDebugGroup();
const bundle = bundleEncoder.finish({ label: 'Dreieck-Bundle' });
console.log(bundle.label);
Verschachtelte Gruppen für mehrere Objekte
// device, format, pipeline und bindGroups wie im ersten Beispiel angelegt
const encoder = device.createRenderBundleEncoder({ colorFormats: [format] });
encoder.pushDebugGroup('Umgebung');
encoder.setPipeline(pipeline);
const objekte = ['Baum', 'Stein', 'Zaun'];
objekte.forEach((name, index) => {
encoder.pushDebugGroup(`Objekt: ${name}`);
encoder.insertDebugMarker(`Draw #${index}`);
encoder.draw(3);
encoder.popDebugGroup(); // schließt „Objekt: …“
});
encoder.popDebugGroup(); // schließt „Umgebung“
const bundle = encoder.finish();
Validierungsfehler durch fehlendes popDebugGroup() erkennen
device.pushErrorScope('validation');
const encoder = device.createRenderBundleEncoder({ colorFormats: [format] });
encoder.pushDebugGroup('Offene Gruppe');
encoder.setPipeline(pipeline);
encoder.draw(3);
// popDebugGroup() vergessen!
encoder.finish();
const error = await device.popErrorScope();
console.log(error ? `Fehler: ${error.message}` : 'Alles in Ordnung');
// Wichtig · Fallstricke
- Gruppen müssen ausgeglichen sein: Wenn beim Aufruf von
finish()noch Gruppen offen sind, gibt es einen Validierungsfehler. Das Ergebnis ist dann ein ungültigesGPURenderBundle. Auch einpopDebugGroup()ohne offene Gruppe ist ein Fehler. - Debug-Gruppen gelten nur innerhalb dieses Encoders. Sie können eine Gruppe nicht im Render-Pass öffnen und im Bundle schließen, und auch nicht umgekehrt.
GPURenderPassEncoder.executeBundles()übernimmt die Gruppen des Bundles nicht in den Stapel des Passes. - Die Namen haben keinen Einfluss auf das Rendering. Der Aufwand zur Laufzeit ist gering, in Hot Paths sollten Sie aber möglichst keine Namen dynamisch erzeugen.
- Nach
finish()ist der Encoder ungültig. Ein weiterer Aufruf vonpushDebugGroup()führt dann zu einem Validierungsfehler. - Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung. Die Unterstützung unterscheidet sich je nach Browser und Plattform. Prüfen Sie deshalb vorher mit
if (!navigator.gpu).