Skip to main content

SlabAllocator

Struct SlabAllocator 

Source
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: BufferUsages

Additional buffer usages to add to any vertex or index buffers created.

Implementations§

Source§

impl<I> SlabAllocator<I>
where I: SlabItem,

Source

pub fn new() -> Self

Creates a new empty slab allocator.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn slab_count(&self) -> usize

Get the number of allocated slabs

Source

pub fn slabs_size(&self) -> u64

Get the total size of all allocated slabs

Source

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§

Source§

impl<I> Default for SlabAllocator<I>
where I: SlabItem,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<I> Freeze for SlabAllocator<I>

§

impl<I> !RefUnwindSafe for SlabAllocator<I>

§

impl<I> Send for SlabAllocator<I>
where I: Send, <I as SlabItem>::Key: Send, <I as SlabItem>::Layout: Send,

§

impl<I> Sync for SlabAllocator<I>
where I: Sync, <I as SlabItem>::Key: Sync, <I as SlabItem>::Layout: Sync,

§

impl<I> Unpin for SlabAllocator<I>
where I: Unpin, <I as SlabItem>::Key: Unpin, <I as SlabItem>::Layout: Unpin,

§

impl<I> UnsafeUnpin for SlabAllocator<I>

§

impl<I> !UnwindSafe for SlabAllocator<I>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts 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>

Converts 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)

Converts &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)

Converts &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
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromWorld for T
where T: Default,

Source§

fn from_world(_world: &mut World) -> T

Creates Self using default().

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,