pub struct GenericMemoryAllocator<S> { /* private fields */ }
Expand description

A generic implementation of a memory allocator.

The allocator keeps a pool of DeviceMemory blocks for each memory type and uses the type parameter S to suballocate these blocks. You can also configure the sizes of these blocks. This means that you can have as many GenericMemoryAllocators as you you want for different needs, or for performance reasons, as long as the block sizes are configured properly so that too much memory isn’t wasted.

See also the MemoryAllocator implementation.

Mapping behavior

Every time a new DeviceMemory block is allocated, it is mapped in full automatically as long as it resides in host-visible memory. It remains mapped until it is dropped, which only happens if the allocator is dropped. In other words, all eligible blocks are persistently mapped, so you don’t need to worry about whether or not your host-visible allocations are host-accessible.

DeviceMemory allocation

If an allocation is created with the MemoryAllocatePreference::Unknown option, and the allocator deems the allocation too big for suballocation (larger than half the block size), or the implementation prefers or requires a dedicated allocation, then that allocation is made a dedicated allocation. Using MemoryAllocatePreference::NeverAllocate, a dedicated allocation is never created, even if the allocation is larger than the block size or a dedicated allocation is required. In such a case an error is returned instead. Using MemoryAllocatePreference::AlwaysAllocate, a dedicated allocation is always created.

In all other cases, DeviceMemory is only allocated if a pool runs out of memory and needs another block. No DeviceMemory is allocated when the allocator is created, the blocks are only allocated once they are needed.

Implementations§

source§

impl GenericMemoryAllocator<FreeListAllocator>

source

pub fn new_default(device: Arc<Device>) -> Self

Creates a new StandardMemoryAllocator with default configuration.

source§

impl<S> GenericMemoryAllocator<S>

source

pub fn new( device: Arc<Device>, create_info: GenericMemoryAllocatorCreateInfo<'_> ) -> Self

Creates a new GenericMemoryAllocator<S> using the provided suballocator S for suballocation of DeviceMemory blocks.

Panics
  • Panics if create_info.block_sizes doesn’t contain as many elements as the number of memory types.
  • Panics if create_info.export_handle_types is non-empty and doesn’t contain as many elements as the number of memory types.

Trait Implementations§

source§

impl<S: Debug> Debug for GenericMemoryAllocator<S>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S> DeviceOwned for GenericMemoryAllocator<S>

source§

fn device(&self) -> &Arc<Device>

Returns the device that owns self.
source§

impl<S: Suballocator + Send + 'static> MemoryAllocator for GenericMemoryAllocator<S>

source§

fn allocate_from_type( &self, memory_type_index: u32, layout: DeviceLayout, allocation_type: AllocationType, never_allocate: bool ) -> Result<MemoryAlloc, MemoryAllocatorError>

Allocates memory from a specific memory type.

Arguments
  • memory_type_index - The index of the memory type to allocate from.

  • layout - The layout of the allocation.

  • allocation_type - The type of resources that can be bound to the allocation.

  • never_allocate - If true then the allocator should never allocate DeviceMemory, instead only suballocate from existing blocks.

Panics
  • Panics if memory_type_index is not less than the number of available memory types.
Errors
  • Returns AllocateDeviceMemory if allocating a new block failed.
  • Returns OutOfPoolMemory if never_allocate is true and the pool doesn’t have enough free space.
  • Returns BlockSizeExceeded if create_info.layout.size() is greater than the block size corresponding to the heap that the memory type corresponding to memory_type_index resides in.
source§

fn allocate( &self, requirements: MemoryRequirements, allocation_type: AllocationType, create_info: AllocationCreateInfo, dedicated_allocation: Option<DedicatedAllocation<'_>> ) -> Result<MemoryAlloc, MemoryAllocatorError>

Allocates memory according to requirements.

Arguments
  • requirements - Requirements of the resource you want to allocate memory for.

    If you plan to bind this memory directly to a non-sparse resource, then this must correspond to the value returned by either RawBuffer::memory_requirements or RawImage::memory_requirements for the respective buffer or image.

  • allocation_type - What type of resource this allocation will be used for.

    This should be Linear for buffers and linear images, and NonLinear for optimal images. You can not bind memory allocated with the Linear type to optimal images or bind memory allocated with the NonLinear type to buffers and linear images. You should never use the Unknown type unless you have to, as that can be less memory efficient.

  • dedicated_allocation - Allows a dedicated allocation to be created.

    You should always fill this field in if you are allocating memory for a non-sparse resource, otherwise the allocator won’t be able to create a dedicated allocation if one is required or recommended.

    This argument is silently ignored (treated as None) if the device API version is below 1.1 and the khr_dedicated_allocation extension is not enabled on the device.

Errors
source§

fn find_memory_type_index( &self, memory_type_bits: u32, filter: MemoryTypeFilter ) -> Option<u32>

Finds the most suitable memory type index in memory_type_bits using the given filter. Returns None if the requirements are too strict and no memory type is able to satisfy them.
source§

fn allocate_dedicated( &self, memory_type_index: u32, allocation_size: DeviceSize, dedicated_allocation: Option<DedicatedAllocation<'_>>, export_handle_types: ExternalMemoryHandleTypes ) -> Result<MemoryAlloc, MemoryAllocatorError>

Creates an allocation with a whole device memory block dedicated to it.
source§

unsafe fn deallocate(&self, allocation: MemoryAlloc)

Deallocates the given allocation. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere 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, U> TryFrom<U> for Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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.