Expand description
A pool that packs many variable-size slices into one array.
The arrays a frame reads are frame-wide: one Array per kind serves every
draw, and a draw names its slice inside it rather than binding a resource of
its own. That works when the slices are of a fixed size — the metadata
entries are — but a mesh’s morph displacements are as long as the mesh has
vertices, so its slice has to be sub-allocated rather than indexed.
An ArrayPool is that: an Array plus an Allocator over its
elements, handing out ArrayRanges. It keeps a CPU mirror of the array’s
bytes, so writing a slice and publishing the array are separate steps —
ArrayPool::write fills the mirror, ArrayPool::upload copies it to
the resource. That is what lets several meshes’ slices be written into the
one array before a single upload reaches the GPU.
§Element granularity
Ranges are counted in elements, the unit the array’s ArrayHandle
indexes by, so a range’s element offset is exactly what a shader adds to its
own base index. Elements are the smallest unit the pool deals in, so an
allocator over them needs no alignment beyond one element.
§Growing
The pool doubles rather than re-packs: an Array cannot be resized, so
growing replaces the resource and every range keeps its element offset. The
CPU mirror carries the live data across, which is why the caller has to
upload after an allocation that grew the pool.
§Example
use unlit_wgpu::array_pool::ArrayPool;
let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default());
// Elements of four bytes: one `f32` each.
let mut pool = ArrayPool::new(&device, "example::arrays", 4, 16, None);
let range = pool.allocate(&device, 3).expect("the pool has room");
pool.write(range, &[1.0f32.to_le_bytes(), 2.0f32.to_le_bytes(), 3.0f32.to_le_bytes()]
.concat());
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("example"),
});
pool.upload(&device, &mut encoder);
pool.release(range.allocation);Re-exports§
use crate::offset_allocator::Allocation;🔒use crate::offset_allocator::Allocator;🔒use crate::offset_allocator::min_allocator_size;🔒use crate::texel_array::Array;🔒use crate::texel_array::ArrayHandle;🔒use core::num::NonZeroU32;🔒
Structs§
- Array
Pool - One array sub-allocated into element ranges, with a CPU mirror of its bytes.
- Array
Range - A range of elements inside an
ArrayPool’s array.
Constants§
- DEFAULT_
MAX_ 🔒RANGES - How many ranges a pool tracks unless the caller says otherwise.
- ELEMENT_
ALIGNMENT 🔒 - The alignment elements are handed out at.
- MIN_
ELEMENTS 🔒 - The smallest pool size, so the first grow has something to grow from.
Functions§
- growth_
step 🔒 - The element count to grow
currentto so it coversend.