Start · Sprachen · JavaScript · Referenz · GPURenderPassEncoder.pushDebugGroup()

GPURenderPassEncoder.pushDebugGroup()

Methode

Öffnet eine benannte Debug-Gruppe im Render-Pass. Alle danach kodierten Befehle gehören zu dieser Gruppe, bis <code>popDebugGroup()</code> sie schließt.

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

Signatur

GPURenderPassEncoder.prototype.pushDebugGroup(groupLabel)

Beschreibung

pushDebugGroup() beginnt innerhalb eines GPURenderPassEncoder eine Debug-Gruppe mit einem frei wählbaren Label. Alle Befehle, die danach kodiert werden (z. B. setPipeline(), setBindGroup(), draw()), gehören zu dieser Gruppe, bis sie mit popDebugGroup() wieder geschlossen wird.

Debug-Gruppen ändern nichts am Rendering. Sie dienen nur der Übersicht: Grafik-Debugger und Profiler wie RenderDoc, PIX, Xcode GPU Frame Capture oder die WebGPU-Inspektoren in den Browser-Entwicklertools zeigen die Befehle als verschachtelte, benannte Abschnitte an. Außerdem können Validierungsfehler in Fehlermeldungen des Browsers dadurch einer bestimmten Gruppe zugeordnet werden.

Gruppen lassen sich verschachteln, etwa „Frame → Opake Geometrie → Terrain“. Jedes pushDebugGroup() braucht ein passendes popDebugGroup(), und zwar im selben Render-Pass. Sind beim Aufruf von end() noch Gruppen offen, wird der Encoder ungültig, und GPUCommandEncoder.finish() löst einen Validierungsfehler aus.

Einzelne Markierungen ohne eigene Gruppe setzt man mit insertDebugMarker().

Parameter

Name Typ Default Beschreibung
$groupLabel Pflicht string Name der Debug-Gruppe. Wird in Debugging-Tools und Fehlermeldungen angezeigt, z. B. "Schatten-Pass".

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert.

Beispiele

Draw-Aufrufe in einer Debug-Gruppe bündeln

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const canvas = document.querySelector('canvas');
const context = 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 {
      var p = array<vec2f, 3>(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({ label: 'Frame-Encoder' });
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();

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

Verschachtelte Gruppen mit Markern

// Voraussetzung: pass, terrainPipeline, treePipeline und bindGroup existieren bereits
pass.pushDebugGroup('Opake Geometrie');

  pass.pushDebugGroup('Terrain');
  pass.setPipeline(terrainPipeline);
  pass.setBindGroup(0, bindGroup);
  pass.draw(6, 1024);
  pass.popDebugGroup();

  pass.pushDebugGroup('Bäume');
  pass.setPipeline(treePipeline);
  pass.insertDebugMarker('Instanzen LOD 0');
  pass.draw(36, 500);
  pass.popDebugGroup();

pass.popDebugGroup();

Hilfsfunktion, die push und pop sicher paart

// Schließt die Gruppe auch dann, wenn der Callback eine Exception wirft
const withDebugGroup = (encoder, label, fn) => {
  encoder.pushDebugGroup(label);
  try {
    fn(encoder);
  } finally {
    encoder.popDebugGroup();
  }
};

withDebugGroup(pass, 'UI-Overlay', (p) => {
  p.setPipeline(uiPipeline);
  p.draw(4, uiElements.length);
});

// Wichtig · Fallstricke

  • Gruppen müssen ausgeglichen sein: Sind beim Aufruf von pass.end() noch Gruppen offen oder wird popDebugGroup() ohne offene Gruppe aufgerufen, wird der Encoder ungültig. Der Fehler fällt oft erst bei commandEncoder.finish() bzw. als GPUValidationError auf, zum Beispiel über device.pushErrorScope('validation') oder uncapturederror.
  • Eine Gruppe darf nicht über Pass-Grenzen gehen. Eine im Render-Pass geöffnete Gruppe muss in diesem Render-Pass wieder geschlossen werden. Für pass-übergreifende Gruppen nimmt man GPUCommandEncoder.pushDebugGroup().
  • Debug-Gruppen kosten wenig, sind aber nicht völlig kostenlos. In Produktions-Builds kann man sie bei Bedarf über ein Debug-Flag abschalten.
  • Labels sollten keine sensiblen Daten enthalten, weil sie in Fehlermeldungen und Debug-Werkzeugen auftauchen.
  • Kompatibilität: WebGPU gibt es nur in sicheren Kontexten und nicht in allen Browsern bzw. auf allen Plattformen. Vorher prüfen, ob navigator.gpu vorhanden ist. Die Methode gibt es auch bei GPUComputePassEncoder und GPURenderBundleEncoder.