webgpu

package module
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: BSD-3-Clause Imports: 13 Imported by: 0

README

webgpu

WebGPU for Go in the browser (GOOS=js GOARCH=wasm): a typed API named after the WebGPU specification, usable from any Go program that runs in a window or a worker.

Status: released, v0.1.0 (pre-1.0: a minor version may change the API). It covers the direct API, batched command encoding (one JavaScript call per submit) and OffscreenCanvas surfaces. The go-wasmcontainers GPU host runs on it.

go get github.com/go-gfx/webgpu@v0.1.0
import "github.com/go-gfx/webgpu"

What it covers

  • Adapters and devices, refusing a fallback (software) adapter unless asked; device loss as a channel.
  • Buffers (vertex, index, uniform, storage, indirect), mapping, WriteBuffer.
  • Textures of every format of the specification, views, samplers, WriteTexture (dirty-rectangle updates), texture and buffer copies.
  • Bind group layouts, pipeline layouts, bind groups, render and compute pipelines (sync and async), depth-stencil, blending, multisampling.
  • Render passes (indexed and instanced draws, indirect draws, viewport, scissor), render bundles, compute passes.
  • Error scopes and uncaptured errors as Go errors.
  • Surfaces: an OffscreenCanvas with a WebGPU context, frames out as ImageBitmaps, and a signal for browsers that have no such context.

Surfaces

if err := webgpu.CanvasSupport(); err != nil {
	// errors.Is(err, webgpu.ErrNoCanvasContext): use another renderer
}
s, err := device.NewSurface(webgpu.SurfaceDescriptor{Width: 640, Height: 480})
tex, err := s.CurrentTexture()     // render into a view of it
bitmap, err := s.Present()         // transferToImageBitmap: post it to the page, or close it

s.CurrentView() is CurrentTexture plus CreateView(nil) for a frame loop: it returns the same Go handles every frame, standing for the new browser objects, and a whole frame (texture write, view, pass, submit) allocates 4 objects (TestFrameAllocs holds it to that).

A standalone OffscreenCanvas never shows itself (the specification says the canvas is presented automatically only for a placeholder canvas): Present moves the frame out as an ImageBitmap without a copy, for a worker to post to its page. NewSurfaceFromCanvas takes a canvas the page transferred with transferControlToOffscreen; the browser presents that one by itself. The surface size is bounded by the quota (SurfaceWidth, SurfaceHeight).

CanvasSupport probes getContext("webgpu") on an OffscreenCanvas. MDN's compatibility data lists that context in Chrome 113 (every platform from 144), Safari 26, and Firefox 141 on Windows only. Where it returns ErrNoCanvasContext, a program should fall back to a non-WebGPU renderer. The browser tests read each presented frame back through a 2D canvas, pixel by pixel, so a blank frame fails them. That includes the Linux SwiftShader lane, where headless Chromium needs Skia on Vulkan to present at all.

Batched encoding: one JavaScript call per submit

A syscall/js call costs about ten times the WebGPU call it carries. A Recorder records a whole submit in Go (buffer and texture writes (WriteBuffer, WriteTexture, ReadBuffer: stream version 4), render and compute passes, dynamic offsets included) as uint32 words; Submit copies them to JavaScript once and replay.js issues the WebGPU calls:

webgpu.InstallReplay(ctx, "/webgpu-replay.js") // once; "" loads the embedded copy from a blob: URL
rec := device.NewRecorder()                    // reuse it frame after frame
rec.WriteBuffer(uniforms, 0, frameData)
p := rec.BeginRenderPass(passDesc)
p.SetPipeline(pipe)
for _, s := range surfaces {
	p.SetBindGroup(0, s.group)
	p.DrawIndexed(s.count, 1, s.first, 0, 0)
}
p.End()
seq, err := rec.Submit()                       // one call; the first refused command, if any
err = device.WaitSubmitted(ctx, seq)           // only when the CPU must wait for the GPU

The recorder checks every command as the direct API does. replay.js (webgpu.ReplayJS, served as webgpu.ReplayJSName) is a plain same-origin script, so a page with script-src 'self' serves it like wasm_exec.js; it evaluates nothing and refuses a malformed stream. Its Go mirror, wire.Decode, reads the same format with the same checks. It is fuzzed, and a browser test holds the two readers to the same verdict on thousands of mutated streams.

The stream format is exported as package wire, which has no GOOS constraint. It contains the opcodes, Decode, StreamVersion and Remap. Remap rewrites every object id of a stream through a mapping and refuses any id the mapping does not grant. With it, a stream recorded in one place (for example, a VM guest sending it over the go-virtio/gpu webgpu-batch context) can be checked and replayed by another table without a second implementation of the format. Device.Replay(words, data, refs...) submits such a stream once its ids name this device's objects. It is checked with wire.Decode first, and it may name only the objects passed in refs.

Outside the browser, NewRemoteDevice(sink, label, quota) returns a remote device. Its creation calls, Queue.WriteBuffer and Recorder.Submit send wire descriptors and streams to a RemoteSink, for example a VM guest's virtio-gpu webgpu-batch context, where a real device runs them. The checks and quotas are the browser path's, so a remote device refuses at the call what a browser device refuses. A sink error loses the device. WriteTexture and command encoders are not carried (ErrRemoteUnsupported).

Read-back (stream version 4, wire.ReadBuffer). mapAsync is asynchronous, which a replayed stream cannot express, so Recorder.ReadBuffer(buf, offset, size) records a read: once the submit's GPU work has completed, the replayer maps the range, copies it into a read window of the submit and unmaps; Submit returns the bytes in the Readback. The rules are GPUBuffer.mapAsync's: the buffer has MAP_READ (which WebGPU allows only with COPY_DST, so the data is first copied there by CopyBufferToBuffer), the offset is a multiple of 8, the size a nonzero multiple of 4, the range inside the buffer. The window is bounded per submit (Quota.ReadBytes, at most wire.MaxReadWindow = 64 MiB). On a remote device the sink must be a ReadSink (SubmitRead fills the window), and Buffer.MapAsync(ctx, MapModeRead, ...), ReadMapped and Unmap work on top of it, one submit per map. On a browser device a Recorder is its own host and Submit waits and maps itself.

The host side is package batch (no GOOS constraint): a Context holds a guest's private id table over a Backend and offers the three messages every transport carries, Create, Destroy and Stream. Ids are translated before the backend sees anything (a stream can only name objects its own context created), a failed message loses the context, and the reads of a stream are checked before it runs: a Reader backend, a window within the quota (Config.MaxRead, 1 MiB by default), MAP_READ buffers, ranges inside the buffers and the window. Before the backend is called, wire.CheckRanges refuses what wire.Decode cannot know, with wire.ErrRange: a WriteBuffer or CopyBufferToBuffer range outside its buffer, an indirect dispatch or draw whose arguments leave the buffer, a Dispatch above maxComputeWorkgroupsPerDimension (65 535, or Config.MaxWorkgroups); Device.Replay applies the same rule to its granted buffers. WebGPU validation stays the second line. Under GOOS=js, NewDeviceBackend(device) is the backend on a browser device. go-virtio/gpudev and the go-wasmcontainers host module both build on it. Measured read-back round trips on an Apple GPU (Chromium, Metal) are in docs/readback.md.

Objects are created remotely the same way. EncodeDescriptor turns a creation descriptor (buffer, texture, view, sampler, shader module, bind group layout, pipeline layout, bind group, render or compute pipeline) into bytes. It names each referenced object by its replay id, in a header (wire.SplitDescriptor), and wire.RemapDescriptor translates those ids without reading the body. DecodeDescriptor rebuilds the descriptor with the receiver's objects. It refuses unknown fields, a wrong reference count and references of the wrong type, and it never keeps an object that the body itself carries. The decoder is fuzzed (FuzzDecodeDescriptor).

Submissions are numbered on a timeline (package timeline, shared by Queue.Submit and Recorder.Submit): completing number n completes every earlier one, the fence model of virtio-gpu, so many waiters cost one onSubmittedWorkDone round trip. The package has no dependency and no notion of a GPU.

Helpers

  • atlas.Shelf (package atlas, no GOOS constraint): a shelf packer that places many small images (textures, lightmaps, glyphs) in one texture.
  • Device.ReadTexture(ctx, src, width, height, bytesPerTexel): copies a region of a texture to Go memory, rows unpadded (the copy to a buffer wants rows padded to 256 bytes). For tests and screenshots, not a frame loop.

Errors at the call, not later on the device

WebGPU reports most mistakes asynchronously. This package checks in Go first and returns a *webgpu.BoundsError from the call: a WriteBuffer past the end of its buffer, a WriteTexture region outside the mip level or a layout that does not fit its data, a vertex buffer range past the buffer, a missing usage. Data from untrusted sources (game maps, container guests) cannot reach the GPU out of range without the caller being told. All size arithmetic is overflow checked and tested on 32-bit targets.

Quotas for embedders

q := &webgpu.Quota{MemoryBytes: 256 << 20, Pipelines: 256, ShaderBytes: 1 << 20}
d, err := adapter.RequestDevice(ctx, &webgpu.DeviceDescriptor{Quota: q})

A quota is charged before the browser is called (texture sizes are computed by the package, mips and samples included) and refunded on Destroy, Release or device loss. Optional features and limits are refused unless the quota lists them, timestamp-query included.

Promises

Methods that wait on a promise (RequestAdapter, RequestDevice, MapAsync, PopErrorScope, OnSubmittedWorkDone, Create*PipelineAsync) block only the calling goroutine, take a context.Context, and must not be called from a js.FuncOf callback.

Invalid objects in batch

batch.DeviceBackend.Create makes shader modules, bind group layouts, pipeline layouts, bind groups and pipelines inside a validation error scope. WGSL that does not compile (a reserved word, a syntax error) or an object WebGPU refuses is an error wrapping batch.ErrInvalid whose text is the browser's message with the WGSL line and column; without the scope it was a silent no-op that later work tripped over. TestInvalidWGSLOnGPU runs a reserved word, a syntax error and an unknown function, and a valid control.

Tests

The descriptor, validation and quota code is platform-neutral and has every block covered on Linux, macOS, Windows and linux/386. The calls are tested in a real browser worker by internal/cmd/wasmbrowser, a go test -exec runner over Playwright:

go -C internal/cmd/wasmbrowser build -o /tmp/wasmbrowser .
WEBGPU_REQUIRE_GPU=1 GOOS=js GOARCH=wasm go test -exec=/tmp/wasmbrowser ./...

The browser tests render a GLQuake-shaped frame (8-bit index texture through a palette texture and a sampler, vertex and index buffers, instancing with per-instance data in a storage buffer, a depth buffer, a dirty-rectangle texture update, the same frame from a render bundle) and check every pixel. CI runs them on macOS with a GPU required (a fallback adapter fails the lane) and on Linux on SwiftShader.

Performance

Measured on an Apple M4 Max, Chromium 143, Metal adapter, in a worker. The machine's load was 10 to 16 during these runs, so the numbers are indicative. One syscall/js call costs about 200 ns for setPipeline, setBindGroup or draw, against 17 ns for the same draw issued from JavaScript: the cost is the call itself (each Value.Call decodes its method name).

CPU time per frame of n draws (setBindGroup + draw each), median of three runs of BenchmarkFrame:

draws direct calls Recorder the same frame in JavaScript
100 80 µs 22 µs 13 µs
1000 491 µs 85 µs 32 µs
5000 2320 µs 380 µs 138 µs

Batching is 5.8 to 6.1 times faster than direct calls from 1000 draws up. The design estimated about 15 times, from a prototype that recorded with no checks and no object table; the checks and the table cost the difference. It is still 2.7 times the JavaScript floor: recording costs about 40 ns per draw in wasm (10 ns natively, BenchmarkRecordDraws), and the rest is the replay itself. All of these timings were taken with the machine's load between 10 and 16, so they are indicative, not final.

WriteBuffer copies through a staging array the device reuses; allocating a fresh Uint8Array per call, as is common, was 3 to 4 times slower. Whether the source is a 64 KiB array, a view into a 64 MiB one or into the Go instance's own memory makes no difference: about 5 µs per 64 KiB write, all spent in the browser's copy (BenchmarkWriteBuffer64KiBSource). An earlier prototype that found the Go-memory view slower had measured a queue that was backing up. A zero-copy path would save one copy per write but would depend on wasm_exec.js internals, so writes go through the staging copy.

Licence

BSD 3-Clause, see LICENSE.

Documentation

Overview

Package webgpu is WebGPU for Go programs that run in the browser (GOOS=js GOARCH=wasm), in a window or a worker: typed handles named after the WebGPU IDL (https://www.w3.org/TR/webgpu/), errors as Go errors, promises awaited without blocking the event loop, and quotas an embedder can enforce on code it does not trust.

Shape

g, err := webgpu.Navigator()                       // navigator.gpu
a, err := g.RequestAdapter(ctx, nil)               // refuses a fallback adapter by default
d, err := a.RequestDevice(ctx, &webgpu.DeviceDescriptor{Quota: q})
b, err := d.CreateBuffer(webgpu.BufferDescriptor{Size: 64, Usage: webgpu.BufferUsageVertex | webgpu.BufferUsageCopyDst})
err = d.Queue().WriteBuffer(b, 0, vertices)         // range checked here
enc, _ := d.CreateCommandEncoder("frame")
pass, _ := enc.BeginRenderPass(desc)
pass.SetPipeline(p); pass.SetVertexBuffer(0, b, 0, 0); pass.Draw(3, 1, 0, 0)
err = pass.End()                                    // first refused command, if any

Descriptors are Go structs; a zero field is left out of the dictionary so the browser applies the specification's default.

Batched encoding

A syscall/js call costs about ten times the WebGPU call it carries. A Recorder records a whole submit as uint32 words in Go and Submit replays it with one call into replay.js (ReplayJS, loaded once by InstallReplay), which issues the WebGPU calls from JavaScript. Every command is checked as in the direct API. Submissions are numbered on the device's timeline (package timeline): WaitSubmitted(ctx, seq) waits for the GPU, and completing a number completes every earlier one.

Errors

WebGPU reports most mistakes asynchronously, as validation errors on the device that nobody sees without an error scope. This package checks what it can in Go first and returns a *BoundsError at the call: out-of-range buffer writes and copies, texture regions outside a mip level, linear layouts that do not fit their data (the specification's "validating linear texture data"), missing usages. Exceptions the browser throws are *JSError; device errors are *GPUError, through PushErrorScope and PopErrorScope or OnUncapturedError (delivered with the next round trip to the GPU process).

Promises

RequestAdapter, RequestDevice, MapAsync, PopErrorScope, OnSubmittedWorkDone and the Create*PipelineAsync methods wait on a promise: only the calling goroutine blocks, the browser's event loop keeps running. They must not be called from a js.FuncOf callback, whose goroutine holds the event loop. Each takes a context.

Quotas

A Quota bounds GPU memory (buffer and texture bytes, computed by the package: TextureBytes), live pipelines, WGSL source size, and the features and limits a device may require. It is charged before the browser is called and refunded on Destroy, Release, or the loss of the device; several devices may share one. Nothing is reachable except through a Device the embedder created.

Surfaces

A Surface is an OffscreenCanvas with a WebGPU context: render into CurrentTexture, and Present moves the frame out as an ImageBitmap (standalone canvases are never presented by the browser). CanvasSupport returns ErrNoCanvasContext where the browser has no such context (Firefox outside Windows): the signal to fall back to another renderer.

Outside GOOS=js the package compiles (descriptors, validation, quotas) and Navigator does not exist.

Index

Constants

View Source
const (
	TextureFormatR8Unorm             TextureFormat = "r8unorm"
	TextureFormatR8Uint              TextureFormat = "r8uint"
	TextureFormatRG8Unorm            TextureFormat = "rg8unorm"
	TextureFormatR32Float            TextureFormat = "r32float"
	TextureFormatR32Uint             TextureFormat = "r32uint"
	TextureFormatRGBA8Unorm          TextureFormat = "rgba8unorm"
	TextureFormatRGBA8UnormSRGB      TextureFormat = "rgba8unorm-srgb"
	TextureFormatBGRA8Unorm          TextureFormat = "bgra8unorm"
	TextureFormatBGRA8UnormSRGB      TextureFormat = "bgra8unorm-srgb"
	TextureFormatRGBA16Float         TextureFormat = "rgba16float"
	TextureFormatRGBA32Float         TextureFormat = "rgba32float"
	TextureFormatStencil8            TextureFormat = "stencil8"
	TextureFormatDepth16Unorm        TextureFormat = "depth16unorm"
	TextureFormatDepth24Plus         TextureFormat = "depth24plus"
	TextureFormatDepth24PlusStencil8 TextureFormat = "depth24plus-stencil8"
	TextureFormatDepth32Float        TextureFormat = "depth32float"

	TextureDimension1D TextureDimension = "1d"
	TextureDimension2D TextureDimension = "2d"
	TextureDimension3D TextureDimension = "3d"

	TextureViewDimension1D        TextureViewDimension = "1d"
	TextureViewDimension2D        TextureViewDimension = "2d"
	TextureViewDimension2DArray   TextureViewDimension = "2d-array"
	TextureViewDimensionCube      TextureViewDimension = "cube"
	TextureViewDimensionCubeArray TextureViewDimension = "cube-array"
	TextureViewDimension3D        TextureViewDimension = "3d"

	TextureAspectAll         TextureAspect = "all"
	TextureAspectStencilOnly TextureAspect = "stencil-only"
	TextureAspectDepthOnly   TextureAspect = "depth-only"

	AddressModeClampToEdge  AddressMode = "clamp-to-edge"
	AddressModeRepeat       AddressMode = "repeat"
	AddressModeMirrorRepeat AddressMode = "mirror-repeat"

	FilterModeNearest FilterMode = "nearest"
	FilterModeLinear  FilterMode = "linear"

	MipmapFilterModeNearest MipmapFilterMode = "nearest"
	MipmapFilterModeLinear  MipmapFilterMode = "linear"

	CompareFunctionNever        CompareFunction = "never"
	CompareFunctionLess         CompareFunction = "less"
	CompareFunctionEqual        CompareFunction = "equal"
	CompareFunctionLessEqual    CompareFunction = "less-equal"
	CompareFunctionGreater      CompareFunction = "greater"
	CompareFunctionNotEqual     CompareFunction = "not-equal"
	CompareFunctionGreaterEqual CompareFunction = "greater-equal"
	CompareFunctionAlways       CompareFunction = "always"

	PrimitiveTopologyPointList     PrimitiveTopology = "point-list"
	PrimitiveTopologyLineList      PrimitiveTopology = "line-list"
	PrimitiveTopologyLineStrip     PrimitiveTopology = "line-strip"
	PrimitiveTopologyTriangleList  PrimitiveTopology = "triangle-list"
	PrimitiveTopologyTriangleStrip PrimitiveTopology = "triangle-strip"

	IndexFormatUint16 IndexFormat = "uint16"
	IndexFormatUint32 IndexFormat = "uint32"

	FrontFaceCCW FrontFace = "ccw"
	FrontFaceCW  FrontFace = "cw"

	CullModeNone  CullMode = "none"
	CullModeFront CullMode = "front"
	CullModeBack  CullMode = "back"

	VertexFormatUint8x4   VertexFormat = "uint8x4"
	VertexFormatUnorm8x4  VertexFormat = "unorm8x4"
	VertexFormatUint16x2  VertexFormat = "uint16x2"
	VertexFormatFloat16x2 VertexFormat = "float16x2"
	VertexFormatFloat16x4 VertexFormat = "float16x4"
	VertexFormatFloat32   VertexFormat = "float32"
	VertexFormatFloat32x2 VertexFormat = "float32x2"
	VertexFormatFloat32x3 VertexFormat = "float32x3"
	VertexFormatFloat32x4 VertexFormat = "float32x4"
	VertexFormatUint32    VertexFormat = "uint32"
	VertexFormatUint32x2  VertexFormat = "uint32x2"
	VertexFormatUint32x4  VertexFormat = "uint32x4"

	VertexStepModeVertex   VertexStepMode = "vertex"
	VertexStepModeInstance VertexStepMode = "instance"

	LoadOpLoad  LoadOp = "load"
	LoadOpClear LoadOp = "clear"

	StoreOpStore   StoreOp = "store"
	StoreOpDiscard StoreOp = "discard"

	BlendFactorZero             BlendFactor = "zero"
	BlendFactorOne              BlendFactor = "one"
	BlendFactorSrc              BlendFactor = "src"
	BlendFactorOneMinusSrc      BlendFactor = "one-minus-src"
	BlendFactorSrcAlpha         BlendFactor = "src-alpha"
	BlendFactorOneMinusSrcAlpha BlendFactor = "one-minus-src-alpha"
	BlendFactorDst              BlendFactor = "dst"
	BlendFactorOneMinusDst      BlendFactor = "one-minus-dst"
	BlendFactorDstAlpha         BlendFactor = "dst-alpha"
	BlendFactorOneMinusDstAlpha BlendFactor = "one-minus-dst-alpha"
	BlendFactorConstant         BlendFactor = "constant"

	BlendOperationAdd             BlendOperation = "add"
	BlendOperationSubtract        BlendOperation = "subtract"
	BlendOperationReverseSubtract BlendOperation = "reverse-subtract"
	BlendOperationMin             BlendOperation = "min"
	BlendOperationMax             BlendOperation = "max"

	StencilOperationKeep    StencilOperation = "keep"
	StencilOperationZero    StencilOperation = "zero"
	StencilOperationReplace StencilOperation = "replace"
	StencilOperationInvert  StencilOperation = "invert"

	BufferBindingTypeUniform         BufferBindingType = "uniform"
	BufferBindingTypeStorage         BufferBindingType = "storage"
	BufferBindingTypeReadOnlyStorage BufferBindingType = "read-only-storage"

	SamplerBindingTypeFiltering    SamplerBindingType = "filtering"
	SamplerBindingTypeNonFiltering SamplerBindingType = "non-filtering"
	SamplerBindingTypeComparison   SamplerBindingType = "comparison"

	TextureSampleTypeFloat         TextureSampleType    = "float"
	TextureSampleTypeUnfilterable  TextureSampleType    = "unfilterable-float"
	TextureSampleTypeDepth         TextureSampleType    = "depth"
	TextureSampleTypeSint          TextureSampleType    = "sint"
	TextureSampleTypeUint          TextureSampleType    = "uint"
	StorageTextureAccessWriteOnly  StorageTextureAccess = "write-only"
	StorageTextureAccessReadOnly   StorageTextureAccess = "read-only"
	StorageTextureAccessReadWrite  StorageTextureAccess = "read-write"
	FeatureTimestampQuery          FeatureName          = "timestamp-query"
	FeatureDepth32FloatStencil8    FeatureName          = "depth32float-stencil8"
	FeatureTextureCompressionBC    FeatureName          = "texture-compression-bc"
	FeatureIndirectFirstInstance   FeatureName          = "indirect-first-instance"
	FeatureShaderF16               FeatureName          = "shader-f16"
	FeatureFloat32Filterable       FeatureName          = "float32-filterable"
	PowerPreferenceLowPower        PowerPreference      = "low-power"
	PowerPreferenceHighPerformance PowerPreference      = "high-performance"
	CanvasAlphaModeOpaque          CanvasAlphaMode      = "opaque"
	CanvasAlphaModePremultiplied   CanvasAlphaMode      = "premultiplied"
	ErrorFilterValidation          ErrorFilter          = "validation"
	ErrorFilterOutOfMemory         ErrorFilter          = "out-of-memory"
	ErrorFilterInternal            ErrorFilter          = "internal"
)
View Source
const (
	BufferUsageMapRead      BufferUsage = 0x0001
	BufferUsageMapWrite     BufferUsage = 0x0002
	BufferUsageCopySrc      BufferUsage = 0x0004
	BufferUsageCopyDst      BufferUsage = 0x0008
	BufferUsageIndex        BufferUsage = 0x0010
	BufferUsageVertex       BufferUsage = 0x0020
	BufferUsageUniform      BufferUsage = 0x0040
	BufferUsageStorage      BufferUsage = 0x0080
	BufferUsageIndirect     BufferUsage = 0x0100
	BufferUsageQueryResolve BufferUsage = 0x0200

	TextureUsageCopySrc          TextureUsage = 0x01
	TextureUsageCopyDst          TextureUsage = 0x02
	TextureUsageTextureBinding   TextureUsage = 0x04
	TextureUsageStorageBinding   TextureUsage = 0x08
	TextureUsageRenderAttachment TextureUsage = 0x10

	ShaderStageVertex   ShaderStage = 0x1
	ShaderStageFragment ShaderStage = 0x2
	ShaderStageCompute  ShaderStage = 0x4

	MapModeRead  MapMode = 0x1
	MapModeWrite MapMode = 0x2

	ColorWriteRed   ColorWrite = 0x1
	ColorWriteGreen ColorWrite = 0x2
	ColorWriteBlue  ColorWrite = 0x4
	ColorWriteAlpha ColorWrite = 0x8
	ColorWriteAll   ColorWrite = 0xF
)
View Source
const ReplayJSName = "webgpu-replay.js"

ReplayJSName is the file name ReplayJS is conventionally served under.

Variables

View Source
var (
	// ErrNoWebGPU: this context has no navigator.gpu (no WebGPU, or not a
	// secure context, or not GOOS=js).
	ErrNoWebGPU = errors.New("webgpu: navigator.gpu is not available")
	// ErrNoAdapter: requestAdapter resolved to null.
	ErrNoAdapter = errors.New("webgpu: no adapter")
	// ErrFallbackAdapter: the only adapter is a fallback (software) one and
	// the caller did not accept it. Work on such an adapter is not GPU work.
	ErrFallbackAdapter = errors.New("webgpu: only a fallback (software) adapter")
	// ErrDestroyed: the object (or its device) was destroyed or released.
	ErrDestroyed = errors.New("webgpu: object destroyed")
	// ErrNoCanvasContext: OffscreenCanvas.getContext("webgpu") returned
	// null here (e.g. Firefox outside Windows); fall back to another
	// renderer.
	ErrNoCanvasContext = errors.New("webgpu: no WebGPU context on OffscreenCanvas")
)
View Source
var ErrDescriptor = errors.New("webgpu: descriptor")

ErrDescriptor is wrapped by every EncodeDescriptor and DecodeDescriptor error.

View Source
var ErrMapState = errors.New("webgpu: buffer is not unmapped")

ErrMapState: MapAsync on a buffer that is already mapped; WebGPU requires the "unmapped" state.

View Source
var ErrNotRead = errors.New("webgpu: the read-back has not completed")

ErrNotRead: a Readback whose submit has not completed (or failed).

View Source
var ErrNotRemote = errors.New("webgpu: outside the browser, only a remote device (NewRemoteDevice) runs GPU work")

ErrNotRemote: a GPU call outside the browser on a Device that is not a remote device.

View Source
var ErrRecorderState = errors.New("webgpu: recorder: command out of order")

ErrRecorderState: a command outside the pass it belongs to, a pass left open at Submit, or a Recorder used after Submit.

View Source
var ErrRemoteUnsupported = errors.New("webgpu: not supported by a remote device")

ErrRemoteUnsupported: a call a remote device does not carry (yet).

View Source
var LimitNames = []string{
	"maxTextureDimension1D", "maxTextureDimension2D", "maxTextureDimension3D", "maxTextureArrayLayers",
	"maxBindGroups", "maxBindGroupsPlusVertexBuffers", "maxImmediateSize", "maxBindingsPerBindGroup",
	"maxDynamicUniformBuffersPerPipelineLayout", "maxDynamicStorageBuffersPerPipelineLayout",
	"maxSampledTexturesPerShaderStage", "maxSamplersPerShaderStage",
	"maxStorageBuffersPerShaderStage", "maxStorageBuffersInVertexStage", "maxStorageBuffersInFragmentStage",
	"maxStorageTexturesPerShaderStage", "maxStorageTexturesInVertexStage", "maxStorageTexturesInFragmentStage",
	"maxUniformBuffersPerShaderStage", "maxUniformBufferBindingSize", "maxStorageBufferBindingSize",
	"minUniformBufferOffsetAlignment", "minStorageBufferOffsetAlignment",
	"maxVertexBuffers", "maxBufferSize", "maxVertexAttributes", "maxVertexBufferArrayStride",
	"maxInterStageShaderVariables", "maxColorAttachments", "maxColorAttachmentBytesPerSample",
	"maxComputeWorkgroupStorageSize", "maxComputeInvocationsPerWorkgroup",
	"maxComputeWorkgroupSizeX", "maxComputeWorkgroupSizeY", "maxComputeWorkgroupSizeZ",
	"maxComputeWorkgroupsPerDimension",
}

LimitNames are the attributes of GPUSupportedLimits (https://www.w3.org/TR/webgpu/#gpusupportedlimits). The interface's attributes live on its prototype and cannot be enumerated, so they are read by name; a name the browser does not have is skipped.

View Source
var ReplayJS string

ReplayJS is replay.js, the JavaScript half of batched encoding (Recorder). A page with a strict Content-Security-Policy (script-src 'self') must serve it from its own origin, as it serves wasm_exec.js, and pass its URL to InstallReplay; ReplayJSName is the conventional file name.

Functions

func DecodeDescriptor added in v0.3.0

func DecodeDescriptor(kind wire.Kind, b []byte, resolve Resolver) (any, error)

DecodeDescriptor rebuilds a creation descriptor of kind from its wire bytes, resolving references with resolve. It returns the same types EncodeDescriptor takes. The bytes come from another party: the body must name no unknown field, the reference count must match the body, every reference must resolve to an object of the right type, and the object fields of the body are discarded, never trusted.

func EncodeDescriptor added in v0.3.0

func EncodeDescriptor(desc any) (wire.Kind, []byte, error)

EncodeDescriptor returns the kind and wire bytes of a creation descriptor: BufferDescriptor, TextureDescriptor, TextureViewCreation, SamplerDescriptor, ShaderModuleDescriptor, BindGroupLayoutDescriptor, PipelineLayoutDescriptor, BindGroupDescriptor, RenderPipelineDescriptor or ComputePipelineDescriptor. Referenced objects must not be nil except where the descriptor allows it (a pipeline's layout, a render pipeline's fragment state).

func ReplayID added in v0.3.0

func ReplayID(h any) (uint32, error)

ReplayID returns the id that streams and wire descriptors name h by (allocated on first use): the id a transport translates a foreign stream's or descriptor's ids to. h is any object handle of this package.

func TextureBytes

func TextureBytes(d TextureDescriptor) (int64, error)

TextureBytes is what a texture costs in GPU memory as this package counts it: every mip level's physical extent, in texel blocks, times the format's memory cost, times the sample count. It is an upper bound for quota purposes, not a promise about the driver's allocation.

Types

type AdapterInfo

type AdapterInfo struct {
	Vendor, Architecture, Device, Description string
	Fallback                                  bool
}

AdapterInfo is a GPUAdapterInfo. Fallback reports a fallback (software) adapter, e.g. SwiftShader: work done on it is not GPU work.

type AddressMode

type AddressMode string

type BindGroup

type BindGroup struct {
	// contains filtered or unexported fields
}

BindGroup is a GPUBindGroup.

func (*BindGroup) Label

func (o *BindGroup) Label() string

Label returns the label the object was created with.

type BindGroupDescriptor

type BindGroupDescriptor struct {
	Label   string
	Layout  *BindGroupLayout
	Entries []BindGroupEntry
}

BindGroupDescriptor is a GPUBindGroupDescriptor.

type BindGroupEntry

type BindGroupEntry struct {
	Binding     uint32
	Buffer      *Buffer
	Offset      uint64
	Size        uint64
	Sampler     *Sampler
	TextureView *TextureView
}

BindGroupEntry is a GPUBindGroupEntry: exactly one of Buffer, Sampler, TextureView is set. Size 0 binds the rest of the buffer from Offset.

type BindGroupLayout

type BindGroupLayout struct {
	// contains filtered or unexported fields
}

BindGroupLayout is a GPUBindGroupLayout.

func (*BindGroupLayout) Label

func (o *BindGroupLayout) Label() string

Label returns the label the object was created with.

type BindGroupLayoutDescriptor

type BindGroupLayoutDescriptor struct {
	Label   string
	Entries []BindGroupLayoutEntry
}

BindGroupLayoutDescriptor is a GPUBindGroupLayoutDescriptor.

type BindGroupLayoutEntry

type BindGroupLayoutEntry struct {
	Binding        uint32
	Visibility     ShaderStage
	Buffer         *BufferBindingLayout
	Sampler        *SamplerBindingLayout
	Texture        *TextureBindingLayout
	StorageTexture *StorageTextureBindingLayout
}

BindGroupLayoutEntry is a GPUBindGroupLayoutEntry: exactly one of Buffer, Sampler, Texture, StorageTexture is set.

type BlendComponent

type BlendComponent struct {
	Operation            BlendOperation
	SrcFactor, DstFactor BlendFactor
}

BlendComponent is a GPUBlendComponent.

type BlendFactor

type BlendFactor string

type BlendOperation

type BlendOperation string

type BlendState

type BlendState struct{ Color, Alpha BlendComponent }

BlendState is a GPUBlendState.

type BoundsError

type BoundsError struct {
	Op  string
	Msg string
}

BoundsError reports an argument the package refused before it reached the browser: an out-of-range write, a misaligned offset, a missing usage. WebGPU itself would report most of these only asynchronously, as a validation error on the device; here they are an error at the call.

func (*BoundsError) Error

func (e *BoundsError) Error() string

type Buffer

type Buffer struct {
	// contains filtered or unexported fields
}

Buffer is a GPUBuffer.

func (*Buffer) Destroy added in v0.3.0

func (b *Buffer) Destroy()

Destroy releases the buffer remotely and refunds its quota once.

func (*Buffer) MapAsync added in v0.3.0

func (b *Buffer) MapAsync(ctx context.Context, mode MapMode, offset, size uint64) error

MapAsync maps [offset, offset+size) of a MAP_READ buffer for reading (size 0: to the end), with GPUBuffer.mapAsync's rules: the buffer must be unmapped, the offset a multiple of 8, the size a multiple of 4, inside the buffer. The range is read from the host by a one-command submit that returns the bytes (Recorder.ReadBuffer), so the sink must be a ReadSink; ReadMapped then copies from them and Unmap releases them. A remote device cannot map for writing (use Queue.WriteBuffer).

func (*Buffer) ReadMapped added in v0.7.0

func (b *Buffer) ReadMapped(offset uint64, dst []byte) error

ReadMapped copies len(dst) bytes of the mapped range, starting at the buffer offset, into dst.

func (*Buffer) Size

func (b *Buffer) Size() uint64

Size is the buffer's size in bytes.

func (*Buffer) Unmap added in v0.7.0

func (b *Buffer) Unmap() error

Unmap releases a mapped range; on an unmapped buffer it does nothing, as GPUBuffer.unmap does.

func (*Buffer) Usage

func (b *Buffer) Usage() BufferUsage

Usage is the buffer's usage flags.

func (*Buffer) WriteMapped added in v0.7.0

func (b *Buffer) WriteMapped(uint64, []byte) error

WriteMapped: a remote device maps for reading only.

type BufferBindingLayout

type BufferBindingLayout struct {
	Type             BufferBindingType
	HasDynamicOffset bool
	MinBindingSize   uint64
}

BufferBindingLayout is a GPUBufferBindingLayout.

type BufferBindingType

type BufferBindingType string

type BufferDescriptor

type BufferDescriptor struct {
	Label            string
	Size             uint64
	Usage            BufferUsage
	MappedAtCreation bool
}

BufferDescriptor is a GPUBufferDescriptor.

type BufferUsage

type BufferUsage uint32

Flag sets, with the values of the IDL's GPUFlagsConstant namespaces.

type CanvasAlphaMode

type CanvasAlphaMode string

type Color

type Color struct{ R, G, B, A float64 }

Color is a GPUColorDict.

type ColorTargetState

type ColorTargetState struct {
	Format    TextureFormat
	Blend     *BlendState
	WriteMask *ColorWrite
}

ColorTargetState is a GPUColorTargetState; a nil WriteMask writes all channels.

type ColorWrite

type ColorWrite uint32

Flag sets, with the values of the IDL's GPUFlagsConstant namespaces.

type CommandBuffer

type CommandBuffer struct {
	// contains filtered or unexported fields
}

CommandBuffer is a GPUCommandBuffer.

func (*CommandBuffer) Label

func (o *CommandBuffer) Label() string

Label returns the label the object was created with.

type CompareFunction

type CompareFunction string

type ComputePassRecorder

type ComputePassRecorder struct {
	// contains filtered or unexported fields
}

ComputePassRecorder records a compute pass's commands.

func (*ComputePassRecorder) DispatchWorkgroups

func (p *ComputePassRecorder) DispatchWorkgroups(x, y, z uint32)

DispatchWorkgroups records dispatchWorkgroups.

func (*ComputePassRecorder) DispatchWorkgroupsIndirect

func (p *ComputePassRecorder) DispatchWorkgroupsIndirect(b *Buffer, offset uint64)

DispatchWorkgroupsIndirect records dispatchWorkgroupsIndirect.

func (*ComputePassRecorder) End

func (p *ComputePassRecorder) End() error

End records end.

func (*ComputePassRecorder) SetBindGroup

func (p *ComputePassRecorder) SetBindGroup(index uint32, g *BindGroup, dynamicOffsets ...uint32)

SetBindGroup records setBindGroup.

func (*ComputePassRecorder) SetPipeline

func (p *ComputePassRecorder) SetPipeline(pl *ComputePipeline)

SetPipeline records setPipeline.

type ComputePipeline

type ComputePipeline struct {
	// contains filtered or unexported fields
}

ComputePipeline is a GPUComputePipeline; Release refunds its quota.

func (*ComputePipeline) Release added in v0.3.0

func (p *ComputePipeline) Release()

Release releases the pipeline remotely and gives its quota back.

type ComputePipelineDescriptor

type ComputePipelineDescriptor struct {
	Label   string
	Layout  *PipelineLayout
	Compute ProgrammableStage
}

ComputePipelineDescriptor is a GPUComputePipelineDescriptor. A nil Layout is "auto".

type CullMode

type CullMode string

type DepthStencilState

type DepthStencilState struct {
	Format              TextureFormat
	DepthWriteEnabled   bool
	DepthCompare        CompareFunction
	StencilFront        StencilFaceState
	StencilBack         StencilFaceState
	StencilReadMask     *uint32
	StencilWriteMask    *uint32
	DepthBias           int32
	DepthBiasSlopeScale float32
	DepthBiasClamp      float32
}

DepthStencilState is a GPUDepthStencilState. DepthWriteEnabled is always sent; nil masks mean the default 0xFFFFFFFF.

type Device

type Device struct {
	// contains filtered or unexported fields
}

Device is a GPUDevice. Its Quota (from DeviceDescriptor) bounds what it may hold.

func NewRemoteDevice added in v0.3.0

func NewRemoteDevice(sink RemoteSink, label string, q *Quota) *Device

NewRemoteDevice returns a Device whose work goes to sink, bounded by q (nil: no quota).

func (*Device) Completed

func (d *Device) Completed() uint64

Completed is the highest submission known to be complete.

func (*Device) CreateBindGroup added in v0.3.0

func (d *Device) CreateBindGroup(desc BindGroupDescriptor) (*BindGroup, error)

CreateBindGroup sends a bind group's creation; buffer ranges are checked against the buffers' sizes first, as in the browser.

func (*Device) CreateBindGroupLayout added in v0.3.0

func (d *Device) CreateBindGroupLayout(desc BindGroupLayoutDescriptor) (*BindGroupLayout, error)

CreateBindGroupLayout sends a bind group layout's creation, checked as in the browser.

func (*Device) CreateBuffer added in v0.3.0

func (d *Device) CreateBuffer(desc BufferDescriptor) (*Buffer, error)

CreateBuffer sends a buffer's creation; its size is charged first.

func (*Device) CreateComputePipeline added in v0.3.0

func (d *Device) CreateComputePipeline(desc ComputePipelineDescriptor) (*ComputePipeline, error)

CreateComputePipeline sends a compute pipeline's creation; it counts against the quota's Pipelines until Release.

func (*Device) CreatePipelineLayout added in v0.3.0

func (d *Device) CreatePipelineLayout(desc PipelineLayoutDescriptor) (*PipelineLayout, error)

CreatePipelineLayout sends a pipeline layout's creation.

func (*Device) CreateRenderPipeline added in v0.3.0

func (d *Device) CreateRenderPipeline(desc RenderPipelineDescriptor) (*RenderPipeline, error)

CreateRenderPipeline sends a render pipeline's creation; it counts against the quota's Pipelines until Release.

func (*Device) CreateSampler added in v0.3.0

func (d *Device) CreateSampler(desc *SamplerDescriptor) (*Sampler, error)

CreateSampler sends a sampler's creation.

func (*Device) CreateShaderModule added in v0.3.0

func (d *Device) CreateShaderModule(desc ShaderModuleDescriptor) (*ShaderModule, error)

CreateShaderModule sends WGSL source, bounded by the quota's ShaderBytes.

func (*Device) CreateTexture added in v0.3.0

func (d *Device) CreateTexture(desc TextureDescriptor) (*Texture, error)

CreateTexture sends a texture's creation; TextureBytes is charged first.

func (*Device) Label

func (o *Device) Label() string

Label returns the label the object was created with.

func (*Device) Limit

func (d *Device) Limit(name string) (uint64, bool)

Limit returns one of the device's limits (e.g. "maxBufferSize") as the browser reported it, and whether it is known.

func (*Device) Lost

func (d *Device) Lost() <-chan struct{}

Lost is closed when the device is lost (destroyed, or by the browser: a GPU reset, a watchdog). LostInfo then says why.

func (*Device) LostInfo

func (d *Device) LostInfo() DeviceLostInfo

LostInfo is why the device was lost; zero while it is not.

func (*Device) NewRecorder

func (d *Device) NewRecorder() *Recorder

NewRecorder returns a Recorder for the device.

func (*Device) Queue added in v0.3.0

func (d *Device) Queue() *Queue

Queue returns the device's queue.

func (*Device) Quota

func (d *Device) Quota() *Quota

Quota returns the device's quota (nil: none).

func (*Device) Submitted

func (d *Device) Submitted() uint64

Submitted is the number of the device's last queue submission (Queue Submit and Recorder.Submit), from 1.

func (*Device) WaitSubmitted added in v0.3.0

func (d *Device) WaitSubmitted(ctx context.Context, seq uint64) error

WaitSubmitted waits until submission seq is complete (a remote device's submits complete when Submit returns).

type DeviceDescriptor

type DeviceDescriptor struct {
	Label            string
	RequiredFeatures []FeatureName
	RequiredLimits   map[string]uint64
	Quota            *Quota
}

DeviceDescriptor is a GPUDeviceDescriptor plus the Quota the device enforces.

type DeviceLostInfo

type DeviceLostInfo struct {
	Reason  string
	Message string
}

DeviceLostInfo says why a device was lost: Reason "destroyed" (Destroy was called) or "unknown".

type ErrorFilter

type ErrorFilter string

type Extent3D

type Extent3D struct{ Width, Height, DepthOrArrayLayers uint32 }

Extent3D is a GPUExtent3DDict. DepthOrArrayLayers 0 means 1.

type FeatureName

type FeatureName string

type FilterMode

type FilterMode string

type FormatInfo

type FormatInfo struct {
	// BlockWidth and BlockHeight are the texel block's size in texels: 1x1
	// for every pixel-based format.
	BlockWidth, BlockHeight uint32
	// CopyBytes is the texel block copy footprint of the format's only
	// copyable aspect, 0 if no aspect can be copied from or to a buffer
	// without naming one (depth24plus, and the combined depth-stencil
	// formats, whose aspects are copied separately).
	CopyBytes uint32
	// MemoryBytes bounds what one texel block costs in GPU memory. The
	// specification calls this informative and gives ranges for some
	// depth-stencil formats; the upper bound is used, so quotas never
	// under-count.
	MemoryBytes uint32
	// Depth and Stencil say which aspects the format has.
	Depth, Stencil bool
	// CopyDst is false for formats whose depth aspect may not be the
	// destination of a texel copy (depth32float and friends).
	CopyDst bool
}

FormatInfo describes a texture format's texel blocks, after the WebGPU specification's texture format capability tables (https://www.w3.org/TR/webgpu/#texture-format-caps).

type FragmentState

type FragmentState struct {
	Module     *ShaderModule
	EntryPoint string
	Constants  map[string]float64
	Targets    []ColorTargetState
}

FragmentState is a GPUFragmentState.

type FrontFace

type FrontFace string

type GPUError

type GPUError struct {
	Kind    string
	Message string
}

GPUError is a WebGPU error reported on the device: by PopErrorScope or to an uncaptured-error handler. Kind is "validation", "out-of-memory" or "internal".

func (*GPUError) Error

func (e *GPUError) Error() string

type IndexFormat

type IndexFormat string

type JSError

type JSError struct {
	Op      string
	Name    string
	Message string
}

JSError is an exception the browser threw synchronously (a TypeError for a malformed descriptor, an OperationError, ...).

func (*JSError) Error

func (e *JSError) Error() string

type LoadOp

type LoadOp string

type MapMode

type MapMode uint32

Flag sets, with the values of the IDL's GPUFlagsConstant namespaces.

type MipmapFilterMode

type MipmapFilterMode string

type MultisampleState

type MultisampleState struct {
	Count                  uint32
	Mask                   uint32
	AlphaToCoverageEnabled bool
}

MultisampleState is a GPUMultisampleState. Zero Count means 1, zero Mask all samples.

type Origin3D

type Origin3D struct{ X, Y, Z uint32 }

Origin3D is a GPUOrigin3DDict.

type PipelineLayout

type PipelineLayout struct {
	// contains filtered or unexported fields
}

PipelineLayout is a GPUPipelineLayout.

func (*PipelineLayout) Label

func (o *PipelineLayout) Label() string

Label returns the label the object was created with.

type PipelineLayoutDescriptor

type PipelineLayoutDescriptor struct {
	Label            string
	BindGroupLayouts []*BindGroupLayout
}

PipelineLayoutDescriptor is a GPUPipelineLayoutDescriptor.

type PowerPreference

type PowerPreference string

type PrimitiveState

type PrimitiveState struct {
	Topology         PrimitiveTopology
	StripIndexFormat IndexFormat
	FrontFace        FrontFace
	CullMode         CullMode
	UnclippedDepth   bool
}

PrimitiveState is a GPUPrimitiveState.

type PrimitiveTopology

type PrimitiveTopology string

type ProgrammableStage

type ProgrammableStage struct {
	Module     *ShaderModule
	EntryPoint string
	Constants  map[string]float64
}

ProgrammableStage is a GPUProgrammableStage.

type Queue

type Queue struct {
	// contains filtered or unexported fields
}

Queue is a GPUQueue.

func (*Queue) Label

func (o *Queue) Label() string

Label returns the label the object was created with.

func (*Queue) WriteBuffer added in v0.3.0

func (q *Queue) WriteBuffer(b *Buffer, offset uint64, data []byte) error

WriteBuffer sends queue.writeBuffer as a one-command submit, checked as in the browser.

func (*Queue) WriteTexture added in v0.3.0

WriteTexture: not carried by a remote device yet.

type Quota

type Quota struct {
	// MemoryBytes bounds buffer and texture bytes alive (texture sizes are
	// computed by the package from the descriptor, mips and samples
	// included). 0 is no limit.
	MemoryBytes int64
	// Pipelines bounds render and compute pipelines alive. 0 is no limit.
	Pipelines int
	// ShaderBytes bounds one WGSL source. 0 is no limit.
	ShaderBytes int
	// ReadBytes bounds the read window of one submit: the bytes its
	// Recorder.ReadBuffer commands may return together. 0 is no limit
	// (wire.MaxReadWindow still bounds it).
	ReadBytes int
	// Features lists the optional features a device may require. Any
	// other required feature is refused, timestamp-query included unless
	// listed.
	Features []FeatureName
	// Limits caps the limits a device may require; a required limit not
	// named here is refused.
	Limits map[string]uint64
	// SurfaceWidth and SurfaceHeight bound a Surface's size. 0 is no
	// limit.
	SurfaceWidth, SurfaceHeight int
	// contains filtered or unexported fields
}

Quota bounds what devices may hold. An embedder that runs untrusted code through this package (the go-wasmcontainers playground does) gives each tenant a Quota and passes it in DeviceDescriptor.Quota; several devices may share one. A nil Quota is no limit.

The package charges a Quota before it calls the browser and refunds on Destroy or Release, so a refused request never reaches WebGPU.

func (*Quota) Usage

func (q *Quota) Usage() (memoryBytes int64, pipelines int)

Usage reports what is charged now.

type QuotaError

type QuotaError struct {
	Resource string // "memory", "pipelines", "shader", "feature", "limit"
	Limit    int64
	Want     int64
	Name     string // the feature or limit, when Resource names one
}

QuotaError reports a request a Quota refused.

func (*QuotaError) Error

func (e *QuotaError) Error() string

type ReadSink added in v0.7.0

type ReadSink interface {
	RemoteSink
	SubmitRead(words []uint32, data []byte, window []byte) error
}

ReadSink is a RemoteSink that also returns read-backs: SubmitRead executes the submit as Submit does and, once its GPU work has completed, fills window (len = the submit's read window) as the stream's ReadBuffer commands say. A remote device whose sink is not a ReadSink refuses a submit that reads.

type Readback added in v0.7.0

type Readback struct {
	// contains filtered or unexported fields
}

Readback is the result of one Recorder.ReadBuffer: its bytes are valid after the Recorder's Submit returned without error.

func (*Readback) Bytes added in v0.7.0

func (rb *Readback) Bytes() ([]byte, error)

Bytes returns the bytes read, owned by the caller. It is ErrNotRead until the submit that carries the read has succeeded, and the recording error if the read was refused.

type Recorder

type Recorder struct {
	// contains filtered or unexported fields
}

Recorder records one submit. Its methods mirror the direct API; like a pass encoder's, they return nothing on the per-draw path: the first refused command is kept, not recorded, and returned by End or Submit. A Recorder is not safe for concurrent use; Reset reuses its memory for the next frame.

func (*Recorder) BeginComputePass

func (r *Recorder) BeginComputePass() *ComputePassRecorder

BeginComputePass records encoder.beginComputePass.

func (*Recorder) BeginRenderPass

func (r *Recorder) BeginRenderPass(desc RenderPassDescriptor) *RenderPassRecorder

BeginRenderPass records encoder.beginRenderPass and returns the pass recorder. Up to 8 color attachments.

func (*Recorder) CopyBufferToBuffer

func (r *Recorder) CopyBufferToBuffer(src *Buffer, srcOffset uint64, dst *Buffer, dstOffset, size uint64)

CopyBufferToBuffer records encoder.copyBufferToBuffer, checked.

func (*Recorder) CopyTextureToTexture added in v0.3.0

func (r *Recorder) CopyTextureToTexture(src, dst TexelCopyTextureInfo, size Extent3D)

CopyTextureToTexture records encoder.copyTextureToTexture. As on the direct path, the browser validates the regions; the textures must not be nil and the aspects must be WebGPU's.

func (*Recorder) Err

func (r *Recorder) Err() error

Err is the first refused command so far.

func (*Recorder) Len

func (r *Recorder) Len() int

Len is the number of words recorded, for tests and metrics.

func (*Recorder) ReadBuffer added in v0.7.0

func (r *Recorder) ReadBuffer(b *Buffer, offset, size uint64) *Readback

ReadBuffer records a read of [offset, offset+size) of b, a MAP_READ buffer, after this submit's GPU work. Record the copy into b before it (CopyBufferToBuffer); the read sees everything the stream does. Submit delivers the bytes to the returned Readback. A refused read is kept as the Recorder's error, as every command's is, and in the Readback.

func (*Recorder) Reset

func (r *Recorder) Reset()

Reset forgets everything recorded, keeping the memory.

func (*Recorder) Submit added in v0.3.0

func (r *Recorder) Submit() (seq uint64, err error)

Submit sends everything recorded as one submit and resets the Recorder. It returns once the sink reports the submit executed; a sink error loses the device.

func (*Recorder) WriteBuffer

func (r *Recorder) WriteBuffer(b *Buffer, offset uint64, data []byte)

WriteBuffer records queue.writeBuffer: the bytes are copied into the recorder now and written, in order, when Submit replays the stream. Checked like Queue.WriteBuffer.

func (*Recorder) WriteTexture added in v0.4.0

func (r *Recorder) WriteTexture(dst TexelCopyTextureInfo, data []byte, layout TexelCopyBufferLayout, size Extent3D)

WriteTexture records queue.writeTexture: the bytes are copied into the recorder now and written, in order, when Submit replays the stream, in the same single call as the passes. Checked like Queue.WriteTexture (region inside the mip level, layout inside data).

type RemoteSink added in v0.3.0

type RemoteSink interface {
	// Create makes object id of kind from a wire descriptor
	// (EncodeDescriptor's bytes).
	Create(id uint32, kind wire.Kind, desc []byte) error
	// Destroy releases object id.
	Destroy(id uint32) error
	// Submit executes one Recorder submit and returns once it has
	// executed (a fenced virtio submission), or with the error that lost
	// the remote device.
	Submit(words []uint32, data []byte) error
}

RemoteSink carries the work of a remote device (NewRemoteDevice, built outside the browser) to where a real device runs it — for example to a virtio-gpu host through go-virtio/gpu's webgpu-batch context.

Object ids are replay ids (ReplayID): the ids streams and descriptors name objects by. The receiver translates them to its own objects (wire.RemapDescriptor, wire.Remap).

type RenderBundle

type RenderBundle struct {
	// contains filtered or unexported fields
}

RenderBundle is a GPURenderBundle.

func (*RenderBundle) Label

func (o *RenderBundle) Label() string

Label returns the label the object was created with.

type RenderBundleEncoderDescriptor

type RenderBundleEncoderDescriptor struct {
	Label              string
	ColorFormats       []TextureFormat
	DepthStencilFormat TextureFormat
	SampleCount        uint32
	DepthReadOnly      bool
	StencilReadOnly    bool
}

RenderBundleEncoderDescriptor is a GPURenderBundleEncoderDescriptor.

type RenderPassColorAttachment

type RenderPassColorAttachment struct {
	View          *TextureView
	DepthSlice    *uint32
	ResolveTarget *TextureView
	ClearValue    Color
	LoadOp        LoadOp
	StoreOp       StoreOp
}

RenderPassColorAttachment is a GPURenderPassColorAttachment.

type RenderPassDepthStencilAttachment

type RenderPassDepthStencilAttachment struct {
	View              *TextureView
	DepthClearValue   float32
	DepthLoadOp       LoadOp
	DepthStoreOp      StoreOp
	DepthReadOnly     bool
	StencilClearValue uint32
	StencilLoadOp     LoadOp
	StencilStoreOp    StoreOp
	StencilReadOnly   bool
}

RenderPassDepthStencilAttachment is a GPURenderPassDepthStencilAttachment. Load and store ops left empty are omitted (required by the browser for the aspects the format has, unless read-only).

type RenderPassDescriptor

type RenderPassDescriptor struct {
	Label                  string
	ColorAttachments       []*RenderPassColorAttachment
	DepthStencilAttachment *RenderPassDepthStencilAttachment
	MaxDrawCount           uint64
}

RenderPassDescriptor is a GPURenderPassDescriptor. A nil entry in ColorAttachments is an unused slot.

type RenderPassRecorder

type RenderPassRecorder struct {
	// contains filtered or unexported fields
}

RenderPassRecorder records a render pass's commands.

func (*RenderPassRecorder) Draw

func (p *RenderPassRecorder) Draw(vertexCount, instanceCount, firstVertex, firstInstance uint32)

Draw records draw.

func (*RenderPassRecorder) DrawIndexed

func (p *RenderPassRecorder) DrawIndexed(indexCount, instanceCount, firstIndex uint32, baseVertex int32, firstInstance uint32)

DrawIndexed records drawIndexed.

func (*RenderPassRecorder) DrawIndexedIndirect

func (p *RenderPassRecorder) DrawIndexedIndirect(b *Buffer, offset uint64)

DrawIndexedIndirect records drawIndexedIndirect.

func (*RenderPassRecorder) DrawIndirect

func (p *RenderPassRecorder) DrawIndirect(b *Buffer, offset uint64)

DrawIndirect records drawIndirect; the record must lie in the buffer.

func (*RenderPassRecorder) End

func (p *RenderPassRecorder) End() error

End records end. It returns the first refused command so far.

func (*RenderPassRecorder) ExecuteBundles

func (p *RenderPassRecorder) ExecuteBundles(bundles ...*RenderBundle)

ExecuteBundles records executeBundles.

func (*RenderPassRecorder) SetBindGroup

func (p *RenderPassRecorder) SetBindGroup(index uint32, g *BindGroup, dynamicOffsets ...uint32)

SetBindGroup records setBindGroup, dynamic offsets included (replayed through the Uint32Array overload, without an array per call).

func (*RenderPassRecorder) SetBlendConstant

func (p *RenderPassRecorder) SetBlendConstant(c Color)

SetBlendConstant records setBlendConstant (as float32).

func (*RenderPassRecorder) SetIndexBuffer

func (p *RenderPassRecorder) SetIndexBuffer(b *Buffer, format IndexFormat, offset, size uint64)

SetIndexBuffer records setIndexBuffer; size 0 binds to the end.

func (*RenderPassRecorder) SetPipeline

func (p *RenderPassRecorder) SetPipeline(pl *RenderPipeline)

SetPipeline records setPipeline.

func (*RenderPassRecorder) SetScissorRect

func (p *RenderPassRecorder) SetScissorRect(x, y, w, h uint32)

SetScissorRect records setScissorRect.

func (*RenderPassRecorder) SetStencilReference

func (p *RenderPassRecorder) SetStencilReference(ref uint32)

SetStencilReference records setStencilReference.

func (*RenderPassRecorder) SetVertexBuffer

func (p *RenderPassRecorder) SetVertexBuffer(slot uint32, b *Buffer, offset, size uint64)

SetVertexBuffer records setVertexBuffer; size 0 binds to the end. Checked like the direct path.

func (*RenderPassRecorder) SetViewport

func (p *RenderPassRecorder) SetViewport(x, y, w, h, minDepth, maxDepth float32)

SetViewport records setViewport.

type RenderPipeline

type RenderPipeline struct {
	// contains filtered or unexported fields
}

RenderPipeline is a GPURenderPipeline; Release refunds its quota.

func (*RenderPipeline) Release added in v0.3.0

func (p *RenderPipeline) Release()

Release releases the pipeline remotely and gives its quota back.

type RenderPipelineDescriptor

type RenderPipelineDescriptor struct {
	Label        string
	Layout       *PipelineLayout
	Vertex       VertexState
	Primitive    PrimitiveState
	DepthStencil *DepthStencilState
	Multisample  MultisampleState
	Fragment     *FragmentState
}

RenderPipelineDescriptor is a GPURenderPipelineDescriptor. A nil Layout is "auto".

type RequestAdapterOptions

type RequestAdapterOptions struct {
	PowerPreference      PowerPreference
	ForceFallbackAdapter bool
	AllowFallback        bool
}

RequestAdapterOptions is a GPURequestAdapterOptions. AllowFallback is ours: without it, a fallback (software) adapter is refused with ErrFallbackAdapter.

type Resolver added in v0.3.0

type Resolver func(id uint32) (any, error)

Resolver returns the receiver's object for a reference id (a *Buffer, *Texture, *TextureView, *Sampler, *ShaderModule, *BindGroupLayout or *PipelineLayout). DecodeDescriptor checks the object's type.

type Sampler

type Sampler struct {
	// contains filtered or unexported fields
}

Sampler is a GPUSampler.

func (*Sampler) Label

func (o *Sampler) Label() string

Label returns the label the object was created with.

type SamplerBindingLayout

type SamplerBindingLayout struct{ Type SamplerBindingType }

SamplerBindingLayout is a GPUSamplerBindingLayout.

type SamplerBindingType

type SamplerBindingType string

type SamplerDescriptor

type SamplerDescriptor struct {
	Label                                    string
	AddressModeU, AddressModeV, AddressModeW AddressMode
	MagFilter, MinFilter                     FilterMode
	MipmapFilter                             MipmapFilterMode
	LodMinClamp, LodMaxClamp                 float32
	Compare                                  CompareFunction
	MaxAnisotropy                            uint16
}

SamplerDescriptor is a GPUSamplerDescriptor. LodMaxClamp 0 means the default, 32.

type ShaderModule

type ShaderModule struct {
	// contains filtered or unexported fields
}

ShaderModule is a GPUShaderModule.

func (*ShaderModule) Label

func (o *ShaderModule) Label() string

Label returns the label the object was created with.

type ShaderModuleDescriptor

type ShaderModuleDescriptor struct {
	Label string
	Code  string
}

ShaderModuleDescriptor is a GPUShaderModuleDescriptor (WGSL source).

type ShaderStage

type ShaderStage uint32

Flag sets, with the values of the IDL's GPUFlagsConstant namespaces.

type StencilFaceState

type StencilFaceState struct {
	Compare                     CompareFunction
	FailOp, DepthFailOp, PassOp StencilOperation
}

StencilFaceState is a GPUStencilFaceState.

type StencilOperation

type StencilOperation string

type StorageTextureAccess

type StorageTextureAccess string

type StorageTextureBindingLayout

type StorageTextureBindingLayout struct {
	Access        StorageTextureAccess
	Format        TextureFormat
	ViewDimension TextureViewDimension
}

StorageTextureBindingLayout is a GPUStorageTextureBindingLayout.

type StoreOp

type StoreOp string

type SurfaceDescriptor

type SurfaceDescriptor struct {
	Width, Height int
	// Format is the canvas textures' format; empty is the browser's
	// preferred canvas format.
	Format TextureFormat
	// Usage of the canvas textures; zero is RENDER_ATTACHMENT.
	Usage TextureUsage
	// AlphaMode; empty is "opaque".
	AlphaMode CanvasAlphaMode
}

SurfaceDescriptor configures a Surface: an OffscreenCanvas with a WebGPU context (GPUCanvasConfiguration, https://www.w3.org/TR/webgpu/#canvas-configuration).

type TexelCopyBufferInfo

type TexelCopyBufferInfo struct {
	Buffer *Buffer
	Layout TexelCopyBufferLayout
}

TexelCopyBufferInfo is a GPUTexelCopyBufferInfo.

type TexelCopyBufferLayout

type TexelCopyBufferLayout struct {
	Offset       uint64
	BytesPerRow  uint32
	RowsPerImage uint32
}

TexelCopyBufferLayout is a GPUTexelCopyBufferLayout. Zero BytesPerRow and RowsPerImage are "not specified".

type TexelCopyTextureInfo

type TexelCopyTextureInfo struct {
	Texture  *Texture
	MipLevel uint32
	Origin   Origin3D
	Aspect   TextureAspect
}

TexelCopyTextureInfo is a GPUTexelCopyTextureInfo.

type Texture

type Texture struct {
	// contains filtered or unexported fields
}

Texture is a GPUTexture.

func (*Texture) CreateView added in v0.3.0

func (t *Texture) CreateView(desc *TextureViewDescriptor) (*TextureView, error)

CreateView sends a view's creation; nil desc is the default view.

func (*Texture) DepthOrArrayLayers

func (t *Texture) DepthOrArrayLayers() uint32

func (*Texture) Descriptor

func (t *Texture) Descriptor() TextureDescriptor

Descriptor returns the texture's descriptor, defaults filled in.

func (*Texture) Destroy added in v0.3.0

func (t *Texture) Destroy()

Destroy releases the texture remotely and refunds its quota once.

func (*Texture) Format

func (t *Texture) Format() TextureFormat

func (*Texture) Height

func (t *Texture) Height() uint32

func (*Texture) Width

func (t *Texture) Width() uint32

Width, Height, DepthOrArrayLayers and Format describe the texture.

type TextureAspect

type TextureAspect string

type TextureBindingLayout

type TextureBindingLayout struct {
	SampleType    TextureSampleType
	ViewDimension TextureViewDimension
	Multisampled  bool
}

TextureBindingLayout is a GPUTextureBindingLayout.

type TextureDescriptor

type TextureDescriptor struct {
	Label         string
	Size          Extent3D
	MipLevelCount uint32
	SampleCount   uint32
	Dimension     TextureDimension
	Format        TextureFormat
	Usage         TextureUsage
	ViewFormats   []TextureFormat
}

TextureDescriptor is a GPUTextureDescriptor. Zero MipLevelCount and SampleCount mean 1, zero Dimension "2d".

type TextureDimension

type TextureDimension string

type TextureFormat

type TextureFormat string

func (TextureFormat) Info

func (f TextureFormat) Info() (FormatInfo, error)

Info returns what the package knows of a format. An unknown format is an error: sizes are never guessed, since quotas and copy bounds depend on them.

type TextureSampleType

type TextureSampleType string

type TextureUsage

type TextureUsage uint32

Flag sets, with the values of the IDL's GPUFlagsConstant namespaces.

type TextureView

type TextureView struct {
	// contains filtered or unexported fields
}

TextureView is a GPUTextureView.

func (*TextureView) Label

func (o *TextureView) Label() string

Label returns the label the object was created with.

func (*TextureView) Texture

func (v *TextureView) Texture() *Texture

Texture returns the viewed texture.

type TextureViewCreation added in v0.3.0

type TextureViewCreation struct {
	Texture    *Texture
	Descriptor *TextureViewDescriptor
}

TextureViewCreation is the descriptor of a texture view: the texture and Texture.CreateView's descriptor (nil: the default view).

type TextureViewDescriptor

type TextureViewDescriptor struct {
	Label           string
	Format          TextureFormat
	Dimension       TextureViewDimension
	Aspect          TextureAspect
	BaseMipLevel    uint32
	MipLevelCount   uint32
	BaseArrayLayer  uint32
	ArrayLayerCount uint32
}

TextureViewDescriptor is a GPUTextureViewDescriptor.

type TextureViewDimension

type TextureViewDimension string

type VertexAttribute

type VertexAttribute struct {
	Format         VertexFormat
	Offset         uint64
	ShaderLocation uint32
}

VertexAttribute is a GPUVertexAttribute.

type VertexBufferLayout

type VertexBufferLayout struct {
	ArrayStride uint64
	StepMode    VertexStepMode
	Attributes  []VertexAttribute
}

VertexBufferLayout is a GPUVertexBufferLayout.

type VertexFormat

type VertexFormat string

type VertexState

type VertexState struct {
	Module     *ShaderModule
	EntryPoint string
	Constants  map[string]float64
	Buffers    []VertexBufferLayout
}

VertexState is a GPUVertexState.

type VertexStepMode

type VertexStepMode string

Directories

Path Synopsis
Package atlas packs rectangles into a texture atlas: the placement half of "many small images in one texture" (textures, lightmaps, glyphs, sprites), which a WebGPU program does to bind one texture instead of hundreds.
Package atlas packs rectangles into a texture atlas: the placement half of "many small images in one texture" (textures, lightmaps, glyphs, sprites), which a WebGPU program does to bind one texture instead of hundreds.
Package batch is the host side of a batched GPU command stream, without a transport: the table of a guest's object ids, the creation and destruction of its objects, the replay of its streams and, for streams that read back (wire.ReadBuffer), the bounded read window.
Package batch is the host side of a batched GPU command stream, without a transport: the table of a guest's object ids, the creation and destruction of its objects, the replay of its streams and, for streams that read back (wire.ReadBuffer), the bounded read window.
internal
Package timeline is a monotonic synchronisation timeline: work is numbered 1, 2, 3, ...
Package timeline is a monotonic synchronisation timeline: work is numbered 1, 2, 3, ...
Package wire is the format of the batched command stream a webgpu.Recorder writes and replay.js executes: opcodes, argument layout, and the Go reader that mirrors replay.js.
Package wire is the format of the batched command stream a webgpu.Recorder writes and replay.js executes: opcodes, argument layout, and the Go reader that mirrors replay.js.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL