Start · Sprachen · JavaScript · Referenz · GPURenderBundleEncoder.insertDebugMarker()

GPURenderBundleEncoder.insertDebugMarker()

Methode

Fügt an der aktuellen Stelle der im Render-Bundle aufgezeichneten Befehle einen benannten Debug-Marker ein, der in GPU-Debuggern und Fehlermeldungen sichtbar wird.

seit JavaScript WebGPU – Chrome/Edge 113+, Safari 26+, Firefox 141 Kategorie: webapi

Signatur

GPURenderBundleEncoder.prototype.insertDebugMarker(markerLabel)

Beschreibung

Die Methode insertDebugMarker() des Interfaces GPURenderBundleEncoder setzt einen einzelnen, benannten Punkt in die Befehlsfolge, die gerade in ein Render-Bundle aufgezeichnet wird. Anders als pushDebugGroup()/popDebugGroup() umschließt ein Marker keinen Bereich, sondern markiert nur einen Zeitpunkt, z. B. „vor dem Zeichnen des Terrains“.

Marker beeinflussen das Rendering nicht. Sie dienen nur der Fehlersuche: Werkzeuge wie PIX, RenderDoc, Xcode GPU Frame Capture oder die Validierungsmeldungen des Browsers zeigen das Label an. So lassen sich einzelne Draw-Calls in einem Bundle schneller wiederfinden, gerade wenn ein Bundle später mit GPURenderPassEncoder.executeBundles() viele Male abgespielt wird.

Man ruft die Methode zwischen device.createRenderBundleEncoder() und finish() auf. Nach finish() ist der Encoder ungültig, weitere Aufrufe führen dann zu einem Validierungsfehler.

Parameter

Name Typ Default Beschreibung
$markerLabel Pflicht string Beliebiger Text, der als Label für den markierten Punkt verwendet wird, z. B. "Draw: Terrain".

Beispiele

Marker vor einem Draw-Call im Render-Bundle

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.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.5, 0, 1); }
  `
});

const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: { module, entryPoint: 'vs' },
  fragment: { module, entryPoint: 'fs', targets: [{ format }] }
});

const bundleEncoder = device.createRenderBundleEncoder({
  label: 'Dreieck-Bundle',
  colorFormats: [format]
});
bundleEncoder.setPipeline(pipeline);
bundleEncoder.insertDebugMarker('Draw: Dreieck');
bundleEncoder.draw(3);
const bundle = bundleEncoder.finish();
console.log(bundle.label);
Dreieck-Bundle

Mehrere Objekte markieren und Bundle abspielen

// Voraussetzung: device, pipeline, format, context (GPUCanvasContext) und
// vertexBuffers (Array von { name, buffer, count }) existieren bereits.
const encoder = device.createRenderBundleEncoder({ colorFormats: [format] });
encoder.setPipeline(pipeline);

for (const { name, buffer, count } of vertexBuffers) {
  encoder.insertDebugMarker(`Objekt: ${name}`);
  encoder.setVertexBuffer(0, buffer);
  encoder.draw(count);
}
const sceneBundle = encoder.finish();

const commandEncoder = device.createCommandEncoder();
const pass = commandEncoder.beginRenderPass({
  colorAttachments: [{
    view: context.getCurrentTexture().createView(),
    loadOp: 'clear',
    clearValue: { r: 0, g: 0, b: 0, a: 1 },
    storeOp: 'store'
  }]
});
pass.executeBundles([sceneBundle]);
pass.end();
device.queue.submit([commandEncoder.finish()]);

Marker mit Debug-Gruppe kombinieren

const enc = device.createRenderBundleEncoder({ colorFormats: [format] });
enc.pushDebugGroup('UI-Ebene');
enc.setPipeline(pipeline);
enc.insertDebugMarker('Button zeichnen');
enc.draw(6);
enc.insertDebugMarker('Icon zeichnen');
enc.draw(6);
enc.popDebugGroup(); // Gruppen müssen vor finish() geschlossen werden
const uiBundle = enc.finish();

// Wichtig · Fallstricke

  • Marker haben keinen Einfluss auf das Rendering. Browser dürfen sie in Produktionsbuilds ignorieren. Verlass dich also nicht auf sie, um das Programm zu steuern.
  • Nach finish() ist der Encoder ungültig. Ein weiterer Aufruf erzeugt einen Validierungsfehler, den du mit device.pushErrorScope('validation') oder über das Event uncapturederror abfangen kannst. Es wird keine JavaScript-Ausnahme geworfen.
  • Nicht verwechseln mit pushDebugGroup(): Offene Debug-Gruppen müssen vor finish() mit popDebugGroup() geschlossen werden. Einzelne Marker brauchen das nicht.
  • Sehr viele Marker in Schleifen, die oft laufen, kosten etwas Rechenzeit auf der CPU. Da Bundles aber meist nur einmal aufgezeichnet werden, spielt das selten eine Rolle.
  • Kompatibilität: WebGPU gibt es nur in sicheren Kontexten und noch nicht überall (Linux- und Android-Unterstützung ist je nach Browser unterschiedlich). Prüfe vorher mit if (!navigator.gpu), ob die API vorhanden ist.