diff --git a/docs/html/allocation_annotation.html b/docs/html/allocation_annotation.html
index 206fac9..b729345 100644
--- a/docs/html/allocation_annotation.html
+++ b/docs/html/allocation_annotation.html
@@ -86,17 +86,17 @@ Allocation user data
vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation,
nullptr);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
@ VMA_MEMORY_USAGE_GPU_ONLY
Definition: vk_mem_alloc.h:466
-Definition: vk_mem_alloc.h:1118
-void * pUserData
Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...
Definition: vk_mem_alloc.h:1157
-VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1126
+Definition: vk_mem_alloc.h:1116
+void * pUserData
Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...
Definition: vk_mem_alloc.h:1155
+VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1124
Represents single memory allocation.
The pointer may be later retrieved as VmaAllocationInfo::pUserData:
MyBufferMetadata* pMetadata = (MyBufferMetadata*)allocInfo.
pUserData;
void vmaGetAllocationInfo(VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo *pAllocationInfo)
Returns current information about specified allocation.
-
Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1260
-
void * pUserData
Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...
Definition: vk_mem_alloc.h:1307
+
Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1258
+
void * pUserData
Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...
Definition: vk_mem_alloc.h:1305
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.
@@ -118,7 +118,7 @@ Allocation names
vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &image, &allocation,
nullptr);
VkResult vmaCreateImage(VmaAllocator allocator, const VkImageCreateInfo *pImageCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkImage *pImage, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
Function similar to vmaCreateBuffer().
@ VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT
Definition: vk_mem_alloc.h:550
-VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1120
+VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1118
The value of pUserData
pointer of the allocation will be different than the one you passed when setting allocation's name - pointing to a buffer managed internally that holds copy of the string.
diff --git a/docs/html/choosing_memory_type.html b/docs/html/choosing_memory_type.html
index bc597fc..d1fb65c 100644
--- a/docs/html/choosing_memory_type.html
+++ b/docs/html/choosing_memory_type.html
@@ -95,8 +95,8 @@ Usage
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation,
nullptr);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
@ VMA_MEMORY_USAGE_GPU_ONLY
Definition: vk_mem_alloc.h:466
-
Definition: vk_mem_alloc.h:1118
-
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1126
+
Definition: vk_mem_alloc.h:1116
+
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1124
Represents single memory allocation.
Required and preferred flags
@@ -110,9 +110,9 @@ Required and preferred flags
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:540
-VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition: vk_mem_alloc.h:1136
-VkMemoryPropertyFlags requiredFlags
Flags that must be set in a Memory Type chosen for an allocation.
Definition: vk_mem_alloc.h:1131
-VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1120
+VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition: vk_mem_alloc.h:1134
+VkMemoryPropertyFlags requiredFlags
Flags that must be set in a Memory Type chosen for an allocation.
Definition: vk_mem_alloc.h:1129
+VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1118
A memory type is chosen that has all the required flags and as many preferred flags set as possible.
If you use VmaAllocationCreateInfo::usage, it is just internally converted to a set of required and preferred flags.
@@ -127,7 +127,7 @@ Explicit memory types
VkBuffer buffer;
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:1144
+uint32_t memoryTypeBits
Bitmask containing one bit set for every memory type acceptable for this allocation.
Definition: vk_mem_alloc.h:1142
Custom memory pools
If you allocate from custom memory pool, all the ways of specifying memory requirements described above are not applicable and the aforementioned members of VmaAllocationCreateInfo structure are ignored. Memory type is selected explicitly when creating the pool and then used to make all the allocations from that pool. For further details, see Custom memory pools.
diff --git a/docs/html/custom_memory_pools.html b/docs/html/custom_memory_pools.html
index 0965e48..2c2dbba 100644
--- a/docs/html/custom_memory_pools.html
+++ b/docs/html/custom_memory_pools.html
@@ -108,13 +108,13 @@ $(function() {
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
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)
-Definition: vk_mem_alloc.h:1118
-VmaPool pool
Pool that this allocation should be created in.
Definition: vk_mem_alloc.h:1150
+Definition: vk_mem_alloc.h:1116
+VmaPool pool
Pool that this allocation should be created in.
Definition: vk_mem_alloc.h:1148
Represents single memory allocation.
-Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1260
-Describes parameter of created VmaPool.
Definition: vk_mem_alloc.h:1169
-uint32_t memoryTypeIndex
Vulkan memory type index to allocate this pool from.
Definition: vk_mem_alloc.h:1172
-size_t maxBlockCount
Maximum number of blocks that can be allocated in this pool. Optional.
Definition: vk_mem_alloc.h:1198
+Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1258
+Describes parameter of created VmaPool.
Definition: vk_mem_alloc.h:1167
+uint32_t memoryTypeIndex
Vulkan memory type index to allocate this pool from.
Definition: vk_mem_alloc.h:1170
+size_t maxBlockCount
Maximum number of blocks that can be allocated in this pool. Optional.
Definition: vk_mem_alloc.h:1196
Represents custom memory pool.
You have to free all allocations made from this pool before destroying it.
@@ -140,7 +140,7 @@ Choosing memory type index
VkResult vmaFindMemoryTypeIndexForBufferInfo(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)
Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.
@ VMA_MEMORY_USAGE_GPU_ONLY
Definition: vk_mem_alloc.h:466
-
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1126
+
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1124
When creating buffers/images allocated in that pool, provide following parameters:
VkBufferCreateInfo
: Prefer to pass same parameters as above. Otherwise you risk creating resources in a memory type that is not suitable for them, which may result in undefined behavior. Using different VK_BUFFER_USAGE_
flags may work, but you shouldn't create images in a pool intended for buffers or the other way around.
diff --git a/docs/html/defragmentation.html b/docs/html/defragmentation.html
index 4cb2795..9a7d725 100644
--- a/docs/html/defragmentation.html
+++ b/docs/html/defragmentation.html
@@ -133,15 +133,15 @@ Defragmenting CPU memory
VkResult vmaBindBufferMemory(VmaAllocator allocator, VmaAllocation allocation, VkBuffer buffer)
Binds buffer to allocation.
void vmaGetAllocationInfo(VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo *pAllocationInfo)
Returns current information about specified allocation.
VkResult vmaDefragmentationEnd(VmaAllocator allocator, VmaDefragmentationContext context)
Ends defragmentation process.
-Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1260
+Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1258
Represents main object of this library initialized.
Represents Opaque object that represents started defragmentation process.
-Parameters for defragmentation.
Definition: vk_mem_alloc.h:1315
-uint32_t allocationCount
Number of allocations in pAllocations array.
Definition: vk_mem_alloc.h:1321
-VkBool32 * pAllocationsChanged
Optional, output. Pointer to array that will be filled with information whether the allocation at cer...
Definition: vk_mem_alloc.h:1335
-uint32_t maxCpuAllocationsToMove
Maximum number of allocations that can be moved to a different place using transfers on CPU side,...
Definition: vk_mem_alloc.h:1364
-const VmaAllocation * pAllocations
Pointer to array of allocations that can be defragmented.
Definition: vk_mem_alloc.h:1329
-VkDeviceSize maxCpuBytesToMove
Maximum total numbers of bytes that can be copied while moving allocations to different places using ...
Definition: vk_mem_alloc.h:1359
+Parameters for defragmentation.
Definition: vk_mem_alloc.h:1313
+uint32_t allocationCount
Number of allocations in pAllocations array.
Definition: vk_mem_alloc.h:1319
+VkBool32 * pAllocationsChanged
Optional, output. Pointer to array that will be filled with information whether the allocation at cer...
Definition: vk_mem_alloc.h:1333
+uint32_t maxCpuAllocationsToMove
Maximum number of allocations that can be moved to a different place using transfers on CPU side,...
Definition: vk_mem_alloc.h:1362
+const VmaAllocation * pAllocations
Pointer to array of allocations that can be defragmented.
Definition: vk_mem_alloc.h:1327
+VkDeviceSize maxCpuBytesToMove
Maximum total numbers of bytes that can be copied while moving allocations to different places using ...
Definition: vk_mem_alloc.h:1357
Setting VmaDefragmentationInfo2::pAllocationsChanged is optional. This output array tells whether particular allocation in VmaDefragmentationInfo2::pAllocations at the same index has been modified during defragmentation. You can pass null, but you then need to query every allocation passed to defragmentation for new parameters using vmaGetAllocationInfo() if you might need to recreate and rebind a buffer or image associated with it.
If you use Custom memory pools, you can fill VmaDefragmentationInfo2::poolCount and VmaDefragmentationInfo2::pPools instead of VmaDefragmentationInfo2::allocationCount and VmaDefragmentationInfo2::pAllocations to defragment all allocations in given pools. You cannot use VmaDefragmentationInfo2::pAllocationsChanged in that case. You can also combine both methods.
@@ -203,9 +203,9 @@ Defragmenting GPU memory
}
}
-uint32_t maxGpuAllocationsToMove
Maximum number of allocations that can be moved to a different place using transfers on GPU side,...
Definition: vk_mem_alloc.h:1374
-VkDeviceSize maxGpuBytesToMove
Maximum total numbers of bytes that can be copied while moving allocations to different places using ...
Definition: vk_mem_alloc.h:1369
-VkCommandBuffer commandBuffer
Optional. Command buffer where GPU copy commands will be posted.
Definition: vk_mem_alloc.h:1383
+uint32_t maxGpuAllocationsToMove
Maximum number of allocations that can be moved to a different place using transfers on GPU side,...
Definition: vk_mem_alloc.h:1372
+VkDeviceSize maxGpuBytesToMove
Maximum total numbers of bytes that can be copied while moving allocations to different places using ...
Definition: vk_mem_alloc.h:1367
+VkCommandBuffer commandBuffer
Optional. Command buffer where GPU copy commands will be posted.
Definition: vk_mem_alloc.h:1381
You can combine these two methods by specifying non-zero maxGpu*
as well as maxCpu*
parameters. The library automatically chooses best method to defragment each memory pool.
You may try not to block your entire program to wait until defragmentation finishes, but do it in the background, as long as you carefully fullfill requirements described in function vmaDefragmentationBegin().
diff --git a/docs/html/group__group__alloc.html b/docs/html/group__group__alloc.html
index 4b49275..e600813 100644
--- a/docs/html/group__group__alloc.html
+++ b/docs/html/group__group__alloc.html
@@ -709,8 +709,7 @@ Functions
VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT | Enables alternative, linear allocation algorithm in this pool.
Specify this flag to enable linear allocation algorithm, which always creates new allocations after last one and doesn't reuse space from allocations freed in between. It trades memory consumption for simplified algorithm and data structure, which has better performance and uses less memory for metadata.
-By using this flag, you can achieve behavior of free-at-once, stack, ring buffer, and double stack. For details, see documentation chapter Linear allocation algorithm.
-When using this flag, you must specify VmaPoolCreateInfo::maxBlockCount == 1 (or 0 for default).
+By using this flag, you can achieve behavior of free-at-once, stack, ring buffer, and double stack. For details, see documentation chapter Linear allocation algorithm.
|
VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT | Enables alternative, buddy allocation algorithm in this pool.
It operates on a tree of blocks, each having size that is a power of two and a half of its parent's size. Comparing to default algorithm, this one provides faster allocation and deallocation and decreased external fragmentation, at the expense of more memory wasted (internal fragmentation). For details, see documentation chapter Buddy allocation algorithm.
diff --git a/docs/html/group__group__virtual.html b/docs/html/group__group__virtual.html
index 680207e..8d6a883 100644
--- a/docs/html/group__group__virtual.html
+++ b/docs/html/group__group__virtual.html
@@ -610,8 +610,7 @@ Functions |
Allocates new virtual allocation inside given VmaVirtualBlock.
-
There is no handle type for a virtual allocation. Virtual allocations within a specific virtual block are uniquely identified by their offsets.
-
If the allocation fails due to not enough free space available, VK_ERROR_OUT_OF_DEVICE_MEMORY
is returned (despite the function doesn't ever allocate actual GPU memory).
+
If the allocation fails due to not enough free space available, VK_ERROR_OUT_OF_DEVICE_MEMORY
is returned (despite the function doesn't ever allocate actual GPU memory). pAllocation
is then set to VK_NULL_HANDLE
AND pOffset
, if not null, it set to UINT64_MAX
.
- Parameters
-
| virtualBlock | Virtual block |
diff --git a/docs/html/memory_mapping.html b/docs/html/memory_mapping.html
index 5325fd7..4d93fca 100644
--- a/docs/html/memory_mapping.html
+++ b/docs/html/memory_mapping.html
@@ -119,11 +119,11 @@ Persistently mapped memory
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
@ VMA_MEMORY_USAGE_CPU_ONLY
Definition: vk_mem_alloc.h:476
@ 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:540
-Definition: vk_mem_alloc.h:1118
-VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1126
-VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1120
-Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1260
-void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition: vk_mem_alloc.h:1302
+Definition: vk_mem_alloc.h:1116
+VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1124
+VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1118
+Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1258
+void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition: vk_mem_alloc.h:1300
There are some exceptions though, when you should consider mapping memory only for a short period of time:
- When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2), device is discrete AMD GPU, and memory type is the special 256 MiB pool of
DEVICE_LOCAL + HOST_VISIBLE
memory (selected when you use VMA_MEMORY_USAGE_CPU_TO_GPU), then whenever a memory block allocated from this memory type stays mapped for the time of any call to vkQueueSubmit()
or vkQueuePresentKHR()
, this block is migrated by WDDM to system RAM, which degrades performance. It doesn't matter if that particular memory block is actually used by the command buffer being submitted.
@@ -168,7 +168,7 @@ Finding out if memory is mappable
}
void vmaGetAllocationMemoryProperties(VmaAllocator allocator, VmaAllocation allocation, VkMemoryPropertyFlags *pFlags)
Given an allocation, returns Property Flags of its memory type.
@ VMA_MEMORY_USAGE_GPU_ONLY
Definition: vk_mem_alloc.h:466
-VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition: vk_mem_alloc.h:1136
+VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition: vk_mem_alloc.h:1134
You can even use VMA_ALLOCATION_CREATE_MAPPED_BIT flag while creating allocations that are not necessarily HOST_VISIBLE
(e.g. using VMA_MEMORY_USAGE_GPU_ONLY). If the allocation ends up in memory type that is HOST_VISIBLE
, it will be persistently mapped and you can use it directly. If not, the flag is just ignored. Example:
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.size = sizeof(ConstantBuffer);
diff --git a/docs/html/quick_start.html b/docs/html/quick_start.html
index 64e1620..6e4393e 100644
--- a/docs/html/quick_start.html
+++ b/docs/html/quick_start.html
@@ -105,11 +105,11 @@ Initialization
VkResult vmaCreateAllocator(const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
Creates VmaAllocator object.
-
Description of a Allocator to be created.
Definition: vk_mem_alloc.h:944
-
VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition: vk_mem_alloc.h:949
-
VkInstance instance
Handle to Vulkan instance object.
Definition: vk_mem_alloc.h:997
-
VkDevice device
Vulkan device.
Definition: vk_mem_alloc.h:952
-
uint32_t vulkanApiVersion
Optional. The highest version of Vulkan that the application is designed to use.
Definition: vk_mem_alloc.h:1006
+
Description of a Allocator to be created.
Definition: vk_mem_alloc.h:942
+
VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition: vk_mem_alloc.h:947
+
VkInstance instance
Handle to Vulkan instance object.
Definition: vk_mem_alloc.h:995
+
VkDevice device
Vulkan device.
Definition: vk_mem_alloc.h:950
+
uint32_t vulkanApiVersion
Optional. The highest version of Vulkan that the application is designed to use.
Definition: vk_mem_alloc.h:1004
Represents main object of this library initialized.
Only members physicalDevice
, device
, instance
are required. However, you should inform the library which Vulkan version do you use by setting VmaAllocatorCreateInfo::vulkanApiVersion and which extensions did you enable by setting VmaAllocatorCreateInfo::flags (like VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT for VK_KHR_buffer_device_address). Otherwise, VMA would use only features of Vulkan 1.0 core with no extensions.
@@ -132,8 +132,8 @@ Resource allocation
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation,
nullptr);
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
@ VMA_MEMORY_USAGE_GPU_ONLY
Definition: vk_mem_alloc.h:466
-Definition: vk_mem_alloc.h:1118
-VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1126
+Definition: vk_mem_alloc.h:1116
+VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1124
Represents single memory allocation.
Don't forget to destroy your objects when no longer needed:
diff --git a/docs/html/resource_aliasing.html b/docs/html/resource_aliasing.html
index e7cd25c..93edd0f 100644
--- a/docs/html/resource_aliasing.html
+++ b/docs/html/resource_aliasing.html
@@ -141,8 +141,8 @@ $(function() {
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.
@ VMA_MEMORY_USAGE_GPU_ONLY
Definition: vk_mem_alloc.h:466
-
Definition: vk_mem_alloc.h:1118
-
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1126
+
Definition: vk_mem_alloc.h:1116
+
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1124
Represents single memory allocation.
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
.
Additional considerations:
diff --git a/docs/html/virtual_allocator.html b/docs/html/virtual_allocator.html
index 7407f8c..dd757a9 100644
--- a/docs/html/virtual_allocator.html
+++ b/docs/html/virtual_allocator.html
@@ -84,8 +84,8 @@ Creating virtual 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:1443
-VkDeviceSize size
Total size of the virtual block.
Definition: vk_mem_alloc.h:1449
+Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().
Definition: vk_mem_alloc.h:1441
+VkDeviceSize size
Total size of the virtual block.
Definition: vk_mem_alloc.h:1447
Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...
Making virtual allocations
@@ -111,8 +111,8 @@ Making virtual allocations
}
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:1464
-VkDeviceSize size
Size of the allocation.
Definition: vk_mem_alloc.h:1469
+Parameters of created virtual allocation to be passed to vmaVirtualAllocate().
Definition: vk_mem_alloc.h:1462
+VkDeviceSize size
Size of the allocation.
Definition: vk_mem_alloc.h:1467
Represents single memory allocation done inside VmaVirtualBlock.
Deallocation
@@ -140,8 +140,8 @@ Allocation parameters
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:1487
-void * pUserData
Custom pointer associated with the allocation.
Definition: vk_mem_alloc.h:1502
+Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().
Definition: vk_mem_alloc.h:1485
+void * pUserData
Custom pointer associated with the allocation.
Definition: vk_mem_alloc.h:1500
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:
@@ -151,7 +151,7 @@ Alignment and units
-VkDeviceSize alignment
Required alignment of the allocation. Optional.
Definition: vk_mem_alloc.h:1474
+VkDeviceSize alignment
Required alignment of the allocation. Optional.
Definition: vk_mem_alloc.h:1472
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:
- VmaVirtualBlockCreateInfo::size
@@ -166,9 +166,9 @@ Statistics
printf("My virtual block has %llu bytes used by %u virtual allocations\n",
void vmaCalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, VmaStatInfo *pStatInfo)
Calculates and returns statistics about virtual allocations and memory usage in given VmaVirtualBlock...
-Calculated statistics of memory usage in entire allocator.
Definition: vk_mem_alloc.h:1050
-uint32_t allocationCount
Number of VmaAllocation allocation objects allocated.
Definition: vk_mem_alloc.h:1054
-VkDeviceSize usedBytes
Total number of bytes occupied by all allocations.
Definition: vk_mem_alloc.h:1058
+Calculated statistics of memory usage in entire allocator.
Definition: vk_mem_alloc.h:1048
+uint32_t allocationCount
Number of VmaAllocation allocation objects allocated.
Definition: vk_mem_alloc.h:1052
+VkDeviceSize usedBytes
Total number of bytes occupied by all allocations.
Definition: vk_mem_alloc.h:1056
You can also request a full list of allocations and free regions as a string in JSON format by calling vmaBuildVirtualBlockStatsString(). Returned string must be later freed using vmaFreeVirtualBlockStatsString(). The format of this string differs from the one returned by the main Vulkan allocator, but it is similar.
Additional considerations
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index 31514a2..c210ef7 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -2366,11 +2366,9 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualAllocationInfo(
/** \brief Allocates new virtual allocation inside given #VmaVirtualBlock.
-There is no handle type for a virtual allocation.
-Virtual allocations within a specific virtual block are uniquely identified by their offsets.
-
If the allocation fails due to not enough free space available, `VK_ERROR_OUT_OF_DEVICE_MEMORY` is returned
(despite the function doesn't ever allocate actual GPU memory).
+`pAllocation` is then set to `VK_NULL_HANDLE` and `pOffset`, if not null, it set to `UINT64_MAX`.
\param virtualBlock Virtual block
\param pCreateInfo Parameters for the allocation
@@ -6430,8 +6428,8 @@ public:
size_t GetAllocationCount() const override { return m_Suballocations.size() - m_FreeCount; }
VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize; }
bool IsEmpty() const override { return (m_Suballocations.size() == 1) && (m_FreeCount == 1); }
- void Free(VmaAllocHandle allocHandle) override { FreeSuballocation(FindAtOffset((VkDeviceSize)allocHandle)); }
- VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle; };
+ void Free(VmaAllocHandle allocHandle) override { FreeSuballocation(FindAtOffset((VkDeviceSize)allocHandle - 1)); }
+ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; };
void Init(VkDeviceSize size) override;
bool Validate() const override;
@@ -6790,8 +6788,8 @@ void VmaBlockMetadata_Generic::Alloc(
VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
// Given offset is inside this suballocation.
- VMA_ASSERT((VkDeviceSize)request.allocHandle >= suballoc.offset);
- const VkDeviceSize paddingBegin = (VkDeviceSize)request.allocHandle - suballoc.offset;
+ VMA_ASSERT((VkDeviceSize)request.allocHandle - 1 >= suballoc.offset);
+ const VkDeviceSize paddingBegin = (VkDeviceSize)request.allocHandle - suballoc.offset - 1;
VMA_ASSERT(suballoc.size >= paddingBegin + request.size);
const VkDeviceSize paddingEnd = suballoc.size - paddingBegin - request.size;
@@ -6799,7 +6797,7 @@ void VmaBlockMetadata_Generic::Alloc(
// it to become used.
UnregisterFreeSuballocation(request.item);
- suballoc.offset = (VkDeviceSize)request.allocHandle;
+ suballoc.offset = (VkDeviceSize)request.allocHandle - 1;
suballoc.size = request.size;
suballoc.type = type;
suballoc.userData = userData;
@@ -6845,8 +6843,8 @@ void VmaBlockMetadata_Generic::Alloc(
void VmaBlockMetadata_Generic::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
{
- const VmaSuballocation& suballoc = *FindAtOffset((VkDeviceSize)allocHandle);
- outInfo.offset = (VkDeviceSize)allocHandle;
+ outInfo.offset = (VkDeviceSize)allocHandle - 1;
+ const VmaSuballocation& suballoc = *FindAtOffset(outInfo.offset);
outInfo.size = suballoc.size;
outInfo.pUserData = suballoc.userData;
}
@@ -6872,7 +6870,7 @@ void VmaBlockMetadata_Generic::Clear()
void VmaBlockMetadata_Generic::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
{
- VmaSuballocation& suballoc = *FindAtOffset((VkDeviceSize)allocHandle);
+ VmaSuballocation& suballoc = *FindAtOffset((VkDeviceSize)allocHandle - 1);
suballoc.userData = userData;
}
@@ -7030,7 +7028,7 @@ bool VmaBlockMetadata_Generic::CheckAllocation(
}
}
- *pAllocHandle = (VmaAllocHandle)offset;
+ *pAllocHandle = (VmaAllocHandle)(offset + 1);
// All tests passed: Success. pAllocHandle is already filled.
return true;
}
@@ -7273,7 +7271,7 @@ public:
VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize; }
bool IsEmpty() const override { return GetAllocationCount() == 0; }
- VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle; };
+ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; };
void Init(VkDeviceSize size) override;
bool Validate() const override;
@@ -8246,7 +8244,8 @@ void VmaBlockMetadata_Linear::Alloc(
VmaSuballocationType type,
void* userData)
{
- const VmaSuballocation newSuballoc = { (VkDeviceSize)request.allocHandle, request.size, userData, type };
+ const VkDeviceSize offset = (VkDeviceSize)request.allocHandle - 1;
+ const VmaSuballocation newSuballoc = { offset, request.size, userData, type };
switch (request.type)
{
@@ -8264,9 +8263,9 @@ void VmaBlockMetadata_Linear::Alloc(
SuballocationVectorType& suballocations1st = AccessSuballocations1st();
VMA_ASSERT(suballocations1st.empty() ||
- (VkDeviceSize)request.allocHandle >= suballocations1st.back().offset + suballocations1st.back().size);
+ offset >= suballocations1st.back().offset + suballocations1st.back().size);
// Check if it fits before the end of the block.
- VMA_ASSERT((VkDeviceSize)request.allocHandle + request.size <= GetSize());
+ VMA_ASSERT(offset + request.size <= GetSize());
suballocations1st.push_back(newSuballoc);
}
@@ -8276,7 +8275,7 @@ void VmaBlockMetadata_Linear::Alloc(
SuballocationVectorType& suballocations1st = AccessSuballocations1st();
// New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector.
VMA_ASSERT(!suballocations1st.empty() &&
- (VkDeviceSize)request.allocHandle + request.size <= suballocations1st[m_1stNullItemsBeginCount].offset);
+ offset + request.size <= suballocations1st[m_1stNullItemsBeginCount].offset);
SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
switch (m_2ndVectorMode)
@@ -8311,7 +8310,7 @@ void VmaBlockMetadata_Linear::Free(VmaAllocHandle allocHandle)
{
SuballocationVectorType& suballocations1st = AccessSuballocations1st();
SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
- VkDeviceSize offset = (VkDeviceSize)allocHandle;
+ VkDeviceSize offset = (VkDeviceSize)allocHandle - 1;
if (!suballocations1st.empty())
{
@@ -8398,8 +8397,8 @@ void VmaBlockMetadata_Linear::Free(VmaAllocHandle allocHandle)
void VmaBlockMetadata_Linear::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
{
- VmaSuballocation& suballoc = FindSuballocation((VkDeviceSize)allocHandle);
- outInfo.offset = (VkDeviceSize)allocHandle;
+ outInfo.offset = (VkDeviceSize)allocHandle - 1;
+ VmaSuballocation& suballoc = FindSuballocation(outInfo.offset);
outInfo.size = suballoc.size;
outInfo.pUserData = suballoc.userData;
}
@@ -8418,7 +8417,7 @@ void VmaBlockMetadata_Linear::Clear()
void VmaBlockMetadata_Linear::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
{
- VmaSuballocation& suballoc = FindSuballocation((VkDeviceSize)allocHandle);
+ VmaSuballocation& suballoc = FindSuballocation((VkDeviceSize)allocHandle - 1);
suballoc.userData = userData;
}
@@ -8670,7 +8669,7 @@ bool VmaBlockMetadata_Linear::CreateAllocationRequest_LowerAddress(
}
// All tests passed: Success.
- pAllocationRequest->allocHandle = (VmaAllocHandle)resultOffset;
+ pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1);
// pAllocationRequest->item, customData unused.
pAllocationRequest->type = VmaAllocationRequestType::EndOf1st;
return true;
@@ -8753,7 +8752,7 @@ bool VmaBlockMetadata_Linear::CreateAllocationRequest_LowerAddress(
}
// All tests passed: Success.
- pAllocationRequest->allocHandle = (VmaAllocHandle)resultOffset;
+ pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1);
pAllocationRequest->type = VmaAllocationRequestType::EndOf2nd;
// pAllocationRequest->item, customData unused.
return true;
@@ -8870,7 +8869,7 @@ bool VmaBlockMetadata_Linear::CreateAllocationRequest_UpperAddress(
}
// All tests passed: Success.
- pAllocationRequest->allocHandle = (VmaAllocHandle)resultOffset;
+ pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1);
// pAllocationRequest->item unused.
pAllocationRequest->type = VmaAllocationRequestType::UpperAddress;
return true;
@@ -8905,7 +8904,7 @@ public:
VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize + GetUnusableSize(); }
bool IsEmpty() const override { return m_Root->type == Node::TYPE_FREE; }
VkResult CheckCorruption(const void* pBlockData) override { return VK_ERROR_FEATURE_NOT_PRESENT; }
- VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle; };
+ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; };
void DebugLogAllAllocations() const override { DebugLogAllAllocationNode(m_Root, 0); }
void Init(VkDeviceSize size) override;
@@ -9206,7 +9205,7 @@ bool VmaBlockMetadata_Buddy::CreateAllocationRequest(
if (freeNode->offset % allocAlignment == 0)
{
pAllocationRequest->type = VmaAllocationRequestType::Normal;
- pAllocationRequest->allocHandle = (VmaAllocHandle)freeNode->offset;
+ pAllocationRequest->allocHandle = (VmaAllocHandle)(freeNode->offset + 1);
pAllocationRequest->size = allocSize;
pAllocationRequest->customData = (void*)(uintptr_t)level;
return true;
@@ -9229,7 +9228,8 @@ void VmaBlockMetadata_Buddy::Alloc(
Node* currNode = m_FreeList[currLevel].front;
VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
- while (currNode->offset != (VkDeviceSize)request.allocHandle)
+ const VkDeviceSize offset = (VkDeviceSize)request.allocHandle - 1;
+ while (currNode->offset != offset)
{
currNode = currNode->free.next;
VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
@@ -9294,8 +9294,8 @@ void VmaBlockMetadata_Buddy::Alloc(
void VmaBlockMetadata_Buddy::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
{
uint32_t level = 0;
- const Node* const node = FindAllocationNode((VkDeviceSize)allocHandle, level);
- outInfo.offset = (VkDeviceSize)allocHandle;
+ outInfo.offset = (VkDeviceSize)allocHandle - 1;
+ const Node* const node = FindAllocationNode(outInfo.offset, level);
outInfo.size = LevelToNodeSize(level);
outInfo.pUserData = node->allocation.userData;
}
@@ -9324,7 +9324,7 @@ void VmaBlockMetadata_Buddy::Clear()
void VmaBlockMetadata_Buddy::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
{
uint32_t level = 0;
- Node* const node = FindAllocationNode((VkDeviceSize)allocHandle, level);
+ Node* const node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level);
node->allocation.userData = userData;
}
@@ -9418,7 +9418,7 @@ uint32_t VmaBlockMetadata_Buddy::AllocSizeToLevel(VkDeviceSize allocSize) const
void VmaBlockMetadata_Buddy::Free(VmaAllocHandle allocHandle)
{
uint32_t level = 0;
- Node* node = FindAllocationNode((VkDeviceSize)allocHandle, level);
+ Node* node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level);
++m_FreeCount;
--m_AllocationCount;
@@ -10312,6 +10312,7 @@ void VmaBlockMetadata_TLSF::RemoveFreeBlock(Block* block)
uint8_t memClass = SizeToMemoryClass(block->size);
uint16_t secondIndex = SizeToSecondIndex(block->size, memClass);
uint32_t index = GetListIndex(memClass, secondIndex);
+ VMA_ASSERT(m_FreeList[index] == block);
m_FreeList[index] = block->NextFree();
if (block->NextFree() == VMA_NULL)
{
@@ -11120,6 +11121,8 @@ VkResult VmaVirtualBlock_T::Allocate(const VmaVirtualAllocationCreateInfo& creat
return VK_SUCCESS;
}
outAllocation = (VmaVirtualAllocation)VK_NULL_HANDLE;
+ if (outOffset)
+ *outOffset = UINT64_MAX;
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
@@ -13663,7 +13666,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
VmaSuballocation suballoc = *srcSuballocIt;
suballoc.offset = dstAllocOffset;
- ((VmaAllocation)(suballoc.userData))->ChangeAllocHandle((VmaAllocHandle)dstAllocOffset);
+ ((VmaAllocation)(suballoc.userData))->ChangeAllocHandle((VmaAllocHandle)(dstAllocOffset + 1));
m_BytesMoved += srcAllocSize;
++m_AllocationsMoved;
@@ -13678,7 +13681,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
move.dstBlockIndex = freeSpaceOrigBlockIndex;
move.srcOffset = srcAllocOffset;
move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)dstAllocOffset;
+ move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
move.size = srcAllocSize;
moves.push_back(move);
@@ -13692,7 +13695,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
VmaSuballocation suballoc = *srcSuballocIt;
suballoc.offset = dstAllocOffset;
- ((VmaAllocation)(suballoc.userData))->ChangeBlockAllocation(m_hAllocator, pFreeSpaceBlock, (VmaAllocHandle)dstAllocOffset);
+ ((VmaAllocation)(suballoc.userData))->ChangeBlockAllocation(m_hAllocator, pFreeSpaceBlock, (VmaAllocHandle)(dstAllocOffset + 1));
m_BytesMoved += srcAllocSize;
++m_AllocationsMoved;
@@ -13707,7 +13710,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
move.dstBlockIndex = freeSpaceOrigBlockIndex;
move.srcOffset = srcAllocOffset;
move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)dstAllocOffset;
+ move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
move.size = srcAllocSize;
moves.push_back(move);
@@ -13759,7 +13762,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
else
{
srcSuballocIt->offset = dstAllocOffset;
- ((VmaAllocation)(srcSuballocIt->userData))->ChangeAllocHandle((VmaAllocHandle)dstAllocOffset);
+ ((VmaAllocation)(srcSuballocIt->userData))->ChangeAllocHandle((VmaAllocHandle)(dstAllocOffset + 1));
dstOffset = dstAllocOffset + srcAllocSize;
m_BytesMoved += srcAllocSize;
++m_AllocationsMoved;
@@ -13769,7 +13772,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
move.dstBlockIndex = dstOrigBlockIndex;
move.srcOffset = srcAllocOffset;
move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)dstAllocOffset;
+ move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
move.size = srcAllocSize;
moves.push_back(move);
@@ -13785,7 +13788,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
VmaSuballocation suballoc = *srcSuballocIt;
suballoc.offset = dstAllocOffset;
- ((VmaAllocation)(suballoc.userData))->ChangeBlockAllocation(m_hAllocator, pDstBlock, (VmaAllocHandle)dstAllocOffset);
+ ((VmaAllocation)(suballoc.userData))->ChangeBlockAllocation(m_hAllocator, pDstBlock, (VmaAllocHandle)(dstAllocOffset + 1));
dstOffset = dstAllocOffset + srcAllocSize;
m_BytesMoved += srcAllocSize;
++m_AllocationsMoved;
@@ -13801,7 +13804,7 @@ VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
move.dstBlockIndex = dstOrigBlockIndex;
move.srcOffset = srcAllocOffset;
move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)dstAllocOffset;
+ move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
move.size = srcAllocSize;
moves.push_back(move);
diff --git a/src/Tests.cpp b/src/Tests.cpp
index 7663581..99e6dc8 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -46,7 +46,8 @@ void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, const char* nam
#define VMA_DEBUG_MARGIN 0
#endif
-enum CONFIG_TYPE {
+enum CONFIG_TYPE
+{
CONFIG_TYPE_MINIMUM,
CONFIG_TYPE_SMALL,
CONFIG_TYPE_AVERAGE,
@@ -60,7 +61,8 @@ static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_SMALL;
enum class FREE_ORDER { FORWARD, BACKWARD, RANDOM, COUNT };
-static const char* FREE_ORDER_NAMES[] = {
+static const char* FREE_ORDER_NAMES[] =
+{
"FORWARD",
"BACKWARD",
"RANDOM",
@@ -2069,7 +2071,6 @@ static void ProcessDefragmentationStepInfo(VmaDefragmentationPassInfo &stepInfo)
}
}
-
static void TestDefragmentationIncrementalBasic()
{
wprintf(L"Test defragmentation incremental basic\n");
@@ -2466,7 +2467,6 @@ void TestDefragmentationIncrementalComplex()
}
}
-
static void TestUserData()
{
VkResult res;
@@ -2727,6 +2727,7 @@ static void TestVirtualBlocks()
allocCreateInfo.size = 8 * MEGABYTE;
VmaVirtualAllocation allocation0 = VK_NULL_HANDLE;
TEST(vmaVirtualAllocate(block, &allocCreateInfo, &allocation0, &offset) == VK_SUCCESS);
+ TEST(allocation0 != VK_NULL_HANDLE);
// # Validate the allocation
@@ -2748,6 +2749,7 @@ static void TestVirtualBlocks()
allocCreateInfo.size = 4 * MEGABYTE;
VmaVirtualAllocation allocation1 = VK_NULL_HANDLE;
TEST(vmaVirtualAllocate(block, &allocCreateInfo, &allocation1, nullptr) == VK_SUCCESS);
+ TEST(allocation1 != VK_NULL_HANDLE);
VmaVirtualAllocationInfo allocInfo1 = {};
vmaGetVirtualAllocationInfo(block, allocation1, &allocInfo1);
TEST(allocInfo1.offset < blockSize);
@@ -2757,13 +2759,15 @@ static void TestVirtualBlocks()
allocCreateInfo.size = 8 * MEGABYTE;
VmaVirtualAllocation allocation2 = VK_NULL_HANDLE;
- TEST(vmaVirtualAllocate(block, &allocCreateInfo, &allocation2, nullptr) < 0);
+ TEST(vmaVirtualAllocate(block, &allocCreateInfo, &allocation2, &offset) < 0);
TEST(allocation2 == VK_NULL_HANDLE);
+ TEST(offset == UINT64_MAX);
// # Free the 4 MB block. Now allocation of 8 MB should succeed.
vmaVirtualFree(block, allocation1);
TEST(vmaVirtualAllocate(block, &allocCreateInfo, &allocation2, nullptr) == VK_SUCCESS);
+ TEST(allocation2 != VK_NULL_HANDLE);
VmaVirtualAllocationInfo allocInfo2 = {};
vmaGetVirtualAllocationInfo(block, allocation2, &allocInfo2);
TEST(allocInfo2.offset < blockSize);
@@ -2806,6 +2810,7 @@ static void TestVirtualBlocks()
allocCreateInfo.size = i * 3 + 15;
allocCreateInfo.alignment = alignment0 ? 0 : 8;
TEST(vmaVirtualAllocate(block, &allocCreateInfo, &allocations[i], nullptr) == VK_SUCCESS);
+ TEST(allocations[i] != VK_NULL_HANDLE);
if(!alignment0)
{
VmaVirtualAllocationInfo info;
@@ -3396,7 +3401,10 @@ void TestHeapSizeLimit()
vmaDestroyAllocator(hAllocator);
}
-#if VMA_DEBUG_MARGIN
+#ifndef VMA_DEBUG_MARGIN
+ #define VMA_DEBUG_MARGIN (0)
+#endif
+
static void TestDebugMargin()
{
if(VMA_DEBUG_MARGIN == 0)
@@ -3417,9 +3425,15 @@ static void TestDebugMargin()
TEST(vmaFindMemoryTypeIndexForBufferInfo(
g_hAllocator, &bufInfo, &allocCreateInfo, &poolCreateInfo.memoryTypeIndex) == VK_SUCCESS);
- for(size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
+ for(size_t algorithmIndex = 0; algorithmIndex < 3; ++algorithmIndex)
{
- poolCreateInfo.flags = (algorithmIndex == 1 ? VMA_POOL_CREATE_TLSF_ALGORITHM_BIT : 0);
+ switch(algorithmIndex)
+ {
+ case 0: poolCreateInfo.flags = 0; break;
+ case 1: poolCreateInfo.flags = VMA_POOL_CREATE_TLSF_ALGORITHM_BIT; break;
+ case 2: poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT; break;
+ default: assert(0);
+ }
VmaPool pool = VK_NULL_HANDLE;
TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS && pool);
@@ -3461,12 +3475,13 @@ static void TestDebugMargin()
{
if(allocInfo[i].deviceMemory == allocInfo[i - 1].deviceMemory)
{
- TEST(allocInfo[i].offset >= allocInfo[i - 1].offset + VMA_DEBUG_MARGIN);
+ TEST(allocInfo[i].offset >=
+ allocInfo[i - 1].offset + allocInfo[i - 1].size + VMA_DEBUG_MARGIN);
}
}
VkResult res = vmaCheckCorruption(g_hAllocator, UINT32_MAX);
- TEST(res == VK_SUCCESS);
+ TEST(res == VK_SUCCESS || res == VK_ERROR_FEATURE_NOT_PRESENT);
// JSON dump
char* json = nullptr;
@@ -3486,6 +3501,8 @@ static void TestDebugMargin()
static void TestDebugMarginNotInVirtualAllocator()
{
+ wprintf(L"Test VMA_DEBUG_MARGIN not applied to virtual allocator\n");
+
constexpr size_t ALLOCATION_COUNT = 10;
for(size_t algorithm = 0; algorithm < 2; ++algorithm)
{
@@ -3509,7 +3526,6 @@ static void TestDebugMarginNotInVirtualAllocator()
vmaDestroyVirtualBlock(block);
}
}
-#endif
static void TestLinearAllocator()
{
@@ -6966,6 +6982,7 @@ static void TestVirtualBlocksAlgorithmsBenchmark()
allocCreateInfo.flags = allocFlags;
TEST(vmaVirtualAllocate(block, &allocCreateInfo, allocs + i, nullptr) == VK_SUCCESS);
+ TEST(allocs[i] != VK_NULL_HANDLE);
}
allocDuration += std::chrono::high_resolution_clock::now() - timeBegin;