Expand description
Dependency-tracked GPU resource graph.
The graph is the renderer’s single source of truth for the wgpu resources a frame draws with — textures and their views, samplers, buffers and bind groups — and for the virtual nodes that hold no handle at all, which group or stand in for the resources around them. Pipeline objects (shader modules, layouts, pipelines) are not tracked: they are immutable once built, and the render pipelines this crate builds are cached by their variant rather than rebuilt from dependencies. Resources are plain wgpu handles — the graph does not wrap them — but it remembers which resource was built from which, so that derived resources can be rebuilt when their inputs change:
ResourceGraph::replaceswaps a resource and marks every resource transitively built from it as dirty.- Dropping the last
ResHandleto a resource makes it collectable. ResourceGraph::maintaincollects the resources no id and no dependent holds any more, and rebuilds the resources marked dirty.
Nothing happens at the point of the change: replace only flips dirty
flags, and taking or dropping an id only moves a reference count. Both take
effect the next time ResourceGraph::maintain runs, which is where a
frame calls it exactly once — before the resources are read.
Updates are therefore lazy and precise: uploading new bytes into an existing buffer does not dirty anything, reallocating it does, and only the resources that actually consumed the old handle are affected.
§Rebuilding
A resource that can be rebuilt is inserted with a recipe:
insert takes an optional
Rebuild closure that produces a fresh handle out of the graph. A recipe
reads the resources it was built from back out of the graph by id rather
than capturing their handles, so it observes the current state of its
inputs — a buffer that was reallocated or an array that was replaced — at
the moment it runs.
ResourceGraph::maintain runs the recipes of the dirty nodes in
dependency order, so a rebuilt resource is always built from
already-rebuilt inputs. A dirty node with no recipe is left dirty: the
caller changed something the graph cannot rebuild on its own.
§Typed ids
A ResHandle is typed by the ResourceKind it names, and the kind is
the resource itself: ResHandle<wgpu::Buffer> resolves to a
buffer, ResHandle<TextureView> to a texture view together
with its format, and ResHandle<Virtual> to a node that
holds no handle.
ResourceGraph::get hands that resource back directly, so no caller
matches on which variant a node holds and a texture view cannot be read
where a buffer is wanted.
The kind is a compile-time claim rather than runtime state: the graph stores
every resource in one Resource enum, and a typed id is an index that
remembers what it names. Insertion derives the
kind from the resource it is given and
replace requires the replacement to have the
same kind, so an id never names a resource of another kind. Where the kind
is genuinely unknown at compile time — a node’s dependencies, a dirty
node — the erased ResHandle<Resource> names it
instead.
§Retention
An id names a strong reference to its resource: cloning one takes another
reference, dropping one gives it up, and ResourceGraph::maintain
collects the resource once its last reference is gone. There is no removal
call and no handle that goes stale — a resource lives exactly while some id
to it does, and letting go of the last id is all it takes to free it.
A resource built from another holds a reference to it too: recording an edge
with add_dependency takes one reference
from the dependency on behalf of the dependent, so a dependency counts its
dependents among the references that keep it alive. A resource that exists
only to feed a consumer therefore lives exactly while some consumer does,
and collecting a consumer releases whatever it was the last holder of in the
same pass. Declaring the same edge twice records it once, and so counts
once.
Insertion is immediate: insert adds the node and returns its id, and
add_dependency records an edge. Nothing
defers, so there is no insertion state to finish and no failure to report —
an edge that would close a cycle is a bug in the caller and panics where it
is declared.
A Virtual node commonly serves as an aggregation root for a group of
resources: the root is built from every part, so the root is the group’s
single lifetime entry point. Dropping the last id to the root releases the
parts the root was the last holder of, and ResourceGraph::maintain
collects them. A part shared by two roots therefore outlives either one
alone.
Re-exports§
use std::sync::Arc;🔒use std::sync::Weak;🔒use crate::dag::Dag;🔒use crate::dag::EdgeError;🔒use crate::dag::NodeId;🔒
Macros§
- into_
resource 🔒 - Implement the erasing conversion into
Resourcefor a kind whose stored variant carries it as its only payload. - stored_
kind 🔒 - Implement
ResourceKindfor a kind stored in oneResourcevariant.
Structs§
- Node 🔒
- Node
Info - One resource as
ResourceGraph::nodesreports it. - Rebuild
- A recipe that builds a resource out of the graph it lives in.
- ResHandle
- Handle to a resource stored in a
ResourceGraph, typed by its kind. - ResId
- A resource’s identity as a plain value.
- Resource
Graph - A directed acyclic graph of wgpu resources.
- Resource
Graph Info - The shape of a
ResourceGraph, as plain data. - Resource
Graph Maintain - What one
ResourceGraph::maintainpass changed. - Resource
Info - One resource slot of a
ResourceGraph, as plain data. - Resource
Kind Count - How many resources of one kind a
ResourceGraphholds. - Texture
View - A texture view together with the format it views its texture as.
- Virtual
- The kind of a virtual node: a graph citizen holding no wgpu handle.
Enums§
- Resource
- A wgpu resource owned by the graph, or a virtual node standing in for one.
Statics§
- VIRTUAL 🔒
- The one
Virtualvalue, so itsResourceKindcan hand out a borrow.
Traits§
- Resource
Kind - A kind of resource that can live in a
ResourceGraph, and the resource an id of that kind resolves to. - Texture
Ext - Creating texture views whose format the graph can track.
Type Aliases§
- Strong
Ref 🔒 - The strong reference count of one node is the number of
ResHandles that name it plus the number of nodes built from it, which is exactly whatArcalready counts. - Strong
Refs 🔒