Start · Sprachen · JavaScript · Referenz · GPUDevice.createBindGroupLayout()

GPUDevice.createBindGroupLayout()

Methode

Erstellt ein <code>GPUBindGroupLayout</code>, das Art, Sichtbarkeit und Binding-Nummern der GPU-Ressourcen (Buffer, Texturen, Sampler) einer Bind Group festlegt.

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

Signatur

GPUDevice.prototype.createBindGroupLayout(descriptor)

Beschreibung

createBindGroupLayout() beschreibt die Schnittstelle zwischen JavaScript-Ressourcen und einem WGSL-Shader. Ein Layout legt fest, welche Ressource unter welcher @binding(n)-Nummer liegt, welcher Art sie ist (Uniform-Buffer, Storage-Buffer, Sampler, Textur, Storage-Textur oder externe Textur) und in welchen Shader-Stufen (Vertex, Fragment, Compute) sie sichtbar ist.

Das Layout selbst enthält keine Daten. Es dient als Vorlage für GPUDevice.createBindGroup(), mit dem die konkreten Ressourcen gebunden werden, und für GPUDevice.createPipelineLayout(), das mehrere Bind-Group-Layouts (eines je @group(n)) zu einem Pipeline-Layout zusammenfasst.

Ein explizites Layout lohnt sich, wenn mehrere Pipelines dieselben Bind Groups nutzen sollen, zum Beispiel Kamera- oder Szenen-Uniforms, die in allen Render-Pipelines unter @group(0) liegen. Mit layout: "auto" erzeugte Pipelines haben dagegen eigene, nicht austauschbare Layouts.

Jeder Eintrag in entries braucht eine eindeutige binding-Nummer, eine visibility-Bitmaske aus GPUShaderStage und genau eines der Felder buffer, sampler, texture, storageTexture oder externalTexture.

Parameter

Name Typ Default Beschreibung
$descriptor Pflicht GPUBindGroupLayoutDescriptor Objekt, das das Layout beschreibt.
$descriptor.entries Pflicht Array<GPUBindGroupLayoutEntry> Liste der Einträge. Jeder Eintrag enthält binding (number, entspricht @binding(n) in WGSL), visibility (Bitmaske aus GPUShaderStage.VERTEX, FRAGMENT und COMPUTE) und genau einen Ressourcentyp: buffer, sampler, texture, storageTexture oder externalTexture.
$entries[].buffer { type?: 'uniform'|'storage'|'read-only-storage', hasDynamicOffset?: boolean, minBindingSize?: number } { type: 'uniform', hasDynamicOffset: false, minBindingSize: 0 } Bindet einen Buffer. Mit hasDynamicOffset gibt man den Offset erst bei setBindGroup() an.
$entries[].sampler { type?: 'filtering'|'non-filtering'|'comparison' } { type: 'filtering' } Bindet einen GPUSampler.
$entries[].texture { sampleType?: 'float'|'unfilterable-float'|'depth'|'sint'|'uint', viewDimension?: string, multisampled?: boolean } { sampleType: 'float', viewDimension: '2d', multisampled: false } Bindet eine Textur-Ansicht, aus der der Shader liest.
$entries[].storageTexture { access?: 'write-only'|'read-only'|'read-write', format: GPUTextureFormat, viewDimension?: string } { access: 'write-only', viewDimension: '2d' } Bindet eine Storage-Textur. format muss angegeben werden.
$entries[].externalTexture {} Bindet eine GPUExternalTexture, etwa ein Videobild.
$descriptor.label string "" Name zur Fehlersuche. Er erscheint in Fehlermeldungen und in Debug-Werkzeugen.

Rückgabewert

Typ
GPUBindGroupLayout
Beschreibung
Das neue Layout-Objekt. Wenn der Deskriptor ungültig ist, wird ein ungültiges Objekt zurückgegeben und ein Validierungsfehler im Device gemeldet. Die Methode wirft keine Ausnahme.

Beispiele

Uniform-Buffer, Sampler und Textur für eine Render-Pipeline

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

// Passt zu WGSL:
// @group(0) @binding(0) var<uniform> camera: Camera;
// @group(0) @binding(1) var mySampler: sampler;
// @group(0) @binding(2) var myTexture: texture_2d<f32>;
const bindGroupLayout = device.createBindGroupLayout({
  label: 'Material-Layout',
  entries: [
    { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
    { binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
    { binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } }
  ]
});

console.log(bindGroupLayout.label);
Material-Layout

Compute-Shader mit Storage-Buffern: Layout, Pipeline und Bind Group

const device = await (await navigator.gpu.requestAdapter()).requestDevice();

const layout = device.createBindGroupLayout({
  entries: [
    { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'read-only-storage' } },
    { binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } }
  ]
});

const module = device.createShaderModule({ code: `
  @group(0) @binding(0) var<storage, read> input: array<f32>;
  @group(0) @binding(1) var<storage, read_write> output: array<f32>;
  @compute @workgroup_size(64)
  fn main(@builtin(global_invocation_id) id: vec3u) {
    if (id.x < arrayLength(&input)) { output[id.x] = input[id.x] * 2.0; }
  }` });

const pipeline = device.createComputePipeline({
  layout: device.createPipelineLayout({ bindGroupLayouts: [layout] }),
  compute: { module, entryPoint: 'main' }
});

const size = 1024 * 4;
const inputBuf = device.createBuffer({ size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
const outputBuf = device.createBuffer({ size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC });

const bindGroup = device.createBindGroup({
  layout,
  entries: [
    { binding: 0, resource: { buffer: inputBuf } },
    { binding: 1, resource: { buffer: outputBuf } }
  ]
});
console.log('Bind Group bereit:', bindGroup instanceof GPUBindGroup);
Bind Group bereit: true

Validierungsfehler gezielt abfangen

const device = await (await navigator.gpu.requestAdapter()).requestDevice();

device.pushErrorScope('validation');
device.createBindGroupLayout({
  entries: [
    // Fehler: binding 0 ist doppelt vergeben
    { binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: {} },
    { binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: {} }
  ]
});
const error = await device.popErrorScope();
console.log(error ? `Fehler: ${error.message}` : 'Layout gültig');
Fehler: … (browserabhängige Meldung zur doppelten Binding-Nummer)