Renderer · interface

BufferReuse

Which values of a graph may share one buffer, as one rule both sides plan by: the device's runner beside this file, and @driftengine/texture's reference evaluator.

Explained in Hello world.

interface BufferReuse
import type { BufferReuse } from '@driftengine/core';

In depth

It lives here rather than beside that evaluator because of the direction of the arrow. texture peers on core and core does not peer on texture — deviceGraph.ts says so and is built around it — so a rule both need has to sit on this side or be written twice. It was on the other side for a day, where it made core's runtime import a devDependency and scripts/boundaries.test.mjs refused it.

A value's buffer is given back after the last node that reads it, and not before — so a node's output never shares a buffer with any of its own inputs, since the inputs are read while the output is written. What is held keeps a buffer of its own for the life of the plan, and so does every output; a value that is neither written by a node nor held is not planned at all, which is how the evaluator leaves weights and inputs in the caller's own arrays.

Two implementations of this would drift, and the failure is a network that runs, validates and answers wrongly — a value overwritten before its last reader reads it.

What it gives up: a free buffer is taken first-come rather than by the size that fits best, so a small value may hold a large buffer while a larger one waits. The transformers this runs repeat a block of identically shaped values, where first-come and best-fit choose the same buffers.

Properties

NameTypeDescription
slotOfreadonlyReadonlyMap<string, number>The buffer each planned value lives in.
sizesreadonlyreadonly number[]Each buffer's size, in values: the largest value it ever holds.