luv

Workshop wiki

live-artifact-tests.lisp

hal/live-artifact-tests.lisp

system luv/test · 25 definitions · on GitHub

in-package#:luv.tests

The generic protocol deliberately requires no common superclass. This is the adapter shape a whole luft renderer cohort can use without pretending to be one per-pipeline artifact.

defclassprotocol-live-artifact
refresh-count:initform0:accessorprotocol-live-artifact-refresh-count
released-p:initformnil:accessorprotocol-live-artifact-released-p
defmethodluv::live-artifact-label
declare
ignoreartifact

protocol cohort

defmethodluv::live-artifact-status
if
protocol-live-artifact-released-partifact
:released:installed
defmethodluv::live-artifact-diagnostic
declare
ignoreartifact
nil
defmethodluv::live-artifact-installed-revision
protocol-live-artifact-refresh-countartifact
defmethodluv::refresh-live-artifact
unless
protocol-live-artifact-released-partifact
incf
protocol-live-artifact-refresh-countartifact
artifact
defmethodluv::release-live-artifact
setf
protocol-live-artifact-released-partifact
t
nil
defclassprotocol-live-application
artifact:initarg:artifact:readerprotocol-live-application-artifact
defmethodluv::application-live-artifacts
list
protocol-live-application-artifactapplication

Backend-independent live-pipeline ownership probe -------------------------

defmethodluv.shader:shader-source-value
name
eql'live-artifact-test-color
declare
ignorename
luv.shader:define-shader-methodluv.shader:shader-specification-forlive-artifact-test-vertex-specification
role
eql:live-artifact-test
stage
eql:vertex
:stage:vertex:inputs
position:vec3:location0
:outputs
clip-position:vec4:built-in:position
let*
luv.shader:set-outputclip-positionclip
luv.shader:define-shader-methodluv.shader:shader-specification-forlive-artifact-test-fragment-specification
role
eql:live-artifact-test
stage
eql:fragment
:stage:fragment:outputs
color:vec4:location0
let*
rgba
luv.shader:vec4live-artifact-test-color0.250.751.0
luv.shader:set-outputcolorrgba
defclasslive-artifact-test-resource
destroy-count:initform0:accessorlive-artifact-test-destroy-count
fail-destroy-p:initformnil:accessorlive-artifact-test-fail-destroy-p
defmethodluv:destroy
incf
live-artifact-test-destroy-countresource
when
live-artifact-test-fail-destroy-presource
error"Deliberate live artifact retirement failure."
nil
defclasslive-artifact-test-device
modules:initformnil:accessorlive-artifact-test-modules
pipelines:initformnil:accessorlive-artifact-test-pipelines
fail-pipeline-p:initformnil:accessorlive-artifact-test-fail-pipeline-p
defmethodluv:create
descriptorluv::shader-module-descriptor
let
module
make-instance'live-artifact-test-module:label
luv::gpu-descriptor-labeldescriptor
pushmodule
live-artifact-test-modulesdevice
module
defmethodluv:create
descriptorluv::render-pipeline-descriptor
declare
ignoredescriptor
when
live-artifact-test-fail-pipeline-pdevice
error"Deliberate live pipeline candidate failure."
let
pipeline
pushpipeline
live-artifact-test-pipelinesdevice
pipeline
defunlive-artifact-test-reference-value
artifact
cdr
assoc'live-artifact-test-color
luv::live-shader-pipeline-attempted-source-valuesartifact
defunredefine-live-artifact-test-fragment
green

Replace the probe's fragment method at its ordinary DEFMETHOD coordinate.

eval`
luv.shader:define-shader-methodluv.shader:shader-specification-forlive-artifact-test-fragment-specification
role
eql:live-artifact-test
stage
eql:fragment
:stage:fragment:outputs
color:vec4:location0
let*
rgba
luv.shader:vec4live-artifact-test-color,green0.751.0
luv.shader:set-outputcolorrgba
deftestlive-pipeline-keeps-last-good-cleans-candidates-and-release-is-terminal
let*
device
artifactnil
unwind-protect
progn
setfartifact
luv::make-live-shader-pipeline:role:live-artifact-test:vertex-role:live-artifact-test:label"live artifact ownership probe":devicedevice:layoutnil:vertex-buffers'
:array-stride12:attributes
:shader-location0:offset0:format:float32x3
:target-format:rgba8-unorm:primitive'
:topology:triangle-list
:depth-stencilnil
let
first-pipeline
luv::live-shader-pipeline-native-pipelineartifact
first-modules
copy-list
live-artifact-test-modulesdevice
ok
eq:installed

The changed live source value requests an attempt. Pipeline creation fails after both candidate modules exist: the old installed cohort survives and both candidates are reclaimed.

setf*live-artifact-test-color*0.8f0
live-artifact-test-fail-pipeline-pdevice
t
ok
eq:failed
ok
ok
eqfirst-pipeline
luv::live-shader-pipeline-native-pipelineartifact
ok
=4
length
live-artifact-test-modulesdevice
ok
every
lambda
resource
=1
live-artifact-test-destroy-countresource
subseq
live-artifact-test-modulesdevice
02
ok
every
lambda
resource
zerop
live-artifact-test-destroy-countresource
first-modules
ok
zerop
live-artifact-test-destroy-countfirst-pipeline

A second value change retries without any method edit. The complete candidate installs, then the old cohort retires.

setf*live-artifact-test-color*0.6f0
live-artifact-test-fail-pipeline-pdevice
nil
ok
eq:installed
ok
=0.6f0
cdr
assoc'live-artifact-test-color
luv::live-shader-pipeline-installed-source-valuesartifact
ok
=1
live-artifact-test-destroy-countfirst-pipeline
ok
every
lambda
resource
=1
live-artifact-test-destroy-countresource
first-modules

Ordinary method replacement is a narrow MOP dependency, quite separate from live values and the global reusable-source stamp.

let
value-pipeline
luv::live-shader-pipeline-native-pipelineartifact
value-modules
subseq
live-artifact-test-modulesdevice
02
ok
luv.shader:shader-definition-change-pending-p
luv::live-shader-pipeline-dependentartifact
ok
not
luv.shader:shader-definition-change-pending-p
luv::live-shader-pipeline-dependentartifact
ok
=1
live-artifact-test-destroy-countvalue-pipeline
ok
every
lambda
resource
=1
live-artifact-test-destroy-countresource
value-modules

Reusable shader functions and abstractions carry a conservative global revision because their call graph is deliberately late bound. It rebuilds the complete candidate and stamps success.

let
method-pipeline
luv::live-shader-pipeline-native-pipelineartifact
method-modules
subseq
live-artifact-test-modulesdevice
02
luv.shader::note-shader-source-redefinition'live-artifact-test-abstraction
let
ok
=source-revision
luv::live-shader-pipeline-installed-source-revisionartifact
ok
=1
live-artifact-test-destroy-countmethod-pipeline
ok
every
lambda
resource
=1
live-artifact-test-destroy-countresource
method-modules
let
installed-pipeline
luv::live-shader-pipeline-native-pipelineartifact
installed-modules
subseq
live-artifact-test-modulesdevice
02
ok
eq:released
ok
null
luv::live-shader-pipeline-native-pipelineartifact
ok
=1
live-artifact-test-destroy-countinstalled-pipeline
ok
every
lambda
resource
=1
live-artifact-test-destroy-countresource
installed-modules

A global reusable-source revision used to resurrect a released pipeline. Release is now terminal and idempotent.

let
module-count
length
live-artifact-test-modulesdevice
pipeline-count
length
live-artifact-test-pipelinesdevice
ok
=module-count
length
live-artifact-test-modulesdevice
ok
=pipeline-count
length
live-artifact-test-pipelinesdevice
ok
=1
live-artifact-test-destroy-countinstalled-pipeline
whenartifact
ignore-errors
deftestlive-pipeline-release-detaches-first-and-attempts-every-retirement
let*
device
artifact
luv::make-live-shader-pipeline:role:live-artifact-test:vertex-role:live-artifact-test:label"live artifact failing retirement probe":devicedevice:layoutnil:vertex-buffers'
:array-stride12:attributes
:shader-location0:offset0:format:float32x3
:target-format:rgba8-unorm:primitive'
:topology:triangle-list
:depth-stencilnil
pipeline
luv::live-shader-pipeline-native-pipelineartifact
modules
copy-list
live-artifact-test-modulesdevice
conditionnil
setf
live-artifact-test-fail-destroy-ppipeline
t
live-artifact-test-fail-destroy-p
firstmodules
t
handler-case
luv:release-error
failure
setfconditionfailure
ok
typepcondition'luv:release-error
ok
=2
length
luv:release-error-failurescondition
ok
eq:released
ok
null
luv::live-shader-pipeline-dependentartifact
ok
null
luv::live-shader-pipeline-vertex-dependentartifact
ok
null
luv::live-shader-pipeline-native-pipelineartifact
ok
null
luv::live-shader-pipeline-fragment-moduleartifact
ok
null
luv::live-shader-pipeline-vertex-moduleartifact
ok
=1
live-artifact-test-destroy-countpipeline
ok
every
lambda
module
=1
live-artifact-test-destroy-countmodule
modules

The error is a published diagnostic, not a claim that teardown may be replayed against wrappers the application has already relinquished.

ok
eqcondition
ok
=1
live-artifact-test-destroy-countpipeline
ok
every
lambda
module
=1
live-artifact-test-destroy-countmodule
modules