pub struct LutPair { /* private fields */ }Expand description
The two LUT textures, their views, the sampler, the baked palette awaiting
upload and the dirty flag — the set every shader-coloured scene owns to
render a palette_mix crossfade.
§The upload is deferred, and that is the invariant this type keeps
set is called from Scene::set_palette, which has no
Queue: a preset switch bakes a palette on the CPU and the GPU upload has to
wait for the next frame. So set stores the palette and raises dirty, and
flush — called at the top of render, where a Queue
exists — uploads and clears it. Two sets between frames cost one upload;
a frame with no set costs none.
A freshly constructed pair is dirty, because its textures are empty. A
scene that builds its GPU resources lazily (or rebuilds them on a resize)
therefore gets the upload for free, but must re-set the palette it is
actually holding — new can only seed the default.
§It owns resources, never a layout shape
bind_entries takes all three binding numbers from
the caller and the caller’s own create_bind_group_layout still spells the
entries. Nothing here can make two layouts share a shape, which is what
ADR-0058 forbids without recorded evidence — and the six scenes bind this
triple at genuinely different indices and in different orders.
Implementations§
Source§impl LutPair
impl LutPair
Sourcepub fn new(device: &Device, stem: &str) -> Self
pub fn new(device: &Device, stem: &str) -> Self
Both textures, both views and the sampler, seeded with the default
palette and dirty — the textures hold no bytes until the first
flush.
stem names the pair: the textures are labelled <stem>-lut-a and
<stem>-lut-b.
Sourcepub fn set(&mut self, palette: &Palette)
pub fn set(&mut self, palette: &Palette)
Hold palette for upload on the next flush. A
6 KB array copy, off the hot path (preset switch or resource build).
Sourcepub fn flush(&mut self, queue: &Queue) -> bool
pub fn flush(&mut self, queue: &Queue) -> bool
Upload the held palette into both textures if anything has changed since the last call, and report whether it did.
Called once per frame from render. The return value is what the unit
test reads; the scenes ignore it.
Sourcepub fn bind_entries(
&self,
binding_a: u32,
binding_b: u32,
binding_sampler: u32,
) -> [BindGroupEntry<'_>; 3]
pub fn bind_entries( &self, binding_a: u32, binding_b: u32, binding_sampler: u32, ) -> [BindGroupEntry<'_>; 3]
The three bind-group entries, at the binding numbers the caller names.
The array is ordered by LUT role — A, B, sampler — not by binding
number, because the callers disagree on both. shape_field and
shape_collage bind the sampler at 0 and the textures at 1 and 2;
fragment_field and warp_mesh bind A, B, sampler at 0, 1, 2; the
attractor at 1, 2, 3 and reaction-diffusion at 3, 4, 5. Each entry
carries its own binding, which is what wgpu matches against the layout,
so spreading this array into an entries list in role order is correct at
every one of them.