From 871913da6a4b132b567d7b65c509600363c0041e Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Thu, 18 Jul 2024 11:00:01 +0200 Subject: [PATCH] Updated documentation - mentioned VMA_LEAK_LOG_FORMAT See #437 --- docs/html/allocation_annotation.html | 12 ++-- docs/html/choosing_memory_type.html | 20 +++--- docs/html/configuration.html | 9 ++- docs/html/custom_memory_pools.html | 16 ++--- docs/html/defragmentation.html | 22 +++--- docs/html/memory_mapping.html | 16 ++--- docs/html/quick_start.html | 22 +++--- docs/html/resource_aliasing.html | 4 +- docs/html/usage_patterns.html | 81 +++++++++++++++++----- docs/html/virtual_allocator.html | 20 +++--- docs/html/vk_ext_memory_priority.html | 12 ++-- docs/html/vk_khr_dedicated_allocation.html | 2 +- include/vk_mem_alloc.h | 12 +++- 13 files changed, 152 insertions(+), 96 deletions(-) diff --git a/docs/html/allocation_annotation.html b/docs/html/allocation_annotation.html index a068ad3..e1bb2ee 100644 --- a/docs/html/allocation_annotation.html +++ b/docs/html/allocation_annotation.html @@ -93,18 +93,18 @@ Allocation user data
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buffer, &allocation, nullptr);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Creates a new VkBuffer, allocates and binds memory for it.
-
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:527
-
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1263
-
void * pUserData
Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...
Definition vk_mem_alloc.h:1302
-
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1271
+
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:529
+
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1265
+
void * pUserData
Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...
Definition vk_mem_alloc.h:1304
+
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1273
Represents single memory allocation.

The pointer may be later retrieved as VmaAllocationInfo::pUserData:

vmaGetAllocationInfo(allocator, allocation, &allocInfo);
MyBufferMetadata* pMetadata = (MyBufferMetadata*)allocInfo.pUserData;
void vmaGetAllocationInfo(VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo *pAllocationInfo)
Returns current information about specified allocation.
-
Definition vk_mem_alloc.h:1382
-
void * pUserData
Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...
Definition vk_mem_alloc.h:1429
+
Definition vk_mem_alloc.h:1384
+
void * pUserData
Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...
Definition vk_mem_alloc.h:1431

It can also be changed using function vmaSetAllocationUserData().

Values of (non-zero) allocations' pUserData are printed in JSON report created by vmaBuildStatsString() in hexadecimal form.

diff --git a/docs/html/choosing_memory_type.html b/docs/html/choosing_memory_type.html index bb61e67..9164287 100644 --- a/docs/html/choosing_memory_type.html +++ b/docs/html/choosing_memory_type.html @@ -103,9 +103,9 @@ Usage

VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Creates a new VkBuffer, allocates and binds memory for it.
-
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:527
-
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1263
-
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1271
+
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:529
+
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1265
+
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1273
Represents single memory allocation.

If you have a preference for putting the resource in GPU (device) memory or CPU (host) memory on systems with discrete graphics card that have the memories separate, you can use VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE or VMA_MEMORY_USAGE_AUTO_PREFER_HOST.

When using VMA_MEMORY_USAGE_AUTO* while you want to map the allocated memory, you also need to specify one of the host access flags: VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT. This will help the library decide about preferred memory type to ensure it has VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT so you can map it.

@@ -121,8 +121,8 @@ Usage
VkBuffer stagingBuffer;
VmaAllocation stagingAllocation;
vmaCreateBuffer(allocator, &stagingBufferInfo, &stagingAllocInfo, &stagingBuffer, &stagingAllocation, nullptr);
-
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition vk_mem_alloc.h:636
-
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition vk_mem_alloc.h:1265
+
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition vk_mem_alloc.h:638
+
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition vk_mem_alloc.h:1267

For more examples of creating different kinds of resources, see chapter Recommended usage patterns. See also: Memory mapping.

Usage values VMA_MEMORY_USAGE_AUTO* are legal to use only when the library knows about the resource being created by having VkBufferCreateInfo / VkImageCreateInfo passed, so they work with functions like: vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo() etc. If you allocate raw memory using function vmaAllocateMemory(), you have to use other means of selecting memory type, as described below.

Note
Old usage values (VMA_MEMORY_USAGE_GPU_ONLY, VMA_MEMORY_USAGE_CPU_ONLY, VMA_MEMORY_USAGE_CPU_TO_GPU, VMA_MEMORY_USAGE_GPU_TO_CPU, VMA_MEMORY_USAGE_CPU_COPY) are still available and work same way as in previous versions of the library for backward compatibility, but they are deprecated.
@@ -137,10 +137,10 @@ Required and preferred flags
VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
-
@ VMA_ALLOCATION_CREATE_MAPPED_BIT
Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
Definition vk_mem_alloc.h:587
-
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
Definition vk_mem_alloc.h:648
-
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition vk_mem_alloc.h:1281
-
VkMemoryPropertyFlags requiredFlags
Flags that must be set in a Memory Type chosen for an allocation.
Definition vk_mem_alloc.h:1276
+
@ VMA_ALLOCATION_CREATE_MAPPED_BIT
Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
Definition vk_mem_alloc.h:589
+
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
Definition vk_mem_alloc.h:650
+
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition vk_mem_alloc.h:1283
+
VkMemoryPropertyFlags requiredFlags
Flags that must be set in a Memory Type chosen for an allocation.
Definition vk_mem_alloc.h:1278

A memory type is chosen that has all the required flags and as many preferred flags set as possible.

Value passed in VmaAllocationCreateInfo::usage is internally converted to a set of required and preferred flags, plus some extra "magic" (heuristics).

@@ -155,7 +155,7 @@ Explicit memory types

VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
-
uint32_t memoryTypeBits
Bitmask containing one bit set for every memory type acceptable for this allocation.
Definition vk_mem_alloc.h:1289
+
uint32_t memoryTypeBits
Bitmask containing one bit set for every memory type acceptable for this allocation.
Definition vk_mem_alloc.h:1291

You can also use this parameter to exclude some memory types. If you inspect memory heaps and types available on the current physical device and you determine that for some reason you don't want to use a specific memory type for the allocation, you can enable automatic memory type selection but exclude certain memory type or types by setting all bits of memoryTypeBits to 1 except the ones you choose.

// ...
uint32_t excludedMemoryTypeIndex = 2;
diff --git a/docs/html/configuration.html b/docs/html/configuration.html index 90ccaa4..5a864b5 100644 --- a/docs/html/configuration.html +++ b/docs/html/configuration.html @@ -78,9 +78,14 @@ $(function() {
Configuration
-

Please check "CONFIGURATION SECTION" in the code to find macros that you can define before each include of this file or change directly in this file to provide your own implementation of basic facilities like assert, min() and max() functions, mutex, atomic etc. The library uses its own implementation of containers by default, but you can switch to using STL containers instead.

+

Please check "CONFIGURATION SECTION" in the code to find macros that you can define before each include of this file or change directly in this file to provide your own implementation of basic facilities like assert, min() and max() functions, mutex, atomic etc.

For example, define VMA_ASSERT(expr) before including the library to provide custom implementation of the assertion, compatible with your project. By default it is defined to standard C assert(expr) in _DEBUG configuration and empty otherwise.

-

+

Similarly, you can define VMA_LEAK_LOG_FORMAT macro to enable printing of leaked (unfreed) allocations, including their names and other parameters. Example:

+
#define VMA_LEAK_LOG_FORMAT(format, ...) do { \
+
printf((format), __VA_ARGS__); \
+
printf("\n"); \
+
} while(false)
+

Pointers to Vulkan functions

There are multiple ways to import pointers to Vulkan functions in the library. In the simplest case you don't need to do anything. If the compilation or linking of your program or the initialization of the VmaAllocator doesn't work for you, you can try to reconfigure it.

First, the allocator tries to fetch pointers to Vulkan functions linked statically, like this:

diff --git a/docs/html/custom_memory_pools.html b/docs/html/custom_memory_pools.html index 805f019..90180cd 100644 --- a/docs/html/custom_memory_pools.html +++ b/docs/html/custom_memory_pools.html @@ -133,15 +133,15 @@ $(function() {
VkResult vmaCreatePool(VmaAllocator allocator, const VmaPoolCreateInfo *pCreateInfo, VmaPool *pPool)
Allocates Vulkan device memory and creates VmaPool object.
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Creates a new VkBuffer, allocates and binds memory for it.
VkResult vmaFindMemoryTypeIndexForBufferInfo(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)
Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.
-
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:527
-
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1263
-
VmaPool pool
Pool that this allocation should be created in.
Definition vk_mem_alloc.h:1295
-
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1271
+
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:529
+
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1265
+
VmaPool pool
Pool that this allocation should be created in.
Definition vk_mem_alloc.h:1297
+
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1273
Represents single memory allocation.
-
Describes parameter of created VmaPool.
Definition vk_mem_alloc.h:1314
-
uint32_t memoryTypeIndex
Vulkan memory type index to allocate this pool from.
Definition vk_mem_alloc.h:1317
-
VkDeviceSize blockSize
Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes....
Definition vk_mem_alloc.h:1330
-
size_t maxBlockCount
Maximum number of blocks that can be allocated in this pool. Optional.
Definition vk_mem_alloc.h:1343
+
Describes parameter of created VmaPool.
Definition vk_mem_alloc.h:1316
+
uint32_t memoryTypeIndex
Vulkan memory type index to allocate this pool from.
Definition vk_mem_alloc.h:1319
+
VkDeviceSize blockSize
Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes....
Definition vk_mem_alloc.h:1332
+
size_t maxBlockCount
Maximum number of blocks that can be allocated in this pool. Optional.
Definition vk_mem_alloc.h:1345
Represents custom memory pool.

You have to free all allocations made from this pool before destroying it.

vmaDestroyBuffer(allocator, buf, alloc);
diff --git a/docs/html/defragmentation.html b/docs/html/defragmentation.html index e690e15..244264c 100644 --- a/docs/html/defragmentation.html +++ b/docs/html/defragmentation.html @@ -143,18 +143,18 @@ $(function() {
VkResult vmaBeginDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)
Starts single defragmentation pass.
VkResult vmaBeginDefragmentation(VmaAllocator allocator, const VmaDefragmentationInfo *pInfo, VmaDefragmentationContext *pContext)
Begins defragmentation process.
VkResult vmaEndDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)
Ends single defragmentation pass.
-
@ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT
Definition vk_mem_alloc.h:744
-
Definition vk_mem_alloc.h:1382
-
void * pUserData
Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...
Definition vk_mem_alloc.h:1429
+
@ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT
Definition vk_mem_alloc.h:746
+
Definition vk_mem_alloc.h:1384
+
void * pUserData
Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...
Definition vk_mem_alloc.h:1431
An opaque object that represents started defragmentation process.
-
Parameters for defragmentation.
Definition vk_mem_alloc.h:1472
-
VmaPool pool
Custom pool to be defragmented.
Definition vk_mem_alloc.h:1479
-
VmaDefragmentationFlags flags
Use combination of VmaDefragmentationFlagBits.
Definition vk_mem_alloc.h:1474
-
VmaAllocation srcAllocation
Allocation that should be moved.
Definition vk_mem_alloc.h:1505
-
VmaAllocation dstTmpAllocation
Temporary allocation pointing to destination memory that will replace srcAllocation.
Definition vk_mem_alloc.h:1512
-
Parameters for incremental defragmentation steps.
Definition vk_mem_alloc.h:1520
-
uint32_t moveCount
Number of elements in the pMoves array.
Definition vk_mem_alloc.h:1522
-
VmaDefragmentationMove * pMoves
Array of moves to be performed by the user in the current defragmentation pass.
Definition vk_mem_alloc.h:1546
+
Parameters for defragmentation.
Definition vk_mem_alloc.h:1474
+
VmaPool pool
Custom pool to be defragmented.
Definition vk_mem_alloc.h:1481
+
VmaDefragmentationFlags flags
Use combination of VmaDefragmentationFlagBits.
Definition vk_mem_alloc.h:1476
+
VmaAllocation srcAllocation
Allocation that should be moved.
Definition vk_mem_alloc.h:1507
+
VmaAllocation dstTmpAllocation
Temporary allocation pointing to destination memory that will replace srcAllocation.
Definition vk_mem_alloc.h:1514
+
Parameters for incremental defragmentation steps.
Definition vk_mem_alloc.h:1522
+
uint32_t moveCount
Number of elements in the pMoves array.
Definition vk_mem_alloc.h:1524
+
VmaDefragmentationMove * pMoves
Array of moves to be performed by the user in the current defragmentation pass.
Definition vk_mem_alloc.h:1548

Although functions like vmaCreateBuffer(), vmaCreateImage(), vmaDestroyBuffer(), vmaDestroyImage() create/destroy an allocation and a buffer/image at once, these are just a shortcut for creating the resource, allocating memory, and binding them together. Defragmentation works on memory allocations only. You must handle the rest manually. Defragmentation is an iterative process that should repreat "passes" as long as related functions return VK_INCOMPLETE not VK_SUCCESS. In each pass:

  1. vmaBeginDefragmentationPass() function call:
      diff --git a/docs/html/memory_mapping.html b/docs/html/memory_mapping.html index ca18df6..961bd7d 100644 --- a/docs/html/memory_mapping.html +++ b/docs/html/memory_mapping.html @@ -105,11 +105,11 @@ Copy functions
      vmaCopyMemoryToAllocation(allocator, &constantBufferData, alloc, 0, sizeof(ConstantBuffer));
      VkResult vmaCopyMemoryToAllocation(VmaAllocator allocator, const void *pSrcHostPointer, VmaAllocation dstAllocation, VkDeviceSize dstAllocationLocalOffset, VkDeviceSize size)
      Maps the allocation temporarily if needed, copies data from specified host pointer to it,...
      VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
      Creates a new VkBuffer, allocates and binds memory for it.
      -
      @ VMA_MEMORY_USAGE_AUTO
      Definition vk_mem_alloc.h:527
      -
      @ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
      Definition vk_mem_alloc.h:636
      -
      Parameters of new VmaAllocation.
      Definition vk_mem_alloc.h:1263
      -
      VmaMemoryUsage usage
      Intended usage of memory.
      Definition vk_mem_alloc.h:1271
      -
      VmaAllocationCreateFlags flags
      Use VmaAllocationCreateFlagBits enum.
      Definition vk_mem_alloc.h:1265
      +
      @ VMA_MEMORY_USAGE_AUTO
      Definition vk_mem_alloc.h:529
      +
      @ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
      Definition vk_mem_alloc.h:638
      +
      Parameters of new VmaAllocation.
      Definition vk_mem_alloc.h:1265
      +
      VmaMemoryUsage usage
      Intended usage of memory.
      Definition vk_mem_alloc.h:1273
      +
      VmaAllocationCreateFlags flags
      Use VmaAllocationCreateFlagBits enum.
      Definition vk_mem_alloc.h:1267
      Represents single memory allocation.

Copy in the other direction - from an allocation to a host pointer can be performed the same way using function vmaCopyAllocationToMemory().

@@ -156,9 +156,9 @@ Persistently mapped memory

// Buffer is already mapped. You can access its memory.
memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData));
-
@ VMA_ALLOCATION_CREATE_MAPPED_BIT
Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
Definition vk_mem_alloc.h:587
-
Definition vk_mem_alloc.h:1382
-
void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition vk_mem_alloc.h:1424
+
@ VMA_ALLOCATION_CREATE_MAPPED_BIT
Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
Definition vk_mem_alloc.h:589
+
Definition vk_mem_alloc.h:1384
+
void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition vk_mem_alloc.h:1426
Note
VMA_ALLOCATION_CREATE_MAPPED_BIT by itself doesn't guarantee that the allocation will end up in a mappable memory type. For this, you need to also specify VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT. VMA_ALLOCATION_CREATE_MAPPED_BIT only guarantees that if the memory is HOST_VISIBLE, the allocation will be mapped on creation. For an example of how to make use of this fact, see section Advanced data uploading.

Cache flush and invalidate

diff --git a/docs/html/quick_start.html b/docs/html/quick_start.html index d7e916b..585fbc8 100644 --- a/docs/html/quick_start.html +++ b/docs/html/quick_start.html @@ -182,14 +182,14 @@ Enabling extensions
vmaDestroyAllocator(allocator);
VkResult vmaCreateAllocator(const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
Creates VmaAllocator object.
void vmaDestroyAllocator(VmaAllocator allocator)
Destroys allocator object.
-
@ VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
Definition vk_mem_alloc.h:393
-
Description of a Allocator to be created.
Definition vk_mem_alloc.h:1040
-
VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition vk_mem_alloc.h:1045
-
VmaAllocatorCreateFlags flags
Flags for created allocator. Use VmaAllocatorCreateFlagBits enum.
Definition vk_mem_alloc.h:1042
-
const VmaVulkanFunctions * pVulkanFunctions
Pointers to Vulkan functions. Can be null.
Definition vk_mem_alloc.h:1088
-
VkInstance instance
Handle to Vulkan instance object.
Definition vk_mem_alloc.h:1093
-
VkDevice device
Vulkan device.
Definition vk_mem_alloc.h:1048
-
uint32_t vulkanApiVersion
Optional. Vulkan version that the application uses.
Definition vk_mem_alloc.h:1104
+
@ VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
Definition vk_mem_alloc.h:395
+
Description of a Allocator to be created.
Definition vk_mem_alloc.h:1042
+
VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition vk_mem_alloc.h:1047
+
VmaAllocatorCreateFlags flags
Flags for created allocator. Use VmaAllocatorCreateFlagBits enum.
Definition vk_mem_alloc.h:1044
+
const VmaVulkanFunctions * pVulkanFunctions
Pointers to Vulkan functions. Can be null.
Definition vk_mem_alloc.h:1090
+
VkInstance instance
Handle to Vulkan instance object.
Definition vk_mem_alloc.h:1095
+
VkDevice device
Vulkan device.
Definition vk_mem_alloc.h:1050
+
uint32_t vulkanApiVersion
Optional. Vulkan version that the application uses.
Definition vk_mem_alloc.h:1106
Represents main object of this library initialized.

Other configuration options

@@ -213,9 +213,9 @@ Resource allocation
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Creates a new VkBuffer, allocates and binds memory for it.
-
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:527
-
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1263
-
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1271
+
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:529
+
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1265
+
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1273
Represents single memory allocation.

Don't forget to destroy your buffer and allocation objects when no longer needed:

vmaDestroyBuffer(allocator, buffer, allocation);
diff --git a/docs/html/resource_aliasing.html b/docs/html/resource_aliasing.html index 3304333..5a4cbb0 100644 --- a/docs/html/resource_aliasing.html +++ b/docs/html/resource_aliasing.html @@ -149,8 +149,8 @@ $(function() {
VkResult vmaBindImageMemory(VmaAllocator allocator, VmaAllocation allocation, VkImage image)
Binds image to allocation.
void vmaFreeMemory(VmaAllocator allocator, const VmaAllocation allocation)
Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(),...
VkResult vmaAllocateMemory(VmaAllocator allocator, const VkMemoryRequirements *pVkMemoryRequirements, const VmaAllocationCreateInfo *pCreateInfo, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
General purpose memory allocation.
-
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1263
-
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition vk_mem_alloc.h:1281
+
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1265
+
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition vk_mem_alloc.h:1283
Represents single memory allocation.

VMA also provides convenience functions that create a buffer or image and bind it to memory represented by an existing VmaAllocation: vmaCreateAliasingBuffer(), vmaCreateAliasingBuffer2(), vmaCreateAliasingImage(), vmaCreateAliasingImage2(). Versions with "2" offer additional parameter allocationLocalOffset.

Remember that using resources that alias in memory requires proper synchronization. You need to issue a memory barrier to make sure commands that use img1 and img2 don't overlap on GPU timeline. You also need to treat a resource after aliasing as uninitialized - containing garbage data. For example, if you use img1 and then want to use img2, you need to issue an image memory barrier for img2 with oldLayout = VK_IMAGE_LAYOUT_UNDEFINED.

diff --git a/docs/html/usage_patterns.html b/docs/html/usage_patterns.html index 2bcee80..5381c6f 100644 --- a/docs/html/usage_patterns.html +++ b/docs/html/usage_patterns.html @@ -106,12 +106,12 @@ GPU-only resource
VmaAllocation alloc;
vmaCreateImage(allocator, &imgCreateInfo, &allocCreateInfo, &img, &alloc, nullptr);
VkResult vmaCreateImage(VmaAllocator allocator, const VkImageCreateInfo *pImageCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkImage *pImage, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Function similar to vmaCreateBuffer().
-
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:527
-
@ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
Set this flag if the allocation should have its own memory block.
Definition vk_mem_alloc.h:566
-
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1263
-
float priority
A floating-point value between 0 and 1, indicating the priority of the allocation relative to other m...
Definition vk_mem_alloc.h:1309
-
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1271
-
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition vk_mem_alloc.h:1265
+
@ VMA_MEMORY_USAGE_AUTO
Definition vk_mem_alloc.h:529
+
@ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
Set this flag if the allocation should have its own memory block.
Definition vk_mem_alloc.h:568
+
Parameters of new VmaAllocation.
Definition vk_mem_alloc.h:1265
+
float priority
A floating-point value between 0 and 1, indicating the priority of the allocation relative to other m...
Definition vk_mem_alloc.h:1311
+
VmaMemoryUsage usage
Intended usage of memory.
Definition vk_mem_alloc.h:1273
+
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition vk_mem_alloc.h:1267
Represents single memory allocation.

Also consider: Consider creating them as dedicated allocations using VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, especially if they are large or if you plan to destroy and recreate them with different sizes e.g. when display resolution changes. Prefer to create such resources first and all other GPU resources (like textures and vertex buffers) later. When VK_EXT_memory_priority extension is enabled, it is also worth setting high priority to such allocation to decrease chances to be evicted to system memory by the operating system.

@@ -136,10 +136,10 @@ Staging copy for upload

memcpy(allocInfo.pMappedData, myData, myDataSize);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Creates a new VkBuffer, allocates and binds memory for it.
-
@ VMA_ALLOCATION_CREATE_MAPPED_BIT
Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
Definition vk_mem_alloc.h:587
-
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition vk_mem_alloc.h:636
-
Definition vk_mem_alloc.h:1382
-
void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition vk_mem_alloc.h:1424
+
@ VMA_ALLOCATION_CREATE_MAPPED_BIT
Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
Definition vk_mem_alloc.h:589
+
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition vk_mem_alloc.h:638
+
Definition vk_mem_alloc.h:1384
+
void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition vk_mem_alloc.h:1426

Also consider: You can map the allocation using vmaMapMemory() or you can create it as persistenly mapped using VMA_ALLOCATION_CREATE_MAPPED_BIT, as in the example above.

Readback

@@ -162,7 +162,7 @@ Readback
...
const float* downloadedData = (const float*)allocInfo.pMappedData;
-
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
Definition vk_mem_alloc.h:648
+
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
Definition vk_mem_alloc.h:650

Advanced data uploading

For resources that you frequently write on CPU via mapped pointer and frequently read on GPU e.g. as a uniform buffer (also called "dynamic"), multiple options are possible:

@@ -192,7 +192,8 @@ Advanced data uploading
VkBuffer buf;
VmaAllocation alloc;
VmaAllocationInfo allocInfo;
-
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
+
VkResult result = vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
+
// Check result...
VkMemoryPropertyFlags memPropFlags;
vmaGetAllocationMemoryProperties(allocator, alloc, &memPropFlags);
@@ -203,10 +204,24 @@ Advanced data uploading
// [Executed in runtime]:
memcpy(allocInfo.pMappedData, myData, myDataSize);
+
result = vmaFlushAllocation(allocator, alloc, 0, VK_WHOLE_SIZE);
+
// Check result...
+
+
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
+
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
+
bufMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
+
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+
bufMemBarrier.buffer = buf;
+
bufMemBarrier.offset = 0;
+
bufMemBarrier.size = VK_WHOLE_SIZE;
+
+
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
+
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
}
else
{
-
// Allocation ended up in a non-mappable memory - need to transfer.
+
// Allocation ended up in a non-mappable memory - a transfer using a staging buffer is required.
VkBufferCreateInfo stagingBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
stagingBufCreateInfo.size = 65536;
stagingBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
@@ -219,22 +234,50 @@ Advanced data uploading
VkBuffer stagingBuf;
VmaAllocation stagingAlloc;
VmaAllocationInfo stagingAllocInfo;
-
vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
-
&stagingBuf, &stagingAlloc, stagingAllocInfo);
+
result = vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
+
&stagingBuf, &stagingAlloc, &stagingAllocInfo);
+
// Check result...
// [Executed in runtime]:
memcpy(stagingAllocInfo.pMappedData, myData, myDataSize);
-
vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
-
//vkCmdPipelineBarrier: VK_ACCESS_HOST_WRITE_BIT --> VK_ACCESS_TRANSFER_READ_BIT
+
result = vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
+
// Check result...
+
+
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
+
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
+
bufMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+
bufMemBarrier.buffer = stagingBuf;
+
bufMemBarrier.offset = 0;
+
bufMemBarrier.size = VK_WHOLE_SIZE;
+
+
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
+
VkBufferCopy bufCopy = {
0, // srcOffset
0, // dstOffset,
-
myDataSize); // size
+
myDataSize, // size
+
};
+
vkCmdCopyBuffer(cmdBuf, stagingBuf, buf, 1, &bufCopy);
+
+
VkBufferMemoryBarrier bufMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
+
bufMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+
bufMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // We created a uniform buffer
+
bufMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+
bufMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+
bufMemBarrier2.buffer = buf;
+
bufMemBarrier2.offset = 0;
+
bufMemBarrier2.size = VK_WHOLE_SIZE;
+
+
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
+
0, 0, nullptr, 1, &bufMemBarrier2, 0, nullptr);
}
VkResult vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size)
Flushes memory of given allocation.
void vmaGetAllocationMemoryProperties(VmaAllocator allocator, VmaAllocation allocation, VkMemoryPropertyFlags *pFlags)
Given an allocation, returns Property Flags of its memory type.
-
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT
Definition vk_mem_alloc.h:660
+
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT
Definition vk_mem_alloc.h:662

Other use cases

Here are some other, less obvious use cases and their recommended settings:

diff --git a/docs/html/virtual_allocator.html b/docs/html/virtual_allocator.html index 6a34cc3..3b065f6 100644 --- a/docs/html/virtual_allocator.html +++ b/docs/html/virtual_allocator.html @@ -93,8 +93,8 @@ Creating virtual block
VmaVirtualBlock block;
VkResult res = vmaCreateVirtualBlock(&blockCreateInfo, &block);
VkResult vmaCreateVirtualBlock(const VmaVirtualBlockCreateInfo *pCreateInfo, VmaVirtualBlock *pVirtualBlock)
Creates new VmaVirtualBlock object.
-
Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().
Definition vk_mem_alloc.h:1571
-
VkDeviceSize size
Total size of the virtual block.
Definition vk_mem_alloc.h:1577
+
Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().
Definition vk_mem_alloc.h:1573
+
VkDeviceSize size
Total size of the virtual block.
Definition vk_mem_alloc.h:1579
Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...

Making virtual allocations

@@ -120,8 +120,8 @@ Making virtual allocations
// Allocation failed - no space for it could be found. Handle this error!
}
VkResult vmaVirtualAllocate(VmaVirtualBlock virtualBlock, const VmaVirtualAllocationCreateInfo *pCreateInfo, VmaVirtualAllocation *pAllocation, VkDeviceSize *pOffset)
Allocates new virtual allocation inside given VmaVirtualBlock.
-
Parameters of created virtual allocation to be passed to vmaVirtualAllocate().
Definition vk_mem_alloc.h:1592
-
VkDeviceSize size
Size of the allocation.
Definition vk_mem_alloc.h:1597
+
Parameters of created virtual allocation to be passed to vmaVirtualAllocate().
Definition vk_mem_alloc.h:1594
+
VkDeviceSize size
Size of the allocation.
Definition vk_mem_alloc.h:1599
Represents single memory allocation done inside VmaVirtualBlock.

Deallocation

@@ -149,8 +149,8 @@ Allocation parameters
vmaVirtualFree(block, alloc);
void vmaGetVirtualAllocationInfo(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VmaVirtualAllocationInfo *pVirtualAllocInfo)
Returns information about a specific virtual allocation within a virtual block, like its size and pUs...
-
Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().
Definition vk_mem_alloc.h:1615
-
void * pUserData
Custom pointer associated with the allocation.
Definition vk_mem_alloc.h:1630
+
Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().
Definition vk_mem_alloc.h:1617
+
void * pUserData
Custom pointer associated with the allocation.
Definition vk_mem_alloc.h:1632

Alignment and units

It feels natural to express sizes and offsets in bytes. If an offset of an allocation needs to be aligned to a multiply of some number (e.g. 4 bytes), you can fill optional member VmaVirtualAllocationCreateInfo::alignment to request it. Example:

@@ -160,7 +160,7 @@ Alignment and units
VmaVirtualAllocation alloc;
res = vmaVirtualAllocate(block, &allocCreateInfo, &alloc, nullptr);
-
VkDeviceSize alignment
Required alignment of the allocation. Optional.
Definition vk_mem_alloc.h:1602
+
VkDeviceSize alignment
Required alignment of the allocation. Optional.
Definition vk_mem_alloc.h:1604

Alignments of different allocations made from one block may vary. However, if all alignments and sizes are always multiply of some size e.g. 4 B or sizeof(MyDataStruct), you can express all sizes, alignments, and offsets in multiples of that size instead of individual bytes. It might be more convenient, but you need to make sure to use this new unit consistently in all the places: