Thread safety
- The library has no global state, so separate VmaAllocator objects can be used independently. There should be no need to create multiple such objects though - one per
VkDevice
is enough.
- By default, all calls to functions that take VmaAllocator as first parameter are safe to call from multiple threads simultaneously because they are synchronized internally when needed.
- When the allocator is created with VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT flag, calls to functions that take such VmaAllocator object must be synchronized externally.
- Access to a VmaAllocation object must be externally synchronized. For example, you must not call vmaGetAllocationInfo() and vmaMapMemory() from different threads at the same time if you pass the same VmaAllocation object to these functions.
Validation layer warnings
When using this library, you can meet following types of warnings issued by Vulkan validation layer. They don't necessarily indicate a bug, so you may need to just ignore them.
- vkBindBufferMemory(): Binding memory to buffer 0xeb8e4 but vkGetBufferMemoryRequirements() has not been called on that buffer.
- It happens when VK_KHR_dedicated_allocation extension is enabled.
vkGetBufferMemoryRequirements2KHR
function is used instead, while validation layer seems to be unaware of it.
- Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.
- It happens when you map a buffer or image, because the library maps entire
VkDeviceMemory
block, where different types of images and buffers may end up together, especially on GPUs with unified memory like Intel.
- Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug.
- It happens when you use lost allocations, and a new image or buffer is created in place of an existing object that bacame lost.
Allocation algorithm
The library uses following algorithm for allocation, in order:
- Try to find free range of memory in existing blocks.
- If failed, try to create a new block of
VkDeviceMemory
, with preferred block size.
- If failed, try to create such block with size/2, size/4, size/8.
- If failed and VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag was specified, try to find space in existing blocks, possilby making some other allocations lost.
- If failed, try to allocate separate
VkDeviceMemory
for this allocation, just like when you use VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
- If failed, choose other memory type that meets the requirements specified in VmaAllocationCreateInfo and go to point 1.
- If failed, return
VK_ERROR_OUT_OF_DEVICE_MEMORY
.
Features not supported
Features deliberately excluded from the scope of this library:
- Data transfer - issuing commands that transfer data between buffers or images, any usage of
VkCommandList
or VkCommandQueue
and related synchronization is responsibility of the user.
- Allocations for imported/exported external memory. They tend to require explicit memory type index and dedicated allocation anyway, so they don't interact with main features of this library. Such special purpose allocations should be made manually, using
vkCreateBuffer()
and vkAllocateMemory()
.
- Support for any programming languages other than C/C++. Bindings to other languages are welcomed as external projects.