---
title: Gpu
description: The main API (`vgpu`) context returned by `init()`. It owns device lifetime and the frame clock; every resource — canvas surfaces, offscreen targets, render, compute, storage, uniforms, samplers, and bundles — is created by a free function that takes the `Gpu` as its first argument.
---

# Gpu



## Import

```ts
import type { Gpu } from "vgpu";
import { init } from "vgpu/mock";
```

## Signature

```ts
import type { Bundle, BundleOptions, BundleRecorder, Clock, Compute, ComputeOptions, Draw, DrawOptions, Effect, EffectOptions, Frame, FrameLoopHandle, FrameLoopOptions, Geometry, GeometryOptions, GeometryRecipe, GpuErrorListener, PingPongStorage, PingPongTargets, SharedUniforms, StorageAccess, StorageBuffer, StorageOptions, Surface, SurfaceOptions, Target, TargetOptions, TargetTextureOptions, Timer, Visibility, VisibilityOptions } from "vgpu";
import type { Device } from "vgpu/core";
import type { ShaderSource } from "vgpu";

interface Gpu {
  readonly device: Device;
  readonly gpu: GPUDevice;
  /** True once `dispose()` ran. Reads stay legal; new work does not. */
  readonly disposed: boolean;
  dispose(): void;
  onError(cb: GpuErrorListener): () => void;
  settled(): Promise<void>;
}

// The creation API: named exports of `vgpu`, `vgpu/node` and `vgpu/mock`, all gpu-first.
declare function surface(gpu: Gpu, canvas: HTMLCanvasElement | OffscreenCanvas, opts?: SurfaceOptions): Surface;
declare function effect(gpu: Gpu, source: string | ShaderSource, opts?: EffectOptions): Effect;
declare function draw(gpu: Gpu, opts: DrawOptions): Draw;
declare function target(gpu: Gpu, opts: TargetOptions): Target;
declare function frame(gpu: Gpu, cb?: (frame: Frame) => void): Frame;
declare function frameLoop(gpu: Gpu, cb: (frame: Frame) => void, opts?: FrameLoopOptions): FrameLoopHandle;
declare function sampler(gpu: Gpu, desc?: GPUSamplerDescriptor): GPUSampler;
declare function geometry(gpu: Gpu, input: GeometryOptions | GeometryRecipe): Geometry;
declare function compute(gpu: Gpu, source: string | ShaderSource, opts?: ComputeOptions): Compute;
declare function storage(gpu: Gpu, bytes: number, access?: StorageAccess | StorageOptions): StorageBuffer;
declare function timer(gpu: Gpu): Timer;
declare function visibility(gpu: Gpu, options?: VisibilityOptions): Visibility;
declare function pingPong(gpu: Gpu, width: number, height: number, opts?: TargetTextureOptions): PingPongTargets;
declare function pingPongStorage(gpu: Gpu, bytes: number): PingPongStorage;
declare function uniforms<T extends Record<string, unknown>>(gpu: Gpu, values: T): SharedUniforms<T>;
declare function bundle(gpu: Gpu, opts: BundleOptions, record: (recorder: BundleRecorder) => void): Bundle;
declare function clock(gpu: Gpu): Clock;
```

## Parameters

`Gpu` is an object, not a callable constructor: it carries no creation methods. Every factory below takes it as `gpu`, its first argument.

| Param                 | Type                                   |         Required | Default        | Notes                                                                                                                                                                                 |                                                                                 |
| --------------------- | -------------------------------------- | ---------------: | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| surface.canvas        | `HTMLCanvasElement \| OffscreenCanvas` |                ✔ | —              | Canvas-like object with a `webgpu` context. A canvas may have one live `Surface`.                                                                                                     |                                                                                 |
| surface.opts          | `SurfaceOptions`                       |                ✖ | `{}`           | Per-surface canvas format, size, DPR, and auto-resize behavior.                                                                                                                       |                                                                                 |
| effect.source         | `string \| ShaderSource`               |                ✔ | —              | WGSL string or loader-produced `ShaderSource { version: 1, wgsl }`.                                                                                                                   |                                                                                 |
| effect.opts           | `EffectOptions`                        |                ✖ | `{}`           | `label` defaults to `"effect"`; `set` defaults to no initial bindings.                                                                                                                |                                                                                 |
| draw\.opts            | `DrawOptions`                          |                ✔ | —              | Includes required `shader`; see `DrawOptions`.                                                                                                                                        |                                                                                 |
| target.opts           | `TargetOptions`                        |                ✔ | —              | Offscreen target options. `size` is required.                                                                                                                                         |                                                                                 |
| frame.cb              | `(frame: Frame) => void`               |                ✖ | `undefined`    | If provided, submits automatically in `finally`; if omitted, caller must call `frame.submit()`.                                                                                       |                                                                                 |
| sampler.desc          | `GPUSamplerDescriptor`                 |                ✖ | `undefined`    | Cached by descriptor. `sampler(gpu)` is the canonical default sampler.                                                                                                                |                                                                                 |
| geometry.input        | \`GeometryOptions \\                   | GeometryRecipe\` | ✔              | —                                                                                                                                                                                     | A raw buffer descriptor, or a `vgpu/scene` recipe such as `box()` or `plane()`. |
| compute.source        | `string \| ShaderSource`               |                ✔ | —              | WGSL string or `ShaderSource`. Must contain a `@compute` entry point.                                                                                                                 |                                                                                 |
| compute.opts          | `ComputeOptions`                       |                ✖ | `{}`           | `label` defaults to `"compute"`; `set` defaults to no initial bindings.                                                                                                               |                                                                                 |
| storage.bytes         | `number`                               |                ✔ | —              | Byte size for a main API (`vgpu`) storage buffer.                                                                                                                                     |                                                                                 |
| storage.access        | `StorageAccess \| StorageOptions`      |                ✖ | `"read-write"` | Access string, or a `StorageOptions` bag `{ access?, indirect? }`. See `Compute` for storage buffer semantics, including `{ indirect: true }` for GPU-driven draw/dispatch arguments. |                                                                                 |
| timer                 | —                                      |                — | —              | No parameters. GPU pass timing; needs the `"timestamp-query"` device feature. See `Timer` for feature gating, spans, and result delivery.                                             |                                                                                 |
| visibility.options    | `VisibilityOptions`                    |                ✖ | `{}`           | Occlusion queries for visibility culling — core WebGPU, no device feature required. See `Visibility` for capacity and handle semantics.                                               |                                                                                 |
| pingPong.width        | `number`                               |                ✔ | —              | Floored and clamped to at least `1`.                                                                                                                                                  |                                                                                 |
| pingPong.height       | `number`                               |                ✔ | —              | Floored and clamped to at least `1`.                                                                                                                                                  |                                                                                 |
| pingPong.opts         | `TargetTextureOptions`                 |                ✖ | `{}`           | Texture/attachment options only; size comes from positional width/height.                                                                                                             |                                                                                 |
| pingPongStorage.bytes | `number`                               |                ✔ | —              | Creates two `"read-write"` storage buffers.                                                                                                                                           |                                                                                 |
| uniforms.values       | `Record<string, unknown>`              |                ✔ | —              | Cloned initial JS values; WGSL layout is adopted when first bound.                                                                                                                    |                                                                                 |
| bundle.opts           | `BundleOptions`                        |                ✔ | —              | Requires a `target` or target signature.                                                                                                                                              |                                                                                 |
| bundle.cb             | `(recorder: BundleRecorder) => void`   |                ✔ | —              | Records bundle commands immediately.                                                                                                                                                  |                                                                                 |
| onError.cb            | `GpuErrorListener`                     |                ✔ | —              | Receives asynchronous vgpu errors; returns an unsubscribe function.                                                                                                                   |                                                                                 |
| clock                 | —                                      |                — | —              | No parameters. The frame clock of this gpu: `{ time, deltaTime, frameCount, advance(dtSeconds) }`, one instance per gpu. See `Clock`.                                                 |                                                                                 |

**Returns:** each factory returns the resource named in its signature. `dispose()` and frame/pass callbacks return `void`.

**Throws:** `VGPU-GPU-DISPOSED` when any factory (or `clock(gpu)`) runs after `gpu.dispose()` — the device and everything it owned are gone, so the handle it would return could only fail later; create resources before disposing, or `init()` a new gpu; `VGPU-GPU-FOREIGN` when the first argument was not created by `init()` (a plain object, a `GPUDevice`, a gpu from another library): it carries no vgpu kernel, so pass the object returned by `init()` from `vgpu`, `vgpu/node` or `vgpu/mock`; `VGPU-LIMIT-STORAGE-VERTEX` / `VGPU-LIMIT-STORAGE-FRAGMENT` when a selected render entry exceeds its granted storage-buffer limit. The structured detail reports `stage`, `entryPoint`, `count`, `limit`, and each counted binding's `name`, `group`, and `binding`; request a supported limit or reduce/move the data; `VGPU-SHADER-SOURCE-INVALID` for malformed `ShaderSource`; `VGPU-SET-TEXTURE-FILTERABILITY` when a known facade texture format cannot satisfy an ordinarily sampled float binding (detail reports format, texture binding/name/label, and paired sampler identity); `VGPU-RING1-UNSUPPORTED` for unsupported effect/compute/target cases; `VGPU-TARGET-REQUIRED` when one-shot drawing needs an explicit target; `VGPU-TARGET-SIZE-REQUIRED` for runtime JS calls to `target(gpu)` without `size`; `VGPU-SURFACE-*` errors from `surface()`, surface resize, surface readback, or using disposed surfaces; plus method-specific `VGPU-R1-*`, `VGPU-R3-*`, and `VGPU-R4-*` errors documented on `Effect`, `Draw`, `Compute`, `Frame`, `Bundle`, `Target`, and `SharedUniforms`.

## Examples

```ts
import { init, draw, frame, target } from "vgpu/mock";

const gpu = await init();
const colorTarget = target(gpu, { size: [128, 128], depth: true });
const drawable = draw(gpu, {
  shader: `
    @vertex fn vs_main(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4f {
      var p = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));
      return vec4f(p[vi], 0, 1);
    }
    @fragment fn fs_main() -> @location(0) vec4f { return vec4f(1, 0, 1, 1); }
  `,
  // optional sync pre-warm; `await draw.compile(target)` is preferred during browser load
  targets: [colorTarget],
});

frame(gpu, (currentFrame) => {
  currentFrame.pass({ target: colorTarget, clear: [0, 0, 0, 1] }, (pass) => pass.draw(drawable));
});
```

```ts
import { init, effect, frameLoop, surface } from "vgpu";

declare const canvas: HTMLCanvasElement;

const gpu = await init();
const canvasSurface = surface(gpu, canvas, { dpr: [1, 2] });
const wave = effect(gpu, `@fragment fn fs_main() -> @location(0) vec4f { return vec4f(0.2, 0.4, 1.0, 1.0); }`);

frameLoop(gpu, (frame) => {
  frame.pass({ target: canvasSurface }, (pass) => pass.draw(wave));
});
```

## Error delivery

`gpu.onError(cb)` subscribes to asynchronous vgpu errors and returns an unsubscribe function. Listeners run in subscription order; removing one stops future deliveries; a throwing listener is reported to `console.error` without stopping the rest. If no listener is registered, vgpu reports the error to `console.error` by default.

`gpu.settled()` resolves after the current snapshot of pending error deliveries and in-flight pipeline work settles. It never rejects, so it is safe for deterministic tests and teardown.

## Notes

* There is no implicit screen property and no implicit default target. Pass `target` explicitly to frame passes and one-shot draws.
* Canvas-specific `size`, `dpr`, and `autoResize` live on `surface(gpu, canvas, opts)`, not on `init()`.
* Time is explicit JS state, and it lives on the clock, not on the context: read `clock(gpu).time` / `.deltaTime` / `.frameCount` and pass them through `set()` or `SharedUniforms` when shaders need them.
* Every factory rejects a disposed gpu with `VGPU-GPU-DISPOSED`, and an object vgpu did not create with `VGPU-GPU-FOREIGN`. Both are thrown synchronously, from the call that made the mistake.
* **See also:** `init`, `Clock`, `Surface`, `Effect`, `Draw`, `Compute`, `Frame`, `Target`, `Bundle`, `SharedUniforms`, `Timer`, `Visibility`.

## Sampled float texture layouts

vgpu infers sampled-texture layouts per selected WGSL entry point. A non-multisampled `texture_*<f32>` used by `textureSample*` or `textureGather*` with an ordinary sampler receives WebGPU `sampleType: "float"`; a texture used only by `textureLoad` remains `"unfilterable-float"`. Calls through helper functions are included.

The WGSL `f32` scalar type does not make every concrete texture format filterable. In particular, `r32float`, `rg32float`, and `rgba32float` require the device's `float32-filterable` feature for ordinary sampling. Use a filterable format, request that feature when supported, or use `textureLoad` without a sampler.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)