vgpu/coreAdvanced5 symbolsView source ↗

Symbols in this topic

bind and explicit binding helpers

bind, createBindGroupLayout, createPipelineLayout, createBindGroup, and createSampler are thin core helpers for explicit WebGPU binding. Use them when you want raw WebGPU layouts, bind groups, and samplers without shader reflection or layout: "auto" inference.

Import

TypeScript
1
import { bind, createBindGroup, createBindGroupLayout, createPipelineLayout, createSampler } from "vgpu/core";

Signature

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import type { Buffer, Device, Texture } from "vgpu/core";
 
type BindVisibility = GPUShaderStageFlags | string | readonly ("vertex" | "fragment" | "compute")[];
type DeviceLike = GPUDevice | Device | { readonly gpu: GPUDevice };
 
interface CreateBindGroupLayoutOptions {
  readonly label?: string;
  readonly entries: readonly GPUBindGroupLayoutEntry[];
}
 
interface CreatePipelineLayoutOptions {
  readonly label?: string;
  readonly bindGroups: readonly GPUBindGroupLayout[];
}
 
interface CreateBindGroupOptions {
  readonly label?: string;
  readonly layout: GPUBindGroupLayout;
  readonly entries: readonly GPUBindGroupEntry[];
}
 
interface SamplerDescriptorWithSugar extends GPUSamplerDescriptor {
  readonly filter?: "linear" | "nearest";
  readonly wrap?: "clamp" | "repeat" | "mirror";
}
 
declare function createBindGroupLayout(device: DeviceLike, opts: CreateBindGroupLayoutOptions): GPUBindGroupLayout;
declare function createPipelineLayout(device: DeviceLike, opts: CreatePipelineLayoutOptions): GPUPipelineLayout;
declare function createBindGroup(device: DeviceLike, opts: CreateBindGroupOptions): GPUBindGroup;
declare function createSampler(device: DeviceLike, descriptor?: SamplerDescriptorWithSugar): GPUSampler;
 
declare const bind: {
  readonly uniform: (binding: number, visibility: BindVisibility, opts?: Omit<GPUBufferBindingLayout, "type">) => GPUBindGroupLayoutEntry;
  readonly storage: (binding: number, visibility: BindVisibility, opts?: Omit<GPUBufferBindingLayout, "type">) => GPUBindGroupLayoutEntry;
  readonly readonlyStorage: (binding: number, visibility: BindVisibility, opts?: Omit<GPUBufferBindingLayout, "type">) => GPUBindGroupLayoutEntry;
  readonly texture: (binding: number, visibility: BindVisibility, opts?: GPUTextureBindingLayout) => GPUBindGroupLayoutEntry;
  readonly storageTexture: (binding: number, visibility: BindVisibility, opts: GPUStorageTextureBindingLayout) => GPUBindGroupLayoutEntry;
  readonly sampler: (binding: number, visibility: BindVisibility, opts?: GPUSamplerBindingLayout) => GPUBindGroupLayoutEntry;
  readonly resource: (binding: number, value: Buffer | Texture | GPUBuffer | GPUBufferBinding | GPUBindingResource | unknown) => GPUBindGroupEntry;
};

Parameters

Shared parameters

ParamTypeRequiredDefaultNotes
deviceDeviceLikeA raw GPUDevice, a vgpu Device, or an object with .gpu: GPUDevice. Helpers unwrap it before calling WebGPU.
bindingnumberExplicit non-negative integer @binding(n). Invalid values throw VGPU-CORE-BINDING-INVALID.
visibilityGPUShaderStageFlags | string | readonly ("vertex" | "fragment" | "compute")[]Numeric flags pass through. Strings split on `

createBindGroupLayout(device, opts)

ParamTypeRequiredDefaultNotes
optsCreateBindGroupLayoutOptionsLayout descriptor wrapper.
opts.labelstringundefinedForwarded to GPUDevice.createBindGroupLayout.
opts.entriesreadonly GPUBindGroupLayoutEntry[]Copied with [...opts.entries] before calling WebGPU; metadata is attached to the returned layout.

createPipelineLayout(device, opts)

ParamTypeRequiredDefaultNotes
optsCreatePipelineLayoutOptionsPipeline layout descriptor wrapper.
opts.labelstringundefinedForwarded to GPUDevice.createPipelineLayout.
opts.bindGroupsreadonly GPUBindGroupLayout[]Copied to WebGPU as bindGroupLayouts: [...opts.bindGroups].

createBindGroup(device, opts)

ParamTypeRequiredDefaultNotes
optsCreateBindGroupOptionsBind group descriptor wrapper.
opts.labelstringundefinedForwarded to GPUDevice.createBindGroup.
opts.layoutGPUBindGroupLayoutRequired explicit layout. Missing/falsy layout throws VGPU-CORE-BIND-GROUP-LAYOUT-REQUIRED; vgpu never uses bind group layout: "auto".
opts.entriesreadonly GPUBindGroupEntry[]Copied with [...opts.entries] before calling WebGPU; metadata is attached to the returned bind group.

createSampler(device, descriptor?)

ParamTypeRequiredDefaultNotes
descriptorSamplerDescriptorWithSugar{}Raw GPUSamplerDescriptor plus vgpu sugar. Sugar is stripped before calling WebGPU.
descriptor.filter"linear" | "nearest"undefinedExpands to magFilter and minFilter only. Raw magFilter/minFilter override this per key.
descriptor.wrap"clamp" | "repeat" | "mirror"undefinedExpands to all three address modes: "clamp""clamp-to-edge", "repeat""repeat", "mirror""mirror-repeat". Raw address fields override per axis.
descriptor.mipmapFilterGPUMipmapFilterModeWebGPU defaultNot set by filter; pass "linear" explicitly for anisotropic sampling.
descriptor.maxAnisotropynumberWebGPU defaultIf filter sugar is used and maxAnisotropy > 1, all three filters must resolve to "linear".

bind.* layout entry helpers

ParamTypeRequiredDefaultNotes
bind.uniform optsOmit<GPUBufferBindingLayout, "type">{}Returns { binding, visibility, buffer: { ...opts, type: "uniform" } }.
bind.storage optsOmit<GPUBufferBindingLayout, "type">{}Returns { binding, visibility, buffer: { ...opts, type: "storage" } }.
bind.readonlyStorage optsOmit<GPUBufferBindingLayout, "type">{}Returns { binding, visibility, buffer: { ...opts, type: "read-only-storage" } }.
bind.texture optsGPUTextureBindingLayout{}Returns { binding, visibility, texture: opts }.
bind.storageTexture optsGPUStorageTextureBindingLayoutReturns { binding, visibility, storageTexture: opts }; storage texture layout fields are not inferred.
bind.sampler optsGPUSamplerBindingLayout{}Returns { binding, visibility, sampler: opts }.
bind.resource valueunknownConverts vgpu Buffer to { buffer: buffer.gpu }, vgpu Texture/texture-like objects to createView(), raw GPUBuffer to { buffer }, and passes through other binding resources.

Returns:

  • createBindGroupLayout(...) returns GPUBindGroupLayout with vgpu layout metadata attached.
  • createPipelineLayout(...) returns raw GPUPipelineLayout.
  • createBindGroup(...) returns GPUBindGroup with vgpu bind-group metadata attached.
  • createSampler(...) returns raw GPUSampler.
  • bind.uniform(...), bind.storage(...), bind.readonlyStorage(...), bind.texture(...), bind.storageTexture(...), and bind.sampler(...) return GPUBindGroupLayoutEntry.
  • bind.resource(...) returns GPUBindGroupEntry.

Throws:

  • VGPU-CORE-BIND-GROUP-LAYOUT-REQUIRED when createBindGroup(...) receives a missing/falsy opts.layout — create and pass an explicit GPUBindGroupLayout.
  • VGPU-CORE-SAMPLER-ANISOTROPY-FILTERS when createSampler(...) uses filter sugar with maxAnisotropy > 1 but the resolved magFilter, minFilter, and mipmapFilter are not all "linear" — add mipmapFilter: "linear" and avoid raw non-linear overrides.
  • VGPU-CORE-BINDING-INVALID when any bind.* helper receives a negative, non-integer, or otherwise invalid binding — pass an explicit non-negative integer.
  • VGPU-CORE-VISIBILITY-INVALID when a string/array visibility contains an unknown shader stage name — use only "vertex", "fragment", and "compute", or pass numeric GPUShaderStageFlags.
  • Native WebGPU validation errors may occur for descriptor/layout/resource incompatibilities — fix the WebGPU descriptor or resource usage.

Examples

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { bind, createBindGroup, createBindGroupLayout, createPipelineLayout, createSampler } from "vgpu/core";
import { createMockAdapter } from "vgpu/mock";
 
const device = await createMockAdapter().requestDevice();
const uniformBuffer = device.createBuffer({ size: 64, usage: ["uniform", "copy_dst"] });
const texture = device.createTexture({
  size: [1, 1],
  format: "rgba8unorm",
  usage: ["texture_binding", "copy_src"],
});
const sampler = createSampler(device, { filter: "linear", wrap: "clamp" });
 
const groupLayout = createBindGroupLayout(device, {
  label: "scene.group0",
  entries: [
    bind.uniform(0, "vertex|fragment"),
    bind.texture(1, "fragment", { sampleType: "float" }),
    bind.sampler(2, ["fragment"], { type: "filtering" }),
  ],
});
 
const pipelineLayout = createPipelineLayout(device, { bindGroups: [groupLayout] });
const group = createBindGroup(device, {
  layout: groupLayout,
  entries: [
    bind.resource(0, uniformBuffer),
    bind.resource(1, texture),
    bind.resource(2, sampler),
  ],
});
 
console.log(pipelineLayout, group);
device.destroy();
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { createSampler } from "vgpu/core";
import { createMockAdapter } from "vgpu/mock";
 
const device = await createMockAdapter().requestDevice();
 
const mixedSampler = createSampler(device, {
  filter: "linear",
  wrap: "repeat",
  magFilter: "nearest", // raw field wins for this key only
});
 
const anisotropicSampler = createSampler(device, {
  filter: "linear",
  mipmapFilter: "linear",
  maxAnisotropy: 16,
});
 
console.log(mixedSampler, anisotropicSampler);
device.destroy();
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
import { bind, createBindGroupLayout } from "vgpu/core";
import { createMockAdapter } from "vgpu/mock";
 
const device = await createMockAdapter().requestDevice();
const computeLayout = createBindGroupLayout(device, {
  entries: [
    bind.storage(0, "compute", { hasDynamicOffset: true }),
    bind.storageTexture(1, "compute", { access: "write-only", format: "rgba8unorm", viewDimension: "2d" }),
  ],
});
 
console.log(computeLayout);
device.destroy();

Notes

  • These helpers are explicit by design: no WGSL reflection, no named binding maps, no hidden resource creation, and no layout: "auto" bind groups.
  • filter sugar does not set mipmapFilter. For anisotropic sampling, spell trilinear filtering explicitly.
  • Raw WebGPU descriptor fields override sugar per key, not all-or-nothing.
  • bind.resource(...) creates a default texture view for vgpu Texture; use a raw GPUTextureView when you need a non-default mip/array/format view.
  • Keep shader @group/@binding numbers synchronized with helper binding numbers; vgpu does not reflect or renumber them here.
  • See also: Device, Buffer, Texture, Queue, VGPUError.