luv

Workshop wiki

gpu.lisp

hal/gpu.lisp

system luv · 161 definitions · on GitHub

Let's define something roughly like a WebGPU style API.

Then we can implement it for our Vulkan bindings.

Later we can implement it for Metal, etc.

This API itself is agnostic of presenting, swapchains, etc.

The base classes omit parent pointer slots. We might, like e.g. McCLIM, also define STANDARD-GPU-QUEUE and so on.

in-package#:luv
define-conditiongpu-error
error
operation:initarg:operation:initformnil:readergpu-error-operation
:documentation

Base condition for errors exposed by the luv GPU API.

define-conditiongpu-request-error
descriptor:initarg:descriptor:readergpu-request-error-descriptor
reason:initarg:reason:readergpu-request-error-reason
details:initarg:details:initformnil:readergpu-request-error-details
:report
lambda
conditionstream
case
gpu-request-error-reasoncondition
:invalid-descriptor
formatstream"Expected a GPU descriptor, got ~S."
gpu-request-error-detailscondition
:unsupported-features
formatstream"Required GPU features are not implemented yet: ~S"
gpu-request-error-detailscondition
:unsupported-limits
formatstream"Required GPU limits are not implemented yet: ~S"
gpu-request-error-detailscondition
otherwise
formatstream"GPU request failed~@[ during ~S~]: ~S~@[ (~S)~]"
gpu-error-operationcondition
gpu-request-error-reasoncondition
gpu-request-error-detailscondition
define-conditiongpu-object-error
object:initarg:object:readergpu-object-error-object
:documentation

Base condition for an operation rejected by a GPU object.

define-conditiongpu-object-destroyed-error
:report
lambda
conditionstream
formatstream"~S has already been destroyed~@[ during ~S~]."
gpu-object-error-objectcondition
gpu-error-operationcondition
define-conditiongpu-invalid-state-error
state:initarg:state:readergpu-invalid-state-error-state
expected-state:initarg:expected-state:readergpu-invalid-state-error-expected-state
:report
lambda
conditionstream
formatstream"Cannot perform ~S on ~S in state ~S; expected ~S."
gpu-error-operationcondition
gpu-object-error-objectcondition
gpu-invalid-state-error-statecondition
gpu-invalid-state-error-expected-statecondition
define-conditiongpu-device-mismatch-error
expected-device:initarg:expected-device:readergpu-device-mismatch-error-expected-device
actual-device:initarg:actual-device:readergpu-device-mismatch-error-actual-device
:report
lambda
conditionstream
formatstream"~S belongs to ~S, not the device ~S required by ~S."
gpu-object-error-objectcondition
gpu-device-mismatch-error-actual-devicecondition
gpu-device-mismatch-error-expected-devicecondition
gpu-error-operationcondition
define-conditiongpu-usage-error
required-usage:initarg:required-usage:readergpu-usage-error-required-usage
actual-usage:initarg:actual-usage:readergpu-usage-error-actual-usage
:report
lambda
conditionstream
formatstream"~S requires usage ~S for ~S, but was created with ~S."
gpu-object-error-objectcondition
gpu-usage-error-required-usagecondition
gpu-error-operationcondition
gpu-usage-error-actual-usagecondition
define-conditiongpu-resource-leaked
warning
resource-class:initarg:resource-class:readergpu-resource-leaked-class
label:initarg:label:initformnil:readergpu-resource-leaked-label
:report
lambda
conditionstream
formatstream

Leaked GPU A~@[ labeled ~S]: it was reclaimed by the ~ garbage collector instead of being destroyed explicitly.

gpu-resource-leaked-classcondition
gpu-resource-leaked-labelcondition
:documentation

Signaled from the finalizer when a live GPU object is collected without destroy. The native resources are still reclaimed, but explicit destruction is the expected discipline.

defstructgpu-retirement-entry

One native teardown durably owned by a GPU queue.

READY-AFTER is the queue completion frontier which makes TEARDOWN safe. RESOURCE is retained for diagnosis and, for current backends, also supplies the native handles used by TEARDOWN.

resource
ready-after0:type
unsigned-byte64
teardown
attempts0:typefixnum
last-error
defstruct
gpu-native-retirement-failure
:constructormake-gpu-native-retirement-failure
&keyresourcecauseattempts
resourcenil:read-onlyt
causenil:read-onlyt
attempts0:typefixnum:read-onlyt
define-conditiongpu-native-retirement-condition
operation:initarg:operation:readergpu-native-retirement-operation
failures:initarg:failures:readergpu-native-retirement-failures
:documentation

Structured evidence that native GPU ownership could not be retired.

define-conditiongpu-native-retirement-warning
:report
lambda
conditionstream
let
failures
gpu-native-retirement-failurescondition
formatstream

D native GPU retirement:P failed during ~S; ~ the retirement ledger retained the failed resource and its FIFO successors ~ for retry.

lengthfailures
gpu-native-retirement-operationcondition
define-conditiongpu-native-retirement-error
:report
lambda
conditionstream
let*
failures
gpu-native-retirement-failurescondition
first
firstfailures
formatstream"Cannot complete ~S: ~D native GPU retirement~:P remain"
gpu-native-retirement-operationcondition
lengthfailures
whenfirst
formatstream" (first failure for ~S: ~A)"
gpu-native-retirement-failure-resourcefirst
gpu-native-retirement-failure-causefirst
write-char#\.stream
defstructgpu-retirement-ledger

A queue-owned list of native teardowns, including failed attempts.

entries'
:typelist
tail
active-batch'
:typelist
defvar*gpu-retirement-ledger-custodians*
make-hash-table:test#'eq
"Process roots for queues with native retirement or submitted work."
defvar*gpu-retirement-ledger-custodian-lock*
sb-thread:make-mutex:name"luv GPU retirement custodians"
"Serializes durable queue roots without entering backend queue locks."
defvar*gpu-retirement-custodian-service-wake*
sb-thread:make-waitqueue:name"luv GPU retirement custodian service"
"Wakes the lazy process-wide retirement custodian service thread."
defvar*gpu-retirement-custodian-service-thread*nil"The lazy process-wide retirement custodian service thread, or NIL."
defvar*gpu-retirement-custodian-service-start-error*nil"Newest best-effort worker start error; queue custody remains unaffected."
defvar*gpu-retirement-custodian-process-exiting-p*nil"True once SBCL has begun orderly process shutdown."
defvar*gpu-retirement-custodian-service-enabled-p*t"Whether retaining a queue custodian starts eventual background service."
defvar*gpu-retirement-custodian-service-failures*
make-hash-table:test#'eq
"Consecutive service failures per custodian, for bounded diagnostics."
defunnote-gpu-retirement-custodian-process-exit

SBCL terminates and joins ephemeral threads while holding its private thread-creation lock. Tell the worker's unwind cleanup not to fight that orderly shutdown by trying to restart itself under the same lock.

defgenericservice-gpu-retirement-custodian
custodian
:documentation

Perform one safe eventual-retirement service pass for custodian.

Backend methods revalidate native liveness while holding their queue lock and return true when the pass made progress. They must never acquire a queue lock while the process-wide custodian registry lock is held.

defmethodservice-gpu-retirement-custodian
custodiant
declare
ignorecustodian
nil
defungpu-retirement-custodian-snapshot

Return a strong snapshot without retaining the registry lock.

sb-thread:with-mutex
loopforcustodianbeingthehash-valuesof*gpu-retirement-ledger-custodians*collectcustodian
defunnote-gpu-retirement-custodian-service-failure
custodiancause

Record cause and warn only on the first consecutive service failure.

let
attempts
sb-thread:with-mutex

A device teardown can prove quiescence after SERVICE releases its queue lock but before this handler runs. Do not resurrect the custodian through the diagnostic table in that race.

when
loopforregisteredbeingthehash-valuesof*gpu-retirement-ledger-custodians*thereis
eqregisteredcustodian
when
eqlattempts1

A hostile warning handler must not kill the service worker. The queue remains rooted before, during, and after this diagnostic.

handler-case
warn'gpu-native-retirement-warning:operation:service-gpu-retirement-custodian:failures
list
make-gpu-native-retirement-failure:resourcecustodian:causecause:attemptsattempts
serious-condition
nil
nil
defunservice-gpu-retirement-custodians-once

Service one registry snapshot without holding the registry lock.

Returns true when any backend reports progress. Errors are diagnosed once per consecutive failure and never prevent later custodians from being serviced.

let
progress-pnil
dolist
handler-case
let
whenprogress
setfprogress-pt
serious-condition
cause
defunspawn-gpu-retirement-custodian-service-thread

This process custodian is runtime infrastructure, like SBCL's finalizer and timer workers: durable ownership lives in the registry, while the worker must not keep a noninteractive Lisp alive after its main thread exits (especially when a failed test deliberately leaves work pending). MAKE-SYSTEM-THREAD is private because callers must serialize it with SBCL's thread-creation mutex; START-THREAD intentionally omits that lock for ephemeral threads under the assumption that it is already held.

sb-thread::call-with-system-mutex
lambda
sb-thread::make-system-thread"luv GPU retirement service"#'run-gpu-retirement-custodian-servicenilnil
sb-thread::*make-thread-lock*
defuntry-start-gpu-retirement-custodian-service-locked

Best-effort worker start which cannot revoke already published custody.

defunrun-gpu-retirement-custodian-service

Eventually service rooted queues, exiting atomically when none remain.

defunretain-gpu-retirement-ledger-custodian
ledgercustodian

Root custodian until its ledger and backend submissions are quiescent.

sb-thread:with-mutex
setfcustodian

The hash publication is the ownership transfer. Thread creation and wakeup are liveness accelerators and must not leave the public wrapper valid after its teardown was already enqueued.

handler-case
sb-thread:condition-notify*gpu-retirement-custodian-service-wake*
serious-condition
cause
ledger
defunrelease-gpu-retirement-ledger-custodian
ledgercustodian

Drop custodian's root after backend quiescence was proved under its lock.

ledger
defunenqueue-gpu-retirement
ledgerresourceready-afterteardown

Transfer resource's native teardown to ledger and return its entry.

The caller holds its queue lock. This append must happen before the public wrapper is marked destroyed or its leak finalizer is cancelled.

check-typeready-after
unsigned-byte64
check-typeteardownfunction
let*
entry
make-gpu-retirement-entry:resourceresource:ready-afterready-after:teardownteardown
cell
listentry
if
gpu-retirement-ledger-tailledger
setf
cdr
gpu-retirement-ledger-tailledger
cell
gpu-retirement-ledger-tailledger
cell
setf
gpu-retirement-ledger-entriesledger
cell
gpu-retirement-ledger-tailledger
cell
entry
defuntransfer-gpu-retirement
ledgerresourceready-afterteardowninvalidate&optionalcustodian

Durably enqueue native ownership, then logically invalidate resource.

invalidate is called only after ledger owns the complete teardown. Queue implementations call this while holding the lock which also guards ledger.

let
entry
enqueue-gpu-retirementledgerresourceready-afterteardown
whencustodian
funcallinvalidate
entry
defungpu-retirement-failure-for-entry
entry
make-gpu-native-retirement-failure:resource
gpu-retirement-entry-resourceentry
:cause
gpu-retirement-entry-last-errorentry
:attempts
gpu-retirement-entry-attemptsentry
defungpu-retirement-ledger-failures
ledger

Describe every currently retained failed entry in ledger.

loopforentryin
gpu-retirement-ledger-entriesledger
when
gpu-retirement-entry-last-errorentry
collect
defunmaintain-gpu-retirement-ledger
ledgercompleted-frontier&key
operation:maintain-queue

Attempt the eligible FIFO prefix in ledger at completed-frontier.

Only a successful eligible prefix leaves the ledger. The first ineligible or failed entry is a FIFO barrier: it and the entire unattempted suffix remain ahead of ownership transferred recursively by teardown callbacks.

check-typecompleted-frontier
unsigned-byte64

A teardown callback can recursively destroy another resource and enter queue maintenance through the same recursive backend lock. The outer batch owns the ordering frontier; leave newly queued work for its next pass rather than letting recursive maintenance overtake it.

when
gpu-retirement-ledger-active-batchledger
return-frommaintain-gpu-retirement-ledger
valuesledgernil
let
pending
gpu-retirement-ledger-entriesledger
pending-tail
gpu-retirement-ledger-tailledger
retained-headnil
merged-pnil
failures'

Teardown callbacks run under a backend's recursive queue lock and may themselves destroy another resource. Detach this maintenance batch so such transfers enter a fresh queue and cannot be visited or overwritten by the traversal below.

setf
gpu-retirement-ledger-entriesledger
nil
gpu-retirement-ledger-tailledger
nil
gpu-retirement-ledger-active-batchledger
pending
labels
merge-retained-batch

The blocked suffix retains its existing cons cells and original tail, then precedes callback-enqueued ownership.

whenretained-head
setf
cdrpending-tail
gpu-retirement-ledger-entriesledger
gpu-retirement-ledger-entriesledger
retained-head
gpu-retirement-ledger-tailledger
or
gpu-retirement-ledger-tailledger
pending-tail
setfmerged-pt
unwind-protect
progn
loopwhilependingforentry=
firstpending
do
cond
>
gpu-retirement-entry-ready-afterentry
completed-frontier
setfretained-headpending
loop-finish
t
incf
gpu-retirement-entry-attemptsentry
handler-case
progn
funcall
gpu-retirement-entry-teardownentry
setf
gpu-retirement-entry-last-errorentry
nil
pending
restpending
gpu-retirement-ledger-active-batchledger
pending
error
cause
setf
gpu-retirement-entry-last-errorentry
cause
retained-headpendingfailures
list
make-gpu-native-retirement-failure:resource
gpu-retirement-entry-resourceentry
:causecause:attempts
gpu-retirement-entry-attemptsentry
loop-finish
merge-retained-batch

Preserve the detached suffix even across an unexpected non-local exit from a callback. Backend locks still delimit all mutation.

unlessmerged-p
setfretained-head
orretained-head
gpu-retirement-ledger-active-batchledger
merge-retained-batch
setf
gpu-retirement-ledger-active-batchledger
nil

Eventual service polls independently of callers. Surface the first failed attempt, but do not emit one warning per poll forever; the ledger retains the cause and attempt count for explicit inspection/teardown.

when
andfailures
some
lambda
failure
=1
gpu-native-retirement-failure-attemptsfailure
failures
warn'gpu-native-retirement-warning:operationoperation:failuresfailures
valuesledgerfailures
defunperform-gpu-retirement-directly
resourceteardowninvalidate&key
operation:destroy

Perform teardown without a live queue, then invalidate resource.

An error leaves the wrapper and its leak finalizer live and is re-signaled as a structured gpu-native-retirement-error retaining the original cause.

let
entry
make-gpu-retirement-entry:resourceresource:teardownteardown
handler-case
progn
incf
gpu-retirement-entry-attemptsentry
funcallteardown
error
cause
setf
gpu-retirement-entry-last-errorentry
cause
error'gpu-native-retirement-error:operationoperation:failures
list
make-gpu-native-retirement-failure:resourceresource:causecause:attempts
gpu-retirement-entry-attemptsentry
funcallinvalidate
resource
defunensure-gpu-retirement-ledger-empty
ledger&key
operation:destroy-device

Refuse owner teardown while ledger still owns any native resources.

let
entries
append
copy-list
gpu-retirement-ledger-active-batchledger
gpu-retirement-ledger-entriesledger
whenentries
error'gpu-native-retirement-error:operationoperation:failures
loopforentryinentriescollect
ledger
defunmake-gpu-retirement-sequence
&reststeps

Return a retryable closure over ordered, individually idempotent steps.

Each zero-argument step is removed only after it returns normally. A retry therefore resumes at the failing native call without repeating any earlier destructive call which already succeeded.

dolist
stepsteps
check-typestepfunction
let
remaining
copy-liststeps
lambda
loopwhileremainingdo
funcall
firstremaining
popremaining
values
defvar*leaked-gpu-resources*'

gpu-resource-leaked conditions recorded for objects the collector had to reclaim. Inspect or clear this from the REPL to audit leak hygiene.

defunnote-gpu-resource-leak
resource-classlabel

Record and signal one gpu-resource-leaked warning.

let
condition
make-condition'gpu-resource-leaked:resource-classresource-class:labellabel
warncondition
values
defclassgpu-provider
:documentation

Instances of gpu-provider subclasses are platform-specific factories for requesting gpu-device instances.

defvar*gpu-provider*nil"If you're lucky, someone has bound this to a working GPU-PROVIDER."
defclassgpu-object
label:initarg:label:initformnil:accessorgpu-object-label
:documentation

Base class for instantiated GPU resources.

defclassgpu-buffer
size:initarg:size:readergpu-buffer-size
usage:initarg:usage:readergpu-buffer-usage
defclassgpu-texture
size:initarg:size:readergpu-texture-size
usage:initarg:usage:readergpu-texture-usage
dimensions:initarg:dimensions:readergpu-texture-dimensions
format:initarg:format:readergpu-texture-format
defclassgpu-texture-view
texture:initarg:texture:readergpu-texture-view-texture
defclassgpu-command-buffer
:documentation

Finished one-shot work accepted by a GPU queue's submit operation.

defclassgpu-encoder
:documentation

Abstract receiver for recorded GPU commands.

defclassgpu-temporal-scaler
input-size:initarg:input-size:readergpu-temporal-scaler-input-size
output-size:initarg:output-size:readergpu-temporal-scaler-output-size
color-usage:initarg:color-usage:readergpu-temporal-scaler-color-usage
depth-usage:initarg:depth-usage:readergpu-temporal-scaler-depth-usage
motion-usage:initarg:motion-usage:readergpu-temporal-scaler-motion-usage
output-usage:initarg:output-usage:readergpu-temporal-scaler-output-usage
:documentation

A retained temporal reconstruction owner and its exact texture contract.

defgenericretire-gpu-native-owner
deviceownerteardowninvalidate
:documentation

Transfer owner's native teardown to device, then invalidate owner.

Backend methods may transfer ownership to a durable device queue before invalidate and attempt it immediately. The default has no such queue: native teardown must return successfully before invalidate is called.

defmethodretire-gpu-native-owner
devicet
ownerteardowninvalidate
declare
ignoredevice
perform-gpu-retirement-directlyownerteardowninvalidate:operation:retire-gpu-native-owner
defvar*gpu-finalizer-retirement-ledger*
make-gpu-retirement-ledger
"Process-local durable ownership for native teardown abandoned by GC."
defvar*gpu-finalizer-retirement-lock*
sb-thread:make-mutex:name"luv GPU finalizer retirement"
"Serializes the process-local finalizer retirement ledger."
defunmaintain-gpu-finalizer-retirements

Retry the process-local FIFO of native ownership recovered by finalizers.

sb-thread:with-recursive-lock
maintain-gpu-retirement-ledger*gpu-finalizer-retirement-ledger*0:operation:maintain-gpu-finalizer-retirements
defunretire-gpu-finalizer-native-owner
deviceownerteardown

Durably route a finalizer's owner through device or the fallback ledger.

The fallback ledger takes ownership before any attempt. Its retryable routing step records when a backend queue has accepted owner, so a warning promoted to an error cannot cause a later retry to transfer the same native owner twice.

check-typeteardownfunction
let
routed-pnil
sb-thread:with-recursive-lock
transfer-gpu-retirement*gpu-finalizer-retirement-ledger*owner0
lambda
unlessrouted-p
retire-gpu-native-ownerdeviceownerteardown
lambda
setfrouted-pt
lambda
nil
values
defgenericrequest-gpu-device
provider&optionaldescriptor
defgenericdevice-queue
device
:documentation

Return the default queue belonging to device.

defgenericcreate
devicedescriptor
:documentation

Asks the device for a handle to newly created instance of some object fulfilling the descriptor.

defgenericadopt-native-texture
devicenative-objectownerdescriptor
:documentation

Wrap a platform texture and its retained owner in the HAL.

defgenericencode
encodercommand
:documentation

Record an inspectable GPU command onto encoder.

defgenericenqueue
queuecommand
:documentation

Issue a queue-scoped GPU command onto queue.

defgenericfinish
encoder
:documentation

Seal encoder and return one finished, one-shot GPU command buffer.

defgenericsubmit
queuework
:documentation

Schedule some command buffers on the queue.

Submission is asynchronous: returning does not mean the GPU has finished the work, only that the implementation retains everything the work depends on until it completes. Use submitted-work-done to wait.

defgenericsubmitted-work-done
queue
:documentation

Block until all work submitted to queue so far has completed on the GPU.

defgenericwrite-buffer
bufferdata&keyoffset
:documentation

Copy host data into buffer starting at byte offset.

defgenericread-buffer
buffer&keyoffsetsize
:documentation

Wait for buffer's device queue and copy mapped bytes back to the host.

defgenericread-buffer-if-ready
buffer&keyoffsetsize
:documentation

Copy mapped buffer bytes only when its own newest submission is complete.

Return the byte vector and true when ready, or NIL and NIL without waiting. Unlike read-buffer this does not wait for unrelated newer queue work.

defgenericdestroy
handle
:documentation

Logically invalidate handle immediately.

Native teardown may be deferred until submitted work which captured handle has completed.

defmethodsubmit
queue
buffersvector

Platforms can override this for more efficient batch submission.

loopforbufferacrossbuffersdo
submitqueuebuffer
defgenericbegin-render-pass
encoderdescriptor
defgenericbegin-compute-pass
encoder&optionaldescriptor
defgenericend-pass
pass-encoder
defstruct
device-descriptor
required-featuresrequired-limits
defstruct
buffer-descriptor
sizeusage
defstruct
texture-descriptor
sizeusagedimensionsformat
defparameter+portable-buffer-usages+'
:uniform:storage:vertex:index:copy-dst
defparameter+portable-texture-usages+'
:copy-src:copy-dst:storage-binding:texture-binding:render-attachment
defunreject-portable-gpu-descriptor
operationdescriptorreasondetails
error'gpu-request-error:operationoperation:descriptordescriptor:reasonreason:detailsdetails
defunportable-sequence-list
value

Copy a proper list or vector value, returning NIL for malformed lists.

typecasevalue
vector
coercevalue'list
list
handler-case
and
list-lengthvalue
copy-listvalue
type-error
nil
otherwisenil
defuncanonical-gpu-usage-list
usagepermitteddescriptorreasonoperation

Return portable usage syntax as one stable, duplicate-free keyword list.

let
unless
andusages
every
lambda
value
membervaluepermitted
usages
reject-portable-gpu-descriptoroperationdescriptorreasonusage

Preserve the caller's first occurrence: usage order is not semantic, but stable normalization makes descriptors pleasant to inspect.

remove-duplicatesusages:test#'eq:from-endt
defuncanonical-texture-extent
sizedescriptor&optional
operation:create

Return the current portable two-dimensional size contract as (W H 1).

let
unless
and
member
lengthcomponents
'
23
every
lambda
value
and
integerpvalue
pluspvalue
components
or
=2
lengthcomponents
=1
thirdcomponents
reject-portable-gpu-descriptoroperationdescriptor:invalid-texture-sizesize
list
firstcomponents
secondcomponents
1
defuncanonical-buffer-descriptor
descriptor&optional
operation:create

Copy descriptor into the one structural shape every backend receives.

let
size
buffer-descriptor-sizedescriptor
unless
and
typepsize'
unsigned-byte64
pluspsize
reject-portable-gpu-descriptoroperationdescriptor:invalid-buffer-sizesize
let
canonical
copy-buffer-descriptordescriptor
setf
buffer-descriptor-usagecanonical
canonical-gpu-usage-list
buffer-descriptor-usagedescriptor
+portable-buffer-usages+descriptor:invalid-buffer-usageoperation
canonical
defuncanonical-texture-descriptor
descriptor&optional
operation:create

Copy descriptor into the portable two-dimensional texture contract.

unless
eq:2d
texture-descriptor-dimensionsdescriptor
reject-portable-gpu-descriptoroperationdescriptor:invalid-texture-dimensions
texture-descriptor-dimensionsdescriptor
let
canonical
copy-texture-descriptordescriptor
setf
texture-descriptor-sizecanonical
canonical-texture-extent
texture-descriptor-sizedescriptor
descriptoroperation
texture-descriptor-usagecanonical
canonical-gpu-usage-list
texture-descriptor-usagedescriptor
+portable-texture-usages+descriptor:invalid-texture-usageoperation
canonical
defmethodcreate:around
descriptorbuffer-descriptor
call-next-methoddevice
defmethodcreate:around
descriptortexture-descriptor
call-next-methoddevice
defmethodadopt-native-texture:around
nativeowner
descriptortexture-descriptor
call-next-methoddevicenativeowner
canonical-texture-descriptordescriptor:adopt-native-texture
defunbuffer-data-foreign-type
data

Return the CFFI element type and byte size for a one-dimensional data array of single-floats or unsigned 8-, 16-, 32-, or 64-bit integers.

let
element-type
and
arraypdata
=1
array-rankdata
array-element-typedata
cond
nullelement-type
nil
subtypepelement-type'single-float
values:float4
subtypepelement-type'
unsigned-byte8
values:uint81
subtypepelement-type'
unsigned-byte16
values:uint162
subtypepelement-type'
unsigned-byte32
values:uint324
subtypepelement-type'
unsigned-byte64
values:uint648
tnil
defuntexture-format-bytes-per-texel
format

Return the exact storage size of one texel in portable format.

ecaseformat
:r16-float2
:rgba8-unorm:rgba8-unorm-srgb:bgra8-unorm:bgra8-unorm-srgb:depth32-float:rg16-uint:rg16-float
4
:rgba16-float8
defunvertex-attribute-format-component-count
format

Return the scalar lane count of a portable vertex attribute format.

The vocabulary is deliberately small and float-only: it names what the mesh and instance products this project actually writes contain, and every backend is expected to accept all of it.

ecaseformat
:float32x22
:float32x33
:float32x44
defuntexture-format-upload-element-type
format

The packed array element type accepted by write-texture for format.

ecase
2'
unsigned-byte16
4'
unsigned-byte32
8'
unsigned-byte64
defuntexture-format-sample-transfer
format

The colour transfer a sampled texture format applies before shader math.

This describes representation decoding, not a quantity. Alpha remains linear for the sRGB formats; the transfer names their RGB-channel behavior.

if
memberformat'
:rgba8-unorm-srgb:bgra8-unorm-srgb
:srgb-to-linear:identity
defstruct
texture-view-descriptor
texture
defstruct
sampler-descriptor
address-mode-u:clamp-to-edge
address-mode-v:clamp-to-edge
address-mode-w:clamp-to-edge
mag-filter:linear
min-filter:linear
mipmap-filter:nearest
compare
defstructtexture-copytexture
mip-level0
origin'
000
aspect:all
defstructtexture-data-layout
offset0
bytes-per-rowrows-per-image
defstruct
bind-group-layout-descriptor
entries
defstruct
bind-group-descriptor
layoutentries
defstruct
render-pipeline-descriptor

A render pipeline. Each fragment target may name :BLEND :PREMULTIPLIED-ALPHA; omitted blending retains opaque replacement semantics.

layoutvertexfragment
primitive'
:topology:triangle-list
depth-stencil
defstruct
mesh-render-pipeline-descriptor

A task/mesh render pipeline.

TASK may be NIL for a direct mesh dispatch. MAX-MESH-WORKGROUPS states the largest task-to-mesh amplification admitted by one task workgroup.

layouttaskmeshfragment
max-mesh-workgroups1
depth-stencil
defstruct
render-pass-descriptor
color-attachmentsdepth-stencil-attachment
defstruct
compute-pipeline-descriptor
layoutmodule
defstruct
command-encoder-descriptor
defstruct
temporal-scaler-descriptor
input-sizeoutput-size
color-format:rgba16-float
depth-format:depth32-float
motion-format:rg16-float
output-format:rgba16-float
defstruct
shader-module-descriptor
code
language:spir-v
defstructgpu-command
defstruct
gpu-queue-command
:includegpu-command
defstruct
gpu-command-encoder-command
:includegpu-command
defstruct
gpu-pass-command
:includegpu-command
defstruct
gpu-render-pass-command
:includegpu-pass-command
defstruct
gpu-compute-pass-command
:includegpu-pass-command
defstruct
gpu-draw-command
:includegpu-render-pass-command
vertex-count
instance-count1
first-vertex0
first-instance0
defstruct
gpu-draw-indexed-command
:includegpu-render-pass-command
index-buffer
index-format:uint16
index-count
instance-count1
first-index0
base-vertex0
first-instance0
defstruct
gpu-draw-mesh-command
:includegpu-render-pass-command
x
y1
z1
defstruct
gpu-set-pipeline-command
:includegpu-pass-command
pipeline
defstruct
gpu-set-bind-group-command
:includegpu-pass-command
index0
bind-group
defstruct
gpu-set-vertex-buffer-command
:includegpu-render-pass-command
slot0
buffer
offset0
defstruct
gpu-dispatch-workgroups-command
:includegpu-compute-pass-command
x
y1
z1
defstruct
gpu-set-viewport-command
:includegpu-render-pass-command
xywidthheightmin-depthmax-depth
defstruct
gpu-set-scissor-command
:includegpu-render-pass-command
xywidthheight
defstruct
gpu-clear-texture-command
:includegpu-command-encoder-command
texturecolor
defstruct
gpu-copy-texture-command
:includegpu-command-encoder-command
sourcedestination
defstruct
gpu-copy-texture-to-buffer-command
:includegpu-command-encoder-command
sourcedestination
defstruct
gpu-write-texture-command
:includegpu-queue-command
destinationdatadata-layoutsize
defstruct
gpu-prepare-texture-command
:includegpu-command-encoder-command
textureusage
defstruct
gpu-temporal-scale-command
:includegpu-command-encoder-command
scalercolordepthmotionoutputjitterreset-p
defstruct
gpu-signal-temporal-scaler-command
:includegpu-render-pass-command
scaler
defstruct
gpu-wait-temporal-scaler-command
:includegpu-render-pass-command
scaler
defmethodencode
error'gpu-request-error:operation:encode:descriptorcommand:reason:unsupported-command-for-encoder:details
list:encoder
class-name
class-ofencoder
:command
type-ofcommand
defmethodenqueue
commandgpu-queue-command
error'gpu-request-error:operation:enqueue:descriptorcommand:reason:unsupported-queue-command:details
list:queue
class-name
class-ofqueue
:command
type-ofcommand

These WebGPU-flavored verbs are intentionally just REPL conveniences. Command objects are the protocol: backends specialize encode for recorded encoder commands and enqueue for immediate queue commands.

defunset-pipeline
pass-encoderpipeline
encodepass-encoder
make-gpu-set-pipeline-command:pipelinepipeline
defunset-bind-group
pass-encoderindexbind-group
encodepass-encoder
make-gpu-set-bind-group-command:indexindex:bind-groupbind-group
defunset-vertex-buffer
pass-encoderslotbuffer&key
offset0
encodepass-encoder
make-gpu-set-vertex-buffer-command:slotslot:bufferbuffer:offsetoffset
defunset-scissor-rect
pass-encoderxywidthheight
encodepass-encoder
make-gpu-set-scissor-command:xx:yy:widthwidth:heightheight
defundispatch-workgroups
pass-encoderx&optional
y1
z1
encodepass-encoder
make-gpu-dispatch-workgroups-command:xx:yy:zz
defundraw
pass-encodervertex-count&optional
instance-count1
first-vertex0
first-instance0
encodepass-encoder
make-gpu-draw-command:vertex-countvertex-count:instance-countinstance-count:first-vertexfirst-vertex:first-instancefirst-instance
defundraw-indexed
pass-encoderindex-bufferindex-formatindex-count&optional
instance-count1
first-index0
base-vertex0
first-instance0

Draw indexed instances from index-buffer.

index-format is :UINT16 or :UINT32. The buffer is carried by the command so recorded work owns the complete indexed-draw dependency at one boundary.

encodepass-encoder
make-gpu-draw-indexed-command:index-bufferindex-buffer:index-formatindex-format:index-countindex-count:instance-countinstance-count:first-indexfirst-index:base-vertexbase-vertex:first-instancefirst-instance
defundraw-mesh-workgroups
pass-encoderx&optional
y1
z1
encodepass-encoder
make-gpu-draw-mesh-command:xx:yy:zz
defunwrite-texture
queuedestinationdatadata-layoutsize

Issue one WebGPU-style convenience upload onto queue.

enqueuequeue
make-gpu-write-texture-command:destinationdestination:datadata:data-layoutdata-layout:sizesize
defunprepare-texture
encodertextureusage

Prepare texture for semantic usage in encoder's following commands.

The backend owns any layout transition, hazard barrier, or validation needed to realize the usage. Application code does not dispatch on the backend. #T5MQO0

encodeencoder
make-gpu-prepare-texture-command:texturetexture:usageusage
defunencode-temporal-scale
encoderscalercolordepthmotionoutputjitterreset-p

Encode one temporal reconstruction from color, depth, and motion.

jitter is the current sample offset in input-pixel units. Motion values are current-to-previous displacements in normalized input-texture coordinates; the scaler's input extent binds their conversion to pixels once per frame.

encodeencoder
make-gpu-temporal-scale-command:scalerscaler:colorcolor:depthdepth:motionmotion:outputoutput:jitterjitter:reset-preset-p
defunsignal-temporal-scaler-inputs
passscaler

Publish pass's attachment writes to scaler's private synchronization.

encodepass
make-gpu-signal-temporal-scaler-command:scalerscaler
defunwait-temporal-scaler-output
passscaler

Make pass's fragment reads wait for scaler's reconstructed output.

encodepass
make-gpu-wait-temporal-scaler-command:scalerscaler