vgpu/coreAdvanced2 symbolsView source ↗

Symbols in this topic

Texture

Texture is the core wrapper around a GPUTexture. Use it for explicit texture allocation through Device.createTexture(...), cached default views, resizing owned textures, readback, and wrapper-aware teardown.

Import

TypeScript
1
import { Texture } 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
import type { Device } from "vgpu/core";
 
type TextureUsageName = "copy_src" | "copy_dst" | "texture_binding" | "storage_binding" | "render_attachment";
 
interface TextureOptions {
  readonly size: readonly [width: number, height: number, depthOrArrayLayers?: number];
  readonly format: GPUTextureFormat;
  readonly usage: readonly TextureUsageName[];
  readonly mipLevelCount?: number;
  readonly sampleCount?: 1 | 4;
  readonly dimension?: GPUTextureDimension;
  readonly viewFormats?: readonly GPUTextureFormat[];
  readonly label?: string;
}
 
declare class Texture {
  constructor(device: Device, gpu: GPUTexture, options: TextureOptions, ownership?: "owned" | "external");
  get gpu(): GPUTexture;
  get options(): TextureOptions;
  get size(): TextureOptions["size"];
  get format(): GPUTextureFormat;
  get usage(): TextureOptions["usage"];
  get mipLevelCount(): number;
  get sampleCount(): 1 | 4;
  get dimension(): GPUTextureDimension;
  get viewFormats(): readonly GPUTextureFormat[];
  get label(): string | undefined;
  get view(): GPUTextureView;
  createView(desc?: GPUTextureViewDescriptor): GPUTextureView;
  resize(size: readonly [number, number] | readonly [number, number, number]): boolean;
  read(): Promise<Uint8Array>;
  readFloats(): Promise<Float32Array>;
  destroy(): void;
  dispose(): void;
}

Parameters

Device.createTexture(opts) / TextureOptions

ParamTypeRequiredDefaultNotes
opts.sizereadonly [width: number, height: number, depthOrArrayLayers?: number]Stored as tuple and converted to { width, height, depthOrArrayLayers: opts.size[2] ?? 1 } for WebGPU.
opts.formatGPUTextureFormatForwarded to GPUTextureDescriptor.format. read()/readFloats() support the color formats listed under Readback formats.
opts.usagereadonly TextureUsageName[]Vgpu usage names mapped to GPUTextureUsage flags.
opts.mipLevelCountnumberWebGPU default (1)Only included in the native descriptor when provided; getter returns opts.mipLevelCount ?? 1.
opts.sampleCount1 | 4WebGPU default (1)Only included when provided; getter returns opts.sampleCount ?? 1. Use 4 for MSAA where WebGPU allows it.
opts.dimensionGPUTextureDimensionWebGPU default ("2d")Only included when provided; getter returns opts.dimension ?? "2d".
opts.viewFormatsreadonly GPUTextureFormat[][]Only included when provided; getter returns opts.viewFormats ?? [].
opts.labelstringundefinedForwarded to GPUTextureDescriptor.label and exposed via texture.label.

Valid TextureUsageName values: "copy_src", "copy_dst", "texture_binding", "storage_binding", "render_attachment".

Constructor

ParamTypeRequiredDefaultNotes
deviceDeviceOwning device wrapper. Normally supplied by Device.createTexture(...).
gpuGPUTextureRaw WebGPU texture.
optionsTextureOptionsOriginal vgpu descriptor exposed as texture.options.
ownership"owned" | "external""owned"Owned textures can be resized and destroyed by the wrapper; external textures cannot be resized or destroyed by the wrapper.

Views, resize, readback

ParamTypeRequiredDefaultNotes
descGPUTextureViewDescriptorundefinedcreateView(desc?) forwards directly to gpu.createView(desc).
sizereadonly [number, number] | readonly [number, number, number]New extent for resize(...). A 2-tuple preserves the current depth/array layers.

Returns:

  • Device.createTexture(opts) returns Texture.
  • texture.view returns a cached default GPUTextureView created with no descriptor.
  • createView(desc?) returns a fresh GPUTextureView.
  • resize(size) returns false if the extent is unchanged, otherwise reallocates the raw texture and returns true.
  • read() returns Promise<Uint8Array> with unpadded texel bytes in the texture's own format: byteLength is width * height * bytesPerPixel(format) (4 for rgba8unorm, 8 for rgba16float, 16 for rgba32float, …). bgra* bytes are swizzled to RGBA order.
  • readFloats() returns Promise<Float32Array> with one f32 per component, row-major, width * height * components(format) long. Float formats keep their HDR values (no clamping to [0, 1]), unorm8 formats are normalized by / 255 without srgb gamma conversion.
  • destroy() and dispose() return void.

Throws:

  • VGPU-CORE-TEXTURE-DESTROYED when view, resize(...), read(), or readFloats() is used after destroy()/dispose() — create a new texture instead.
  • VGPU-CORE-EXTERNAL-TEXTURE when resize(...) is called on a texture constructed with ownership: "external" — resize the owning canvas/swapchain/resource instead.
  • VGPU-CORE-TEXTURE-RESIZE-LOCKED when an internal resize lock is active — follow the lock message and resize through the owner that installed the lock.
  • VGPU-CORE-UNSUPPORTED-FORMAT when read()/readFloats() is called on a format outside Readback formats (depth/stencil, packed, snorm/uint/sint, and compressed formats) — blit into a supported format first, or read the data through a storage buffer.
  • Native WebGPU validation errors may occur for invalid size/format/usage combinations.

Examples

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { createMockAdapter } from "vgpu/mock";
 
const device = await createMockAdapter().requestDevice();
const target = device.createTexture({
  label: "offscreen-target",
  size: [4, 4],
  format: "rgba8unorm",
  usage: ["render_attachment", "texture_binding", "copy_src"],
});
 
const defaultView = target.view;
const explicitView = target.createView({ label: "offscreen-target.view" });
console.log(defaultView, explicitView, target.sampleCount); // sampleCount defaults to 1
 
device.destroy();
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { createMockAdapter } from "vgpu/mock";
 
const device = await createMockAdapter().requestDevice();
const texture = device.createTexture({
  size: [1, 1, 6],
  format: "rgba8unorm",
  usage: ["texture_binding", "copy_src"],
});
 
console.log(texture.resize([2, 2])); // true; depthOrArrayLayers stays 6
console.log(texture.size); // [2, 2, 6]
console.log(texture.resize([2, 2, 6])); // false; unchanged
 
const pixels = await texture.read();
console.log(pixels.byteLength); // width * height * 4
 
device.destroy();
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { createMockAdapter } from "vgpu/mock";
 
const device = await createMockAdapter().requestDevice();
const hdr = device.createTexture({
  size: [2, 2],
  format: "rgba16float",
  usage: ["render_attachment", "copy_src"],
});
 
const bytes = await hdr.read();
console.log(bytes.byteLength); // 2 * 2 * 8 — raw half-float bytes
 
const floats = await hdr.readFloats();
console.log(floats.length); // 2 * 2 * 4 — decoded rgba components, values may exceed 1
 
device.destroy();

Readback formats

FormatBytes per texelComponentsreadFloats() decoding
r8unorm11byte / 255
rg8unorm22byte / 255
rgba8unorm, rgba8unorm-srgb44byte / 255 (no srgb gamma conversion)
bgra8unorm, bgra8unorm-srgb44byte / 255, channels swizzled to RGBA
r16float21binary16 widened to f32
rg16float42binary16 widened to f32
rgba16float84binary16 widened to f32
r32float41verbatim f32
rg32float82verbatim f32
rgba32float164verbatim f32

Subnormals, infinities, and NaN survive the binary16 → f32 widening unchanged.

Notes

  • texture.view is cached and descriptorless. Use createView(descriptor) for mip, array-layer, cube, or format-specific views.
  • resize(...) preserves all descriptor fields except size; contents are not preserved. Rebuild bind groups or caches keyed by texture.gpu after a resize.
  • Prefer texture.destroy()/texture.dispose() over texture.gpu.destroy() so the wrapper invalidates cached views and emits lifecycle state correctly.
  • Include "copy_src" when you plan to call read()/readFloats() on real WebGPU devices; mock textures can still expose their mock bytes.
  • Prefer readFloats() for HDR textures (rgba16float, rgba32float): read() hands back the raw half/float bytes, which are only useful after a decode. read() remains the right call for rgba8unorm snapshots and PNG encoding.
  • See also: Device, Buffer, Queue, cubeView, layerView.