pub struct SlabAllocator<I>where
I: SlabItem,{
pub slabs: HashMap<SlabId<I>, Slab<I>>,
pub key_to_slab: HashMap<I::Key, SlabId<I>>,
pub extra_buffer_usages: BufferUsages,
/* private fields */
}Expand description
A general-purpose allocator that manages a set of GPU buffer slabs.
You can use this allocator to pack data that needs to be accessible by the GPU into a small set of buffers, known as slabs. Each individual slab is expected to contain homogeneous data of a single type. However, you can use a single allocator to manage multiple slabs, each of which can have a different data layout. Objects managed by the allocator are referenced with a key that you can define.
To use this allocator, implement the SlabItem trait; see the
documentation of that trait for details.
For performance, you’ll want to batch your allocation and deallocation
operations to be performed at a single point in the frame. To perform
allocation, call Self::stage_allocation to obtain an
AllocationStage, call AllocationStage::allocate to allocate
individual objects, and then commit the allocation transaction using
AllocationStage::commit. Likewise, to perform deallocation, call
Self::stage_deallocation to obtain a DeallocationStage, call
DeallocationStage::free to free objects, and then call
DeallocationStage::commit. Once you’ve committed an allocation stage,
you can copy new data into the slabs via Self::copy_element_data.
Within each slab, or hardware buffer, the underlying allocation algorithm
is offset_allocator, a Rust port of Sebastian Aaltonen’s hard-real-time
C++ OffsetAllocator. Slabs start small and then grow as their contents
fill up, up to a maximum size limit. To reduce fragmentation, objects that
are too large bypass this system and receive their own buffers.
The SlabAllocatorSettings allows you to tune the behavior of the
allocator for better performance with your use case.
See crate::mesh::allocator::MeshAllocator for an example of usage.
Fields§
§slabs: HashMap<SlabId<I>, Slab<I>>Holds all buffers and allocators.
key_to_slab: HashMap<I::Key, SlabId<I>>Maps slab allocation keys to the ID of the slabs that hold their data.
extra_buffer_usages: BufferUsagesAdditional buffer usages to add to any vertex or index buffers created.
Implementations§
Source§impl<I> SlabAllocator<I>where
I: SlabItem,
impl<I> SlabAllocator<I>where
I: SlabItem,
Sourcepub fn stage_allocation(&mut self) -> AllocationStage<'_, I>
pub fn stage_allocation(&mut self) -> AllocationStage<'_, I>
Creates an AllocationStage, enabling batched allocation of objects
in this slab.
Allocation of objects in the slab requires calling this function,
calling AllocationStage::allocate on the resulting
AllocationStage, and finally calling AllocationStage::commit.
Grouping allocations into a batch, preferably at most one per frame, is
the most efficient way to perform many allocations at once.
Sourcepub fn stage_deallocation(&mut self) -> DeallocationStage<'_, I>
pub fn stage_deallocation(&mut self) -> DeallocationStage<'_, I>
Creates a DeallocationStage, enabling batched deallocation.
Deallocation of objects in the slab requires calling this function,
calling DeallocationStage::free on the resulting
DeallocationStage, and finally calling
DeallocationStage::commit. Grouping deallocations into a batch,
preferably at most one per frame, is the most efficient way to perform
many deallocations at once.
Sourcepub fn buffer_for_slab(&self, slab_id: SlabId<I>) -> Option<&Buffer>
pub fn buffer_for_slab(&self, slab_id: SlabId<I>) -> Option<&Buffer>
Returns the GPU buffer corresponding to the slab with the given ID if that slab has been uploaded to the GPU.
Sourcepub fn slab_allocation_slice(
&self,
key: &I::Key,
slab_id: SlabId<I>,
) -> Option<SlabAllocationBufferSlice<'_, I>>
pub fn slab_allocation_slice( &self, key: &I::Key, slab_id: SlabId<I>, ) -> Option<SlabAllocationBufferSlice<'_, I>>
Given a slab and the key of data located with it, returns the buffer and range of that data within the slab.
Sourcepub fn slab_count(&self) -> usize
pub fn slab_count(&self) -> usize
Get the number of allocated slabs
Sourcepub fn slabs_size(&self) -> u64
pub fn slabs_size(&self) -> u64
Get the total size of all allocated slabs
Sourcepub fn copy_element_data(
&mut self,
key: &I::Key,
len: usize,
fill_data: impl Fn(WriteOnly<'_, [u8]>),
render_device: &RenderDevice,
render_queue: &RenderQueue,
)
pub fn copy_element_data( &mut self, key: &I::Key, len: usize, fill_data: impl Fn(WriteOnly<'_, [u8]>), render_device: &RenderDevice, render_queue: &RenderQueue, )
Copies data into an allocated slab.
len specifies the size of the data to be copied in bytes. The given
fill_data callback is expected to write the data into the given slice;
this callback approach avoids a copy.
Trait Implementations§
Auto Trait Implementations§
impl<I> Freeze for SlabAllocator<I>
impl<I> !RefUnwindSafe for SlabAllocator<I>
impl<I> Send for SlabAllocator<I>
impl<I> Sync for SlabAllocator<I>
impl<I> Unpin for SlabAllocator<I>
impl<I> UnsafeUnpin for SlabAllocator<I>
impl<I> !UnwindSafe for SlabAllocator<I>
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T ShaderType for self. When used in AsBindGroup
derives, it is safe to assume that all images in self exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more