Convert Figma logo to code with AI

GPUOpen-LibrariesAndSDKs logoVulkanMemoryAllocator

Easy to integrate Vulkan memory allocation library

2,558
350
2,558
29

Top Related Projects

One stop solution for all Vulkan samples

10,152

C++ examples for the Vulkan graphics API

A beginner-friendly Vulkan path tracing tutorial in under 300 lines of C++.

3,403

A conformant OpenGL ES implementation for Windows, Mac, Linux, iOS and Android.

Vulkan Samples

Quick Overview

VulkanMemoryAllocator (VMA) is a C++ library for memory allocation in Vulkan applications. It provides a high-level interface for managing GPU memory, simplifying the process of allocating, freeing, and managing memory for Vulkan buffers and images.

Pros

  • Simplifies Vulkan memory management, reducing boilerplate code
  • Optimizes memory usage through intelligent allocation strategies
  • Supports custom memory pools and defragmentation
  • Provides debugging and profiling features

Cons

  • Adds a dependency to Vulkan projects
  • May have a slight performance overhead compared to manual memory management
  • Requires understanding of Vulkan concepts for effective use
  • Limited to Vulkan-based applications

Code Examples

  1. Creating an allocator:
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.physicalDevice = physicalDevice;
allocatorInfo.device = device;
allocatorInfo.instance = instance;

VmaAllocator allocator;
vmaCreateAllocator(&allocatorInfo, &allocator);
  1. Allocating a buffer:
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = 65536;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;

VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
  1. Mapping and unmapping memory:
void* mappedData;
vmaMapMemory(allocator, allocation, &mappedData);
memcpy(mappedData, sourceData, dataSize);
vmaUnmapMemory(allocator, allocation);

Getting Started

  1. Include VMA in your project:

    • Add VulkanMemoryAllocator.h to your include path
    • Include the header in your code: #include "vk_mem_alloc.h"
  2. Create a VMA allocator:

VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.physicalDevice = physicalDevice;
allocatorInfo.device = device;
allocatorInfo.instance = instance;

VmaAllocator allocator;
vmaCreateAllocator(&allocatorInfo, &allocator);
  1. Use VMA functions to allocate and manage memory for your Vulkan resources.

  2. Don't forget to destroy the allocator when you're done:

vmaDestroyAllocator(allocator);

Competitor Comparisons

One stop solution for all Vulkan samples

Pros of Vulkan-Samples

  • Comprehensive collection of Vulkan best practices and techniques
  • Regularly updated with new Vulkan features and optimizations
  • Includes performance profiling and debugging tools

Cons of Vulkan-Samples

  • Larger and more complex codebase, potentially harder to integrate
  • Focuses on demonstrating various Vulkan features rather than specific memory management
  • May include unnecessary components for projects only needing memory allocation

Code Comparison

VulkanMemoryAllocator:

VmaAllocator allocator;
VmaAllocatorCreateInfo allocatorInfo = {};
vmaCreateAllocator(&allocatorInfo, &allocator);

VkBufferCreateInfo bufferInfo = { /* ... */ };
VmaAllocationCreateInfo allocInfo = {};
VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

Vulkan-Samples:

vkb::core::Buffer buffer{
    device,
    buffer_size,
    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
    VMA_MEMORY_USAGE_CPU_TO_GPU
};

void *data = buffer.map();
memcpy(data, &uniform_data, sizeof(uniform_data));
buffer.unmap();

VulkanMemoryAllocator provides a more focused and lightweight approach to memory management, while Vulkan-Samples offers a broader range of Vulkan features and best practices. The choice between them depends on project requirements and scope.

10,152

C++ examples for the Vulkan graphics API

Pros of Vulkan

  • Comprehensive collection of Vulkan examples and demos
  • Covers a wide range of Vulkan features and techniques
  • Includes detailed documentation and explanations for each example

Cons of Vulkan

  • Focuses on examples rather than providing a reusable library
  • May require more effort to integrate into existing projects
  • Not specifically optimized for memory allocation tasks

Code Comparison

VulkanMemoryAllocator:

VmaAllocator allocator;
VmaAllocatorCreateInfo allocatorInfo = {};
vmaCreateAllocator(&allocatorInfo, &allocator);

VkBufferCreateInfo bufferInfo = { /* ... */ };
VmaAllocationCreateInfo allocInfo = {};
VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

Vulkan (SaschaWillems):

VkBufferCreateInfo bufferInfo = { /* ... */ };
VkBuffer buffer;
vkCreateBuffer(device, &bufferInfo, nullptr, &buffer);

VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, buffer, &memRequirements);

VkMemoryAllocateInfo allocInfo = { /* ... */ };
VkDeviceMemory bufferMemory;
vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory);
vkBindBufferMemory(device, buffer, bufferMemory, 0);

The VulkanMemoryAllocator code is more concise and abstracts away memory allocation details, while the Vulkan example demonstrates raw Vulkan API usage for buffer creation and memory allocation.

A beginner-friendly Vulkan path tracing tutorial in under 300 lines of C++.

Pros of vk_mini_path_tracer

  • Focused on path tracing, providing a specific implementation for graphics rendering
  • Includes a complete, self-contained example of a Vulkan-based path tracer
  • Offers educational value for those learning real-time ray tracing techniques

Cons of vk_mini_path_tracer

  • Limited scope, focusing only on path tracing rather than general memory management
  • May require more manual memory management compared to VulkanMemoryAllocator
  • Less flexible for use in diverse Vulkan applications

Code Comparison

VulkanMemoryAllocator:

VmaAllocator allocator;
VmaAllocatorCreateInfo allocatorInfo = {};
vmaCreateAllocator(&allocatorInfo, &allocator);

VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
VmaAllocationCreateInfo allocInfo = {};
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

vk_mini_path_tracer:

VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
VkBuffer buffer;
vkCreateBuffer(device, &bufferInfo, nullptr, &buffer);

VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory);
3,403

A conformant OpenGL ES implementation for Windows, Mac, Linux, iOS and Android.

Pros of ANGLE

  • Cross-platform support for OpenGL ES on top of various graphics APIs (Direct3D, Metal, Vulkan)
  • Extensive testing and wide industry adoption, including use in major browsers
  • Active development with frequent updates and improvements

Cons of ANGLE

  • Larger codebase and potentially higher complexity compared to VulkanMemoryAllocator
  • May introduce some performance overhead due to its abstraction layer
  • Primarily focused on OpenGL ES emulation, which may not be necessary for all projects

Code Comparison

ANGLE (OpenGL ES 2.0 context creation):

EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, NULL, NULL);
eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);

VulkanMemoryAllocator (memory allocation):

VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

While both libraries serve different purposes, this comparison highlights ANGLE's focus on graphics API abstraction and VulkanMemoryAllocator's specialization in Vulkan memory management.

Vulkan Samples

Pros of VulkanSamples

  • Provides a wide range of Vulkan code samples and tutorials
  • Regularly updated with new Vulkan features and best practices
  • Includes cross-platform support for Windows, Linux, and Android

Cons of VulkanSamples

  • Focuses on individual samples rather than a comprehensive memory management solution
  • May require more manual memory management in complex scenarios
  • Less optimized for high-performance applications compared to VulkanMemoryAllocator

Code Comparison

VulkanSamples (basic memory allocation):

VkMemoryAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory);

VulkanMemoryAllocator (simplified allocation):

VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

The VulkanMemoryAllocator code is more concise and abstracts away complex memory management details, while VulkanSamples provides a more direct approach to Vulkan memory allocation.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Vulkan Memory Allocator

Easy to integrate Vulkan memory allocation library.

Documentation: Browse online: Vulkan Memory Allocator (generated from Doxygen-style comments in include/vk_mem_alloc.h)

License: MIT. See LICENSE.txt

Changelog: See CHANGELOG.md

Product page: Vulkan Memory Allocator on GPUOpen

Build status:

  • Windows: Build status
  • Linux: Build Status

Average time to resolve an issue

Problem

Memory allocation and resource (buffer and image) creation in Vulkan is difficult (comparing to older graphics APIs, like D3D11 or OpenGL) for several reasons:

  • It requires a lot of boilerplate code, just like everything else in Vulkan, because it is a low-level and high-performance API.
  • There is additional level of indirection: VkDeviceMemory is allocated separately from creating VkBuffer/VkImage and they must be bound together.
  • Driver must be queried for supported memory heaps and memory types. Different GPU vendors provide different types of it.
  • It is recommended to allocate bigger chunks of memory and assign parts of them to particular resources, as there is a limit on maximum number of memory blocks that can be allocated.

Features

This library can help game developers to manage memory allocations and resource creation by offering some higher-level functions:

  1. Functions that help to choose correct and optimal memory type based on intended usage of the memory.
    • Required or preferred traits of the memory are expressed using higher-level description comparing to Vulkan flags.
  2. Functions that allocate memory blocks, reserve and return parts of them (VkDeviceMemory + offset + size) to the user.
    • Library keeps track of allocated memory blocks, used and unused ranges inside them, finds best matching unused ranges for new allocations, respects all the rules of alignment and buffer/image granularity.
  3. Functions that can create an image/buffer, allocate memory for it and bind them together - all in one call.

Additional features:

  • Well-documented - description of all functions and structures provided, along with chapters that contain general description and example code.
  • Thread-safety: Library is designed to be used in multithreaded code. Access to a single device memory block referred by different buffers and textures (binding, mapping) is synchronized internally. Memory mapping is reference-counted.
  • Configuration: Fill optional members of VmaAllocatorCreateInfo structure to provide custom CPU memory allocator, pointers to Vulkan functions and other parameters.
  • Customization and integration with custom engines: Predefine appropriate macros to provide your own implementation of all external facilities used by the library like assert, mutex, atomic.
  • Support for memory mapping, reference-counted internally. Support for persistently mapped memory: Just allocate with appropriate flag and access the pointer to already mapped memory.
  • Support for non-coherent memory. Functions that flush/invalidate memory. nonCoherentAtomSize is respected automatically.
  • Support for resource aliasing (overlap).
  • Support for sparse binding and sparse residency: Convenience functions that allocate or free multiple memory pages at once.
  • Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size) and allocate memory out of it.
  • Linear allocator: Create a pool with linear algorithm and use it for much faster allocations and deallocations in free-at-once, stack, double stack, or ring buffer fashion.
  • Support for Vulkan 1.0, 1.1, 1.2, 1.3.
  • Support for extensions (and equivalent functionality included in new Vulkan versions):
    • VK_KHR_dedicated_allocation: Just enable it and it will be used automatically by the library.
    • VK_KHR_bind_memory2.
    • VK_KHR_maintenance4.
    • VK_KHR_maintenance5, including VkBufferUsageFlags2CreateInfoKHR.
    • VK_EXT_memory_budget: Used internally if available to query for current usage and budget. If not available, it falls back to an estimation based on memory heap sizes.
    • VK_KHR_buffer_device_address: Flag VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR is automatically added to memory allocations where needed.
    • VK_EXT_memory_priority: Set priority of allocations or custom pools and it will be set automatically using this extension.
    • VK_AMD_device_coherent_memory.
    • VK_KHR_external_memory_win32.
  • Defragmentation of GPU and CPU memory: Let the library move data around to free some memory blocks and make your allocations better compacted.
  • Statistics: Obtain brief or detailed statistics about the amount of memory used, unused, number of allocated blocks, number of allocations etc. - globally, per memory heap, and per memory type.
  • Debug annotations: Associate custom void* pUserData and debug char* pName with each allocation.
  • JSON dump: Obtain a string in JSON format with detailed map of internal state, including list of allocations, their string names, and gaps between them.
  • Convert this JSON dump into a picture to visualize your memory. See tools/GpuMemDumpVis.
  • Debugging incorrect memory usage: Enable initialization of all allocated memory with a bit pattern to detect usage of uninitialized or freed memory. Enable validation of a magic number after every allocation to detect out-of-bounds memory corruption.
  • Support for interoperability with OpenGL.
  • Virtual allocator: Interface for using core allocation algorithm to allocate any custom data, e.g. pieces of one large buffer.

Prerequisites

  • Self-contained C++ library in single header file. No external dependencies other than standard C and C++ library and of course Vulkan. Some features of C++14 used. STL containers, RTTI, or C++ exceptions are not used.
  • Public interface in C, in same convention as Vulkan API. Implementation in C++.
  • Error handling implemented by returning VkResult error codes - same way as in Vulkan.
  • Interface documented using Doxygen-style comments.
  • Platform-independent, but developed and tested on Windows using Visual Studio. Continuous integration setup for Windows and Linux. Used also on Android, MacOS, and other platforms.

Example

Basic usage of this library is very simple. Advanced features are optional. After you created global VmaAllocator object, a complete code needed to create a buffer may look like this:

VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = 65536;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;

VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_AUTO;

VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

With this one function call:

  1. VkBuffer is created.
  2. VkDeviceMemory block is allocated if needed.
  3. An unused region of the memory block is bound to this buffer.

VmaAllocation is an object that represents memory assigned to this buffer. It can be queried for parameters like VkDeviceMemory handle and offset.

How to build

On Windows it is recommended to use CMake GUI.

Alternatively you can generate/open a Visual Studio from the command line:

# By default CMake picks the newest version of Visual Studio it can use
cmake -S .  -B build -D VMA_BUILD_SAMPLES=ON
cmake --open build

On Linux:

cmake -S . -B build
# Since VMA has no source files, you can skip to installation immediately
cmake --install build --prefix build/install

How to use

After calling either find_package or add_subdirectory simply link the library. This automatically handles configuring the include directory. Example:

find_package(VulkanMemoryAllocator CONFIG REQUIRED)
target_link_libraries(YourGameEngine PRIVATE GPUOpen::VulkanMemoryAllocator)

For more info on using CMake visit the official CMake documentation.

Building using vcpkg

You can download and install VulkanMemoryAllocator using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install vulkan-memory-allocator

The VulkanMemoryAllocator port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Binaries

The release comes with precompiled binary executable for "VulkanSample" application which contains test suite. It is compiled using Visual Studio 2022, so it requires appropriate libraries to work, including "MSVCP140.dll", "VCRUNTIME140.dll", "VCRUNTIME140_1.dll". If the launch fails with error message telling about those files missing, please download and install Microsoft Visual C++ Redistributable, "X64" version.

Read more

See Documentation.

Software using this library

Many other projects on GitHub and some game development studios that use Vulkan in their games.

See also

  • D3D12 Memory Allocator - equivalent library for Direct3D 12. License: MIT.
  • Awesome Vulkan - a curated list of awesome Vulkan libraries, debuggers and resources.
  • vcpkg dependency manager from Microsoft also offers a port of this library.
  • VulkanMemoryAllocator-Hpp - C++ binding for this library. License: CC0-1.0.
  • PyVMA - Python wrapper for this library. Author: Jean-Sébastien B. (@realitix). License: Apache 2.0.
  • vk-mem - Rust binding for this library. Author: Graham Wihlidal. License: Apache 2.0 or MIT.
  • Haskell bindings, github - Haskell bindings for this library. Author: Ellie Hermaszewska (@expipiplus1). License BSD-3-Clause.
  • vma_sample_sdl - SDL port of the sample app of this library (with the goal of running it on multiple platforms, including MacOS). Author: @rextimmy. License: MIT.
  • vulkan-malloc - Vulkan memory allocation library for Rust. Based on version 1 of this library. Author: Dylan Ede (@dylanede). License: MIT / Apache 2.0.