Documentation
¶
Overview ¶
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.
It is portable (no GOOS constraint) so that a stream can be carried outside the browser that recorded it — for example from a virtual machine's guest to a host over a virtio-gpu context — and checked and remapped there by the one implementation of the format, instead of a copy. The Recorder (package webgpu) is the only writer; replay.js and Decode are the readers, and the package tests keep them in agreement.
A stream is a []uint32 of commands plus a data []byte that writeBuffer commands point into. Object arguments are ids: indices of a table the replayer holds (replay.js's object table, or a remote host's).
Index ¶
- Constants
- Variables
- func AppendDescriptor(dst []byte, refs []uint32, body []byte) []byte
- func CheckRanges(cmds []Cmd, size func(id uint32) (uint64, bool), maxWorkgroups uint32) error
- func Remap(w []uint32, ndata uint32, f func(uint32) (uint32, bool)) error
- func RemapDescriptor(b []byte, f func(uint32) (uint32, bool)) error
- func SplitDescriptor(b []byte) (refs []uint32, body []byte, err error)
- type Cmd
- type Kind
- type Op
- type Read
Constants ¶
const ( MaxColorAttachments = 8 MaxDynamicOffsets = 1 << 16 MaxBundles = 1 << 16 )
Limits the readers enforce on counts inside one command.
const DefaultMaxWorkgroups = 65535
DefaultMaxWorkgroups is WebGPU's default maxComputeWorkgroupsPerDimension, the dispatch bound of a device that was not asked for a raised limit.
const MaxReadWindow = 64 << 20
MaxReadWindow bounds the read window of one submit (ReadBuffer's windowOffset + size), 64 MiB. A host grants a smaller one.
const MaxRefs = 4096
MaxRefs bounds the object references of one descriptor (a bind group: its layout and one per entry; WebGPU's maxBindingsPerBindGroup default is 1000).
const StreamVersion = 4
StreamVersion is the version of this format. It changes whenever an opcode's layout changes, so that a remote host and its guests can check they speak the same stream.
2 added CopyTextureToTexture. 3 added WriteTexture. 4 added ReadBuffer.
Variables ¶
var ErrRange = errors.New("replay: range refused")
ErrRange is wrapped by every CheckRanges refusal.
Functions ¶
func AppendDescriptor ¶ added in v0.3.0
AppendDescriptor appends a descriptor to dst.
func CheckRanges ¶ added in v0.8.0
CheckRanges checks, before any replay, what Decode does not know: the buffer sizes. WriteBuffer and CopyBufferToBuffer ranges must lie inside their buffers, an indirect dispatch or draw must find its arguments inside the buffer, and a Dispatch may not exceed maxWorkgroups per dimension (0 is DefaultMaxWorkgroups). size returns the byte size of the buffer a replayer id names, and false for an id that is not a buffer. cmds are the commands of a stream already checked by Decode or Remap, in the replayer's ids. WebGPU validates the same rules later and loses the device; a host refuses them first, as a Go error.
func Remap ¶
Remap rewrites, in place, every object id of a stream through f, which returns the replacement and whether the id is valid. Id 0 where the format allows "none" is left alone and not passed to f. Remap checks the stream exactly as Decode does; on error the words are partly rewritten and must be discarded.
A transport uses it to translate ids from the namespace of the program that recorded the stream to the table of the replayer: an id f does not know is an error, so a stream can only name objects f grants.
func RemapDescriptor ¶ added in v0.3.0
RemapDescriptor rewrites, in place, every nonzero reference of a descriptor through f, and refuses any reference f does not grant: a descriptor can only name objects the transport allows. 0 (an optional reference left out) stays 0.
Types ¶
type Cmd ¶
Cmd is one decoded command; Args aliases the stream.
type Kind ¶ added in v0.3.0
type Kind uint32
Kind is the kind of object a creation descriptor makes.
type Op ¶
type Op uint32
Op is a command's opcode, the first word of a command.
const ( SetPipeline Op = 1 // id SetBindGroup Op = 2 // index id n offsets[n] (id 0: unbind) Draw Op = 3 // vertexCount instanceCount firstVertex firstInstance DrawIndexed Op = 4 // indexCount instanceCount firstIndex baseVertex(int32) firstInstance SetVertexBuffer Op = 5 // slot id offset(2) size(2) SetIndexBuffer Op = 6 // id format offset(2) size(2) SetViewport Op = 7 // x y w h minDepth maxDepth (float32 bits) SetScissorRect Op = 8 // x y w h SetBlendConstant Op = 9 // r g b a (float32 bits) SetStencilReference Op = 10 // ref ExecuteBundles Op = 11 // n ids[n] DrawIndirect Op = 12 // id offset(2) DrawIndexedIndirect Op = 13 // id offset(2) BeginRenderPass Op = 20 // nColors, 8 words per color, depth flag, 9 depth words if 1 EndPass Op = 21 BeginComputePass Op = 22 Dispatch Op = 23 // x y z DispatchIndirect Op = 24 // id offset(2) WriteBuffer Op = 30 // id offset(2) dataOffset length CopyBufferToBuffer Op = 31 // src srcOffset(2) dst dstOffset(2) size(2) // srcTexture mip x y z aspect, dstTexture mip x y z aspect, width // height depthOrArrayLayers. Aspect: 0 default, 1 all, 2 stencil-only, // 3 depth-only. CopyTextureToTexture Op = 32 // texture mip x y z aspect dataOffset dataLength layoutOffset(2) // bytesPerRow rowsPerImage width height depthOrArrayLayers. The bytes // are data[dataOffset, dataOffset+dataLength); layoutOffset is // relative to dataOffset (queue.writeTexture's dataLayout.offset). // Aspect as in CopyTextureToTexture. WriteTexture Op = 33 // id offset(2) size windowOffset. Read-back (GPUBuffer.mapAsync with // MAP_READ, then getMappedRange and unmap): once the stream's GPU work // has completed, the bytes [offset, offset+size) of buffer id are // copied into [windowOffset, windowOffset+size) of the submit's read // window, a byte range the caller of the replay owns. The buffer needs // MAP_READ; offset is a multiple of 8, size a nonzero multiple of 4 // (the mapAsync rules of the WebGPU specification). replay.js ignores // the command: a host performs it after the replay, in stream order. ReadBuffer Op = 34 Submit Op = 40 )
Opcodes; after each, the words that follow it. (2) is a uint64 as low, high words.
type Read ¶ added in v0.7.0
type Read struct {
ID uint32 // the buffer (the replayer's id after Remap)
Offset uint64 // into the buffer, a multiple of 8
Size uint32 // a nonzero multiple of 4
WindowOffset uint32 // into the read window
}
Read is a decoded ReadBuffer command.
func RemapReads ¶ added in v0.7.0
RemapReads is Remap that also returns the stream's ReadBuffer commands, in order, with their ids translated. A host checks them against its buffers' sizes and usage, and its window, before it replays anything.