Numeric statistics
JSON dump
diff --git a/docs/html/memory_mapping.html b/docs/html/memory_mapping.html
index 81f445f..69b3ff0 100644
--- a/docs/html/memory_mapping.html
+++ b/docs/html/memory_mapping.html
@@ -116,15 +116,15 @@ Persistently mapped memory
memcpy(allocInfo.
pMappedData , &constantBufferData,
sizeof (constantBufferData));
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
-@ VMA_MEMORY_USAGE_AUTO
Definition: vk_mem_alloc.h:493
-@ 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:551
-@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition: vk_mem_alloc.h:598
-Definition: vk_mem_alloc.h:1218
-VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1226
-VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1220
+@ VMA_MEMORY_USAGE_AUTO
Definition: vk_mem_alloc.h:488
+@ 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:546
+@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition: vk_mem_alloc.h:593
+Definition: vk_mem_alloc.h:1211
+VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1219
+VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1213
Represents single memory allocation.
-Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1333
-void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition: vk_mem_alloc.h:1375
+Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1326
+void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition: vk_mem_alloc.h:1368
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/menudata.js b/docs/html/menudata.js
index 1005963..74a8ea2 100644
--- a/docs/html/menudata.js
+++ b/docs/html/menudata.js
@@ -33,7 +33,6 @@ var menudata={children:[
{text:"All",url:"functions.html",children:[
{text:"a",url:"functions.html#index_a"},
{text:"b",url:"functions.html#index_b"},
-{text:"c",url:"functions.html#index_c"},
{text:"d",url:"functions.html#index_d"},
{text:"f",url:"functions.html#index_f"},
{text:"i",url:"functions.html#index_i"},
@@ -48,7 +47,6 @@ var menudata={children:[
{text:"Variables",url:"functions_vars.html",children:[
{text:"a",url:"functions_vars.html#index_a"},
{text:"b",url:"functions_vars.html#index_b"},
-{text:"c",url:"functions_vars.html#index_c"},
{text:"d",url:"functions_vars.html#index_d"},
{text:"f",url:"functions_vars.html#index_f"},
{text:"i",url:"functions_vars.html#index_i"},
diff --git a/docs/html/quick_start.html b/docs/html/quick_start.html
index 815399a..14bba29 100644
--- a/docs/html/quick_start.html
+++ b/docs/html/quick_start.html
@@ -124,16 +124,16 @@ Initialization
VkResult vmaCreateAllocator(const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
Creates VmaAllocator object.
-Description of a Allocator to be created.
Definition: vk_mem_alloc.h:1001
-VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition: vk_mem_alloc.h:1006
-const VmaVulkanFunctions * pVulkanFunctions
Pointers to Vulkan functions. Can be null.
Definition: vk_mem_alloc.h:1049
-VkInstance instance
Handle to Vulkan instance object.
Definition: vk_mem_alloc.h:1054
-VkDevice device
Vulkan device.
Definition: vk_mem_alloc.h:1009
-uint32_t vulkanApiVersion
Optional. The highest version of Vulkan that the application is designed to use.
Definition: vk_mem_alloc.h:1063
+Description of a Allocator to be created.
Definition: vk_mem_alloc.h:994
+VkPhysicalDevice physicalDevice
Vulkan physical device.
Definition: vk_mem_alloc.h:999
+const VmaVulkanFunctions * pVulkanFunctions
Pointers to Vulkan functions. Can be null.
Definition: vk_mem_alloc.h:1042
+VkInstance instance
Handle to Vulkan instance object.
Definition: vk_mem_alloc.h:1047
+VkDevice device
Vulkan device.
Definition: vk_mem_alloc.h:1002
+uint32_t vulkanApiVersion
Optional. The highest version of Vulkan that the application is designed to use.
Definition: vk_mem_alloc.h:1056
Represents main object of this library initialized.
-Pointers to some Vulkan functions - a subset used by the library.
Definition: vk_mem_alloc.h:954
-PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr
Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
Definition: vk_mem_alloc.h:956
-PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr
Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
Definition: vk_mem_alloc.h:958
+Pointers to some Vulkan functions - a subset used by the library.
Definition: vk_mem_alloc.h:947
+PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr
Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
Definition: vk_mem_alloc.h:949
+PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr
Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
Definition: vk_mem_alloc.h:951
Resource allocation
When you want to create a buffer or image:
@@ -153,9 +153,9 @@ 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_AUTO
Definition: vk_mem_alloc.h:493
-Definition: vk_mem_alloc.h:1218
-VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1226
+@ VMA_MEMORY_USAGE_AUTO
Definition: vk_mem_alloc.h:488
+Definition: vk_mem_alloc.h:1211
+VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1219
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 e4a4e5d..1a29aa3 100644
--- a/docs/html/resource_aliasing.html
+++ b/docs/html/resource_aliasing.html
@@ -140,8 +140,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.
-
Definition: vk_mem_alloc.h:1218
-
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition: vk_mem_alloc.h:1236
+
Definition: vk_mem_alloc.h:1211
+
VkMemoryPropertyFlags preferredFlags
Flags that preferably should be set in a memory type chosen for an allocation.
Definition: vk_mem_alloc.h:1229
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/search/all_0.js b/docs/html/search/all_0.js
index 81469a9..c99be0f 100644
--- a/docs/html/search/all_0.js
+++ b/docs/html/search/all_0.js
@@ -1,11 +1,10 @@
var searchData=
[
['alignment_0',['alignment',['../struct_vma_virtual_allocation_create_info.html#a9d19709872fc1904a105079e1c885821',1,'VmaVirtualAllocationCreateInfo']]],
- ['allocation_1',['allocation',['../struct_vma_defragmentation_pass_move_info.html#ae885c861c2dd8d622e6c19e281d035cc',1,'VmaDefragmentationPassMoveInfo']]],
- ['allocation_20names_20and_20user_20data_2',['Allocation names and user data',['../allocation_annotation.html',1,'index']]],
- ['allocationbytes_3',['allocationBytes',['../struct_vma_statistics.html#a21db06eba3422f87a2b4b4703d879c16',1,'VmaStatistics']]],
- ['allocationcount_4',['allocationCount',['../struct_vma_statistics.html#ab0ff76e50f58f9f54b6f265e5bf5dde2',1,'VmaStatistics::allocationCount()'],['../struct_vma_defragmentation_info2.html#a3cf86ab32c1da779b4923d301a3056ba',1,'VmaDefragmentationInfo2::allocationCount()']]],
- ['allocationsizemax_5',['allocationSizeMax',['../struct_vma_detailed_statistics.html#a06b2add24eed3449a66ff151979a0201',1,'VmaDetailedStatistics']]],
- ['allocationsizemin_6',['allocationSizeMin',['../struct_vma_detailed_statistics.html#a6fb397e7487e10f2a52e241577d2a2b8',1,'VmaDetailedStatistics']]],
- ['allocationsmoved_7',['allocationsMoved',['../struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9',1,'VmaDefragmentationStats']]]
+ ['allocation_20names_20and_20user_20data_1',['Allocation names and user data',['../allocation_annotation.html',1,'index']]],
+ ['allocationbytes_2',['allocationBytes',['../struct_vma_statistics.html#a21db06eba3422f87a2b4b4703d879c16',1,'VmaStatistics']]],
+ ['allocationcount_3',['allocationCount',['../struct_vma_statistics.html#ab0ff76e50f58f9f54b6f265e5bf5dde2',1,'VmaStatistics']]],
+ ['allocationsizemax_4',['allocationSizeMax',['../struct_vma_detailed_statistics.html#a06b2add24eed3449a66ff151979a0201',1,'VmaDetailedStatistics']]],
+ ['allocationsizemin_5',['allocationSizeMin',['../struct_vma_detailed_statistics.html#a6fb397e7487e10f2a52e241577d2a2b8',1,'VmaDetailedStatistics']]],
+ ['allocationsmoved_6',['allocationsMoved',['../struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9',1,'VmaDefragmentationStats']]]
];
diff --git a/docs/html/search/all_11.js b/docs/html/search/all_11.js
index ac192d9..b5091c0 100644
--- a/docs/html/search/all_11.js
+++ b/docs/html/search/all_11.js
@@ -46,153 +46,157 @@ var searchData=
['vma_5fallocation_5fcreate_5fstrategy_5ffirst_5ffit_5fbit_43',['VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a33eb2052674f3ad92386c714a65fb777',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fstrategy_5fmask_44',['VMA_ALLOCATION_CREATE_STRATEGY_MASK',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a8e16845d81ae3d27c47106d4770d5c7e',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fstrategy_5fmin_5fmemory_5fbit_45',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a8af1210cf591784afa026d94998f735d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_46',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a0729e932b7ea170e3a128cad96c5cf6d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fupper_5faddress_5fbit_47',['VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fuser_5fdata_5fcopy_5fstring_5fbit_48',['VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fwithin_5fbudget_5fbit_49',['VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597ab8b1764f3e9022368e440c057783b92d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5famd_5fdevice_5fcoherent_5fmemory_5fbit_50',['VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca2acce4886d8078552efa38878413970f',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fbuffer_5fdevice_5faddress_5fbit_51',['VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca5f1b28b0414319d1687e1f2b30ab0089',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fext_5fmemory_5fbudget_5fbit_52',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4d4687863f7bd4b418c6006dc04400b0',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fext_5fmemory_5fpriority_5fbit_53',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7caffdd7a5169be3dbd7cbf6b3619e4f78a',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fexternally_5fsynchronized_5fbit_54',['VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fflag_5fbits_5fmax_5fenum_55',['VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fkhr_5fbind_5fmemory2_5fbit_56',['VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca8fb75bf07cd184ab903596295e863dee',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fkhr_5fdedicated_5fallocation_5fbit_57',['VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878',1,'vk_mem_alloc.h']]],
- ['vma_5fbind_5fmemory2_58',['VMA_BIND_MEMORY2',['../vk__mem__alloc_8h.html#a88bef97f86d70a34a4c0746e09a2680d',1,'vk_mem_alloc.h']]],
- ['vma_5fbuffer_5fdevice_5faddress_59',['VMA_BUFFER_DEVICE_ADDRESS',['../vk__mem__alloc_8h.html#a7f9d5e71b70dd1a137c303a8a8262c10',1,'vk_mem_alloc.h']]],
- ['vma_5fdedicated_5fallocation_60',['VMA_DEDICATED_ALLOCATION',['../vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4',1,'vk_mem_alloc.h']]],
- ['vma_5fdefragmentation_5fflag_5fbits_5fmax_5fenum_61',['VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cab87ec33154803bfeb5ac2b379f1d6a97',1,'vk_mem_alloc.h']]],
- ['vma_5fdefragmentation_5fflag_5fincremental_62',['VMA_DEFRAGMENTATION_FLAG_INCREMENTAL',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50ca31af49446af2459284a568ce2f3fdd33',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fbudget_63',['VMA_MEMORY_BUDGET',['../vk__mem__alloc_8h.html#a05decf1cf4ebf767beba7acca6c1ec3a',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fauto_64',['VMA_MEMORY_USAGE_AUTO',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fauto_5fprefer_5fdevice_65',['VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccae2adb696d6a73c18bb20c23666661327',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fauto_5fprefer_5fhost_66',['VMA_MEMORY_USAGE_AUTO_PREFER_HOST',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9b422585242160b8ed3418310ee6664d',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fcpu_5fcopy_67',['VMA_MEMORY_USAGE_CPU_COPY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca416a444d4d0fc20067c3f76f32ff2500',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fcpu_5fonly_68',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu_69',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fgpu_5flazily_5fallocated_70',['VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca835333d9072db63a653818030e17614d',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fgpu_5fonly_71',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fgpu_5fto_5fcpu_72',['VMA_MEMORY_USAGE_GPU_TO_CPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fmax_5fenum_73',['VMA_MEMORY_USAGE_MAX_ENUM',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5funknown_74',['VMA_MEMORY_USAGE_UNKNOWN',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5falgorithm_5fmask_75',['VMA_POOL_CREATE_ALGORITHM_MASK',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7af4d270f8f42517a0f70037ceb6ac1d9c',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5fbuddy_5falgorithm_5fbit_76',['VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a97a0dc38e5161b780594d998d313d35e',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5fflag_5fbits_5fmax_5fenum_77',['VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit_78',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5flinear_5falgorithm_5fbit_79',['VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5ftlsf_5falgorithm_5fbit_80',['VMA_POOL_CREATE_TLSF_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a855ee6e02e46d835ee28c8cd596b7e32',1,'vk_mem_alloc.h']]],
- ['vma_5fstats_5fstring_5fenabled_81',['VMA_STATS_STRING_ENABLED',['../vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum_82',['VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac1163c03ea837fa663462dc286d6a1a9',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmask_83',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac5b5e45c335368d18df59c9f27df17e3',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5fmemory_5fbit_84',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ae2a9591a62b5e3b1bdcbc81c6188a1bf',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_85',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a562d10a46012719d33167d3dc5dbbf9b',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fupper_5faddress_5fbit_86',['VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a9524a329a55b5ec390d57d90b67ad78e',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5falgorithm_5fmask_87',['VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaaf9487467136e1a9e371894dc3a7c4844',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5fbuddy_5falgorithm_5fbit_88',['VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa923116612509e26bf84982b9baf25c63',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5fflag_5fbits_5fmax_5fenum_89',['VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa5fc0d333c3d5687a8bbf57df9b377a87',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5flinear_5falgorithm_5fbit_90',['VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaae6423e2fa2f3c9211b21c819e3f10f96',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5ftlsf_5falgorithm_5fbit_91',['VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa4db7cb39f9c0f1a4b71c5f76b4cfa691',1,'vk_mem_alloc.h']]],
- ['vmaallocatememory_92',['vmaAllocateMemory',['../group__group__alloc.html#gabf28077dbf82d0908b8acbe8ee8dd9b8',1,'vk_mem_alloc.h']]],
- ['vmaallocatememoryforbuffer_93',['vmaAllocateMemoryForBuffer',['../group__group__alloc.html#ga7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
- ['vmaallocatememoryforimage_94',['vmaAllocateMemoryForImage',['../group__group__alloc.html#ga0faa3f9e5fb233d29d1e00390650febb',1,'vk_mem_alloc.h']]],
- ['vmaallocatememorypages_95',['vmaAllocateMemoryPages',['../group__group__alloc.html#gad37e82e492b3de38fc3f4cffd9ad0ae1',1,'vk_mem_alloc.h']]],
- ['vmaallocation_96',['VmaAllocation',['../struct_vma_allocation.html',1,'']]],
- ['vmaallocationcreateflagbits_97',['VmaAllocationCreateFlagBits',['../group__group__alloc.html#ga4fceecc301f4064dc808d3cd6c038941',1,'VmaAllocationCreateFlagBits(): vk_mem_alloc.h'],['../group__group__alloc.html#gad9889c10c798b040d59c92f257cae597',1,'VmaAllocationCreateFlagBits(): vk_mem_alloc.h']]],
- ['vmaallocationcreateflags_98',['VmaAllocationCreateFlags',['../group__group__alloc.html#ga5225e5e11f8376f6a31a1791f3d6e817',1,'vk_mem_alloc.h']]],
- ['vmaallocationcreateinfo_99',['VmaAllocationCreateInfo',['../struct_vma_allocation_create_info.html',1,'VmaAllocationCreateInfo'],['../group__group__alloc.html#ga3bf110892ea2fb4649fedb68488d026a',1,'VmaAllocationCreateInfo(): vk_mem_alloc.h']]],
- ['vmaallocationinfo_100',['VmaAllocationInfo',['../struct_vma_allocation_info.html',1,'VmaAllocationInfo'],['../group__group__alloc.html#ga1cf7774606721026a68aabe3af2e5b50',1,'VmaAllocationInfo(): vk_mem_alloc.h']]],
- ['vmaallocator_101',['VmaAllocator',['../struct_vma_allocator.html',1,'']]],
- ['vmaallocatorcreateflagbits_102',['VmaAllocatorCreateFlagBits',['../group__group__init.html#gafd73b95e737ee7e76f827cb5472f559f',1,'VmaAllocatorCreateFlagBits(): vk_mem_alloc.h'],['../group__group__init.html#ga4f87c9100d154a65a4ad495f7763cf7c',1,'VmaAllocatorCreateFlagBits(): vk_mem_alloc.h']]],
- ['vmaallocatorcreateflags_103',['VmaAllocatorCreateFlags',['../group__group__init.html#gacfe6863e160722c2c1bbcf7573fddc4d',1,'vk_mem_alloc.h']]],
- ['vmaallocatorcreateinfo_104',['VmaAllocatorCreateInfo',['../struct_vma_allocator_create_info.html',1,'VmaAllocatorCreateInfo'],['../group__group__init.html#gaad9652301d33759b83e52d4f3605a14a',1,'VmaAllocatorCreateInfo(): vk_mem_alloc.h']]],
- ['vmaallocatorinfo_105',['VmaAllocatorInfo',['../struct_vma_allocator_info.html',1,'VmaAllocatorInfo'],['../group__group__init.html#ga1988031b0223fdbd564250fa1edd942c',1,'VmaAllocatorInfo(): vk_mem_alloc.h']]],
- ['vmabegindefragmentationpass_106',['vmaBeginDefragmentationPass',['../group__group__alloc.html#gac0f01545b6262f7d4d128fc8f8e5c77b',1,'vk_mem_alloc.h']]],
- ['vmabindbuffermemory_107',['vmaBindBufferMemory',['../group__group__alloc.html#ga6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
- ['vmabindbuffermemory2_108',['vmaBindBufferMemory2',['../group__group__alloc.html#ga927c944f45e0f2941182abb6f608e64a',1,'vk_mem_alloc.h']]],
- ['vmabindimagememory_109',['vmaBindImageMemory',['../group__group__alloc.html#ga3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
- ['vmabindimagememory2_110',['vmaBindImageMemory2',['../group__group__alloc.html#gaa8251ee81b0045a443e35b8e8aa021bc',1,'vk_mem_alloc.h']]],
- ['vmabudget_111',['VmaBudget',['../struct_vma_budget.html',1,'VmaBudget'],['../group__group__stats.html#gaa078667e71b1ef24e87a6a30d128381d',1,'VmaBudget(): vk_mem_alloc.h']]],
- ['vmabuildstatsstring_112',['vmaBuildStatsString',['../group__group__stats.html#gaa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
- ['vmabuildvirtualblockstatsstring_113',['vmaBuildVirtualBlockStatsString',['../group__group__stats.html#ga52d810e1222c592e5d80556ad005f1e6',1,'vk_mem_alloc.h']]],
- ['vmacalculatepoolstatistics_114',['vmaCalculatePoolStatistics',['../group__group__stats.html#ga50ba0eb25d2b363b792be4645ca7a380',1,'vk_mem_alloc.h']]],
- ['vmacalculatestatistics_115',['vmaCalculateStatistics',['../group__group__stats.html#ga36f3484de7aa6cd6edc4de9edfa0ff59',1,'vk_mem_alloc.h']]],
- ['vmacalculatevirtualblockstatistics_116',['vmaCalculateVirtualBlockStatistics',['../group__group__virtual.html#ga93c5741bca44b43e5b849cacbd616098',1,'vk_mem_alloc.h']]],
- ['vmacheckcorruption_117',['vmaCheckCorruption',['../group__group__alloc.html#ga49329a7f030dafcf82f7b73334c22e98',1,'vk_mem_alloc.h']]],
- ['vmacheckpoolcorruption_118',['vmaCheckPoolCorruption',['../group__group__alloc.html#gad535935619c7a549bf837e1bb0068f89',1,'vk_mem_alloc.h']]],
- ['vmaclearvirtualblock_119',['vmaClearVirtualBlock',['../group__group__virtual.html#ga5eda6f55919fb05bd2f56a112590c571',1,'vk_mem_alloc.h']]],
- ['vmacreateallocator_120',['vmaCreateAllocator',['../group__group__init.html#ga200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
- ['vmacreatebuffer_121',['vmaCreateBuffer',['../group__group__alloc.html#gac72ee55598617e8eecca384e746bab51',1,'vk_mem_alloc.h']]],
- ['vmacreatebufferwithalignment_122',['vmaCreateBufferWithAlignment',['../group__group__alloc.html#gaa06a690013a0d01e60894ac378083834',1,'vk_mem_alloc.h']]],
- ['vmacreateimage_123',['vmaCreateImage',['../group__group__alloc.html#ga02a94f25679275851a53e82eacbcfc73',1,'vk_mem_alloc.h']]],
- ['vmacreatepool_124',['vmaCreatePool',['../group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50',1,'vk_mem_alloc.h']]],
- ['vmacreatevirtualblock_125',['vmaCreateVirtualBlock',['../group__group__virtual.html#gab585754076877265fdae33e5c40ef13b',1,'vk_mem_alloc.h']]],
- ['vmadefragment_126',['vmaDefragment',['../group__group__alloc.html#ga9f0f8f56db5f7f57fe4454f465142dac',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationbegin_127',['vmaDefragmentationBegin',['../group__group__alloc.html#ga36ba776fd7fd5cb1e9359fdc0d8e6e8a',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationcontext_128',['VmaDefragmentationContext',['../struct_vma_defragmentation_context.html',1,'']]],
- ['vmadefragmentationend_129',['vmaDefragmentationEnd',['../group__group__alloc.html#ga8774e20e91e245aae959ba63efa15dd2',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationflagbits_130',['VmaDefragmentationFlagBits',['../group__group__alloc.html#ga13415cc0b443353a7b5abda300b833fc',1,'VmaDefragmentationFlagBits(): vk_mem_alloc.h'],['../group__group__alloc.html#ga6552a65b71d16f378c6994b3ceaef50c',1,'VmaDefragmentationFlagBits(): vk_mem_alloc.h']]],
- ['vmadefragmentationflags_131',['VmaDefragmentationFlags',['../group__group__alloc.html#ga88a77cef37e5d3c4fc9eb328885d048d',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationinfo_132',['VmaDefragmentationInfo',['../struct_vma_defragmentation_info.html',1,'VmaDefragmentationInfo'],['../group__group__alloc.html#ga2bf47f96bf92bed2a49461bd9af3acfa',1,'VmaDefragmentationInfo(): vk_mem_alloc.h']]],
- ['vmadefragmentationinfo2_133',['VmaDefragmentationInfo2',['../struct_vma_defragmentation_info2.html',1,'VmaDefragmentationInfo2'],['../group__group__alloc.html#gad6daeffaa670ce6d11a203a6224c9937',1,'VmaDefragmentationInfo2(): vk_mem_alloc.h']]],
- ['vmadefragmentationpassinfo_134',['VmaDefragmentationPassInfo',['../struct_vma_defragmentation_pass_info.html',1,'VmaDefragmentationPassInfo'],['../group__group__alloc.html#ga72aebd522242d56abea67b4f47f6549e',1,'VmaDefragmentationPassInfo(): vk_mem_alloc.h']]],
- ['vmadefragmentationpassmoveinfo_135',['VmaDefragmentationPassMoveInfo',['../struct_vma_defragmentation_pass_move_info.html',1,'VmaDefragmentationPassMoveInfo'],['../group__group__alloc.html#gad6799e8e2b1527abfc84d33bc44aeaf5',1,'VmaDefragmentationPassMoveInfo(): vk_mem_alloc.h']]],
- ['vmadefragmentationstats_136',['VmaDefragmentationStats',['../struct_vma_defragmentation_stats.html',1,'VmaDefragmentationStats'],['../group__group__alloc.html#gad94034192259c2e34a4d1c5e27810403',1,'VmaDefragmentationStats(): vk_mem_alloc.h']]],
- ['vmadestroyallocator_137',['vmaDestroyAllocator',['../group__group__init.html#gaa8d164061c88f22fb1fd3c8f3534bc1d',1,'vk_mem_alloc.h']]],
- ['vmadestroybuffer_138',['vmaDestroyBuffer',['../group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77',1,'vk_mem_alloc.h']]],
- ['vmadestroyimage_139',['vmaDestroyImage',['../group__group__alloc.html#gae50d2cb3b4a3bfd4dd40987234e50e7e',1,'vk_mem_alloc.h']]],
- ['vmadestroypool_140',['vmaDestroyPool',['../group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1',1,'vk_mem_alloc.h']]],
- ['vmadestroyvirtualblock_141',['vmaDestroyVirtualBlock',['../group__group__virtual.html#ga3795f7783ae2c182cede067d656f66a5',1,'vk_mem_alloc.h']]],
- ['vmadetailedstatistics_142',['VmaDetailedStatistics',['../struct_vma_detailed_statistics.html',1,'VmaDetailedStatistics'],['../group__group__stats.html#ga9ab0c535a6ca655dc63b8609ab4b8394',1,'VmaDetailedStatistics(): vk_mem_alloc.h']]],
- ['vmadevicememorycallbacks_143',['VmaDeviceMemoryCallbacks',['../struct_vma_device_memory_callbacks.html',1,'VmaDeviceMemoryCallbacks'],['../group__group__init.html#ga77692d3c8770ea8882d573206bd27b2b',1,'VmaDeviceMemoryCallbacks(): vk_mem_alloc.h']]],
- ['vmaenddefragmentationpass_144',['vmaEndDefragmentationPass',['../group__group__alloc.html#ga1b9ffa538bed905af55c747cc48963bd',1,'vk_mem_alloc.h']]],
- ['vmafindmemorytypeindex_145',['vmaFindMemoryTypeIndex',['../group__group__alloc.html#gaef15a94b58fbcb0fe706d5720e84a74a',1,'vk_mem_alloc.h']]],
- ['vmafindmemorytypeindexforbufferinfo_146',['vmaFindMemoryTypeIndexForBufferInfo',['../group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888',1,'vk_mem_alloc.h']]],
- ['vmafindmemorytypeindexforimageinfo_147',['vmaFindMemoryTypeIndexForImageInfo',['../group__group__alloc.html#ga088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
- ['vmaflushallocation_148',['vmaFlushAllocation',['../group__group__alloc.html#ga30c37c1eec6025f397be41644f48490f',1,'vk_mem_alloc.h']]],
- ['vmaflushallocations_149',['vmaFlushAllocations',['../group__group__alloc.html#gac3dd00da721875ed99fa8a881922bdfc',1,'vk_mem_alloc.h']]],
- ['vmafreememory_150',['vmaFreeMemory',['../group__group__alloc.html#ga5fea5518972ae9094b1526cbcb19b05f',1,'vk_mem_alloc.h']]],
- ['vmafreememorypages_151',['vmaFreeMemoryPages',['../group__group__alloc.html#ga834b1e4aef395c0a1d56a28e69a4a17e',1,'vk_mem_alloc.h']]],
- ['vmafreestatsstring_152',['vmaFreeStatsString',['../group__group__stats.html#ga3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
- ['vmafreevirtualblockstatsstring_153',['vmaFreeVirtualBlockStatsString',['../group__group__stats.html#ga47fb8d8aa69df4a7c23a9719b4080623',1,'vk_mem_alloc.h']]],
- ['vmagetallocationinfo_154',['vmaGetAllocationInfo',['../group__group__alloc.html#ga86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
- ['vmagetallocationmemoryproperties_155',['vmaGetAllocationMemoryProperties',['../group__group__alloc.html#ga571e87dd38e552249b56b1b0b982fad1',1,'vk_mem_alloc.h']]],
- ['vmagetallocatorinfo_156',['vmaGetAllocatorInfo',['../group__group__init.html#gafa02231a791b37255720d566a52683e7',1,'vk_mem_alloc.h']]],
- ['vmagetheapbudgets_157',['vmaGetHeapBudgets',['../group__group__stats.html#ga9f88db9d46a432c0ad7278cecbc5eaa7',1,'vk_mem_alloc.h']]],
- ['vmagetmemoryproperties_158',['vmaGetMemoryProperties',['../group__group__init.html#gab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]],
- ['vmagetmemorytypeproperties_159',['vmaGetMemoryTypeProperties',['../group__group__init.html#ga8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]],
- ['vmagetphysicaldeviceproperties_160',['vmaGetPhysicalDeviceProperties',['../group__group__init.html#gaecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]],
- ['vmagetpoolname_161',['vmaGetPoolName',['../group__group__alloc.html#gaf09b4e4eafdbee812e8d73ddf960f030',1,'vk_mem_alloc.h']]],
- ['vmagetpoolstatistics_162',['vmaGetPoolStatistics',['../group__group__stats.html#ga34d8e7d83774eed0caee5c5ae88e217d',1,'vk_mem_alloc.h']]],
- ['vmagetvirtualallocationinfo_163',['vmaGetVirtualAllocationInfo',['../group__group__virtual.html#ga8ee14ceb1fe033ec84d8aa29e1f75afa',1,'vk_mem_alloc.h']]],
- ['vmagetvirtualblockstatistics_164',['vmaGetVirtualBlockStatistics',['../group__group__virtual.html#ga2902aa3130866afcc64bb5f984113db3',1,'vk_mem_alloc.h']]],
- ['vmainvalidateallocation_165',['vmaInvalidateAllocation',['../group__group__alloc.html#gaaa8412919139ef413a4215ac6a290fae',1,'vk_mem_alloc.h']]],
- ['vmainvalidateallocations_166',['vmaInvalidateAllocations',['../group__group__alloc.html#gab25b558d75f7378ec944a1522fdcc3c5',1,'vk_mem_alloc.h']]],
- ['vmaisvirtualblockempty_167',['vmaIsVirtualBlockEmpty',['../group__group__virtual.html#gacd53b5b1d23f8fcbad692ccfdc1811f1',1,'vk_mem_alloc.h']]],
- ['vmamapmemory_168',['vmaMapMemory',['../group__group__alloc.html#gad5bd1243512d099706de88168992f069',1,'vk_mem_alloc.h']]],
- ['vmamemoryusage_169',['VmaMemoryUsage',['../group__group__alloc.html#gaa5846affa1e9da3800e3e78fae2305cc',1,'VmaMemoryUsage(): vk_mem_alloc.h'],['../group__group__alloc.html#ga806e8499dde802e59eb72a1dc811c35f',1,'VmaMemoryUsage(): vk_mem_alloc.h']]],
- ['vmapool_170',['VmaPool',['../struct_vma_pool.html',1,'']]],
- ['vmapoolcreateflagbits_171',['VmaPoolCreateFlagBits',['../group__group__alloc.html#ga9a7c45f9c863695d98c83fa5ac940fe7',1,'VmaPoolCreateFlagBits(): vk_mem_alloc.h'],['../group__group__alloc.html#ga4d4f2efc2509157a9e4ecd4fd7942303',1,'VmaPoolCreateFlagBits(): vk_mem_alloc.h']]],
- ['vmapoolcreateflags_172',['VmaPoolCreateFlags',['../group__group__alloc.html#ga2770e325ea42e087c1b91fdf46d0292a',1,'vk_mem_alloc.h']]],
- ['vmapoolcreateinfo_173',['VmaPoolCreateInfo',['../struct_vma_pool_create_info.html',1,'VmaPoolCreateInfo'],['../group__group__alloc.html#ga1017aa83489c0eee8d2163d2bf253f67',1,'VmaPoolCreateInfo(): vk_mem_alloc.h']]],
- ['vmasetallocationuserdata_174',['vmaSetAllocationUserData',['../group__group__alloc.html#gaf9147d31ffc11d62fc187bde283ed14f',1,'vk_mem_alloc.h']]],
- ['vmasetcurrentframeindex_175',['vmaSetCurrentFrameIndex',['../group__group__init.html#gade56bf8dc9f5a5eaddf5f119ed525236',1,'vk_mem_alloc.h']]],
- ['vmasetpoolname_176',['vmaSetPoolName',['../group__group__alloc.html#gadbae3a0b4ab078024462fc85c37f3b58',1,'vk_mem_alloc.h']]],
- ['vmasetvirtualallocationuserdata_177',['vmaSetVirtualAllocationUserData',['../group__group__virtual.html#ga001ea1850458a4062b829e09c303fca2',1,'vk_mem_alloc.h']]],
- ['vmastatistics_178',['VmaStatistics',['../group__group__stats.html#gac94bd1a382a3922ddc8de3af4d3ddd06',1,'VmaStatistics(): vk_mem_alloc.h'],['../struct_vma_statistics.html',1,'VmaStatistics']]],
- ['vmatotalstatistics_179',['VmaTotalStatistics',['../struct_vma_total_statistics.html',1,'VmaTotalStatistics'],['../group__group__stats.html#ga68916e729e55d513f88ffafbadddb770',1,'VmaTotalStatistics(): vk_mem_alloc.h']]],
- ['vmaunmapmemory_180',['vmaUnmapMemory',['../group__group__alloc.html#ga9bc268595cb33f6ec4d519cfce81ff45',1,'vk_mem_alloc.h']]],
- ['vmavirtualallocate_181',['vmaVirtualAllocate',['../group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01',1,'vk_mem_alloc.h']]],
- ['vmavirtualallocation_182',['VmaVirtualAllocation',['../struct_vma_virtual_allocation.html',1,'']]],
- ['vmavirtualallocationcreateflagbits_183',['VmaVirtualAllocationCreateFlagBits',['../group__group__virtual.html#ga2e9c64d405b14156fea7e10c4ad06cb6',1,'VmaVirtualAllocationCreateFlagBits(): vk_mem_alloc.h'],['../group__group__virtual.html#ga936815e64946a6b6d812d08d10184c23',1,'VmaVirtualAllocationCreateFlagBits(): vk_mem_alloc.h']]],
- ['vmavirtualallocationcreateflags_184',['VmaVirtualAllocationCreateFlags',['../group__group__virtual.html#gae96ffc099bf898257fb19e9410ed08a7',1,'vk_mem_alloc.h']]],
- ['vmavirtualallocationcreateinfo_185',['VmaVirtualAllocationCreateInfo',['../struct_vma_virtual_allocation_create_info.html',1,'VmaVirtualAllocationCreateInfo'],['../group__group__virtual.html#gac3c90d80bedc6847a41b82d0e2158c9e',1,'VmaVirtualAllocationCreateInfo(): vk_mem_alloc.h']]],
- ['vmavirtualallocationinfo_186',['VmaVirtualAllocationInfo',['../struct_vma_virtual_allocation_info.html',1,'VmaVirtualAllocationInfo'],['../group__group__virtual.html#ga75bc33ff7cf18c98e101f570dc2a5ebc',1,'VmaVirtualAllocationInfo(): vk_mem_alloc.h']]],
- ['vmavirtualblock_187',['VmaVirtualBlock',['../struct_vma_virtual_block.html',1,'']]],
- ['vmavirtualblockcreateflagbits_188',['VmaVirtualBlockCreateFlagBits',['../group__group__virtual.html#ga88bcf8c1cd3bb1610ff7343811c65bca',1,'VmaVirtualBlockCreateFlagBits(): vk_mem_alloc.h'],['../group__group__virtual.html#ga0860ba1c0a67178fae4aecb63a78573e',1,'VmaVirtualBlockCreateFlagBits(): vk_mem_alloc.h']]],
- ['vmavirtualblockcreateflags_189',['VmaVirtualBlockCreateFlags',['../group__group__virtual.html#ga4e49c2f0ab7f6b4868833e5bac78d91e',1,'vk_mem_alloc.h']]],
- ['vmavirtualblockcreateinfo_190',['VmaVirtualBlockCreateInfo',['../group__group__virtual.html#ga4753d42d40217a3a652a3cdf253ad773',1,'VmaVirtualBlockCreateInfo(): vk_mem_alloc.h'],['../struct_vma_virtual_block_create_info.html',1,'VmaVirtualBlockCreateInfo']]],
- ['vmavirtualfree_191',['vmaVirtualFree',['../group__group__virtual.html#ga09fc688c0c3653ff23723b037e5d5033',1,'vk_mem_alloc.h']]],
- ['vmavulkanfunctions_192',['VmaVulkanFunctions',['../group__group__init.html#gabb0a8e3b5040d847571cca6c7f9a8074',1,'VmaVulkanFunctions(): vk_mem_alloc.h'],['../struct_vma_vulkan_functions.html',1,'VmaVulkanFunctions']]],
- ['vulkan_20memory_20allocator_193',['Vulkan Memory Allocator',['../index.html',1,'']]],
- ['vulkanapiversion_194',['vulkanApiVersion',['../struct_vma_allocator_create_info.html#ae0ffc55139b54520a6bb704b29ffc285',1,'VmaAllocatorCreateInfo']]]
+ ['vma_5fallocation_5fcreate_5fstrategy_5fmin_5foffset_5fbit_46',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a8099acedc0d04cdccaaddcfe37fd227d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_47',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a0729e932b7ea170e3a128cad96c5cf6d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fupper_5faddress_5fbit_48',['VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fuser_5fdata_5fcopy_5fstring_5fbit_49',['VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fwithin_5fbudget_5fbit_50',['VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597ab8b1764f3e9022368e440c057783b92d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5famd_5fdevice_5fcoherent_5fmemory_5fbit_51',['VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca2acce4886d8078552efa38878413970f',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fbuffer_5fdevice_5faddress_5fbit_52',['VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca5f1b28b0414319d1687e1f2b30ab0089',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fext_5fmemory_5fbudget_5fbit_53',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4d4687863f7bd4b418c6006dc04400b0',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fext_5fmemory_5fpriority_5fbit_54',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7caffdd7a5169be3dbd7cbf6b3619e4f78a',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fexternally_5fsynchronized_5fbit_55',['VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fflag_5fbits_5fmax_5fenum_56',['VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fkhr_5fbind_5fmemory2_5fbit_57',['VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca8fb75bf07cd184ab903596295e863dee',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fkhr_5fdedicated_5fallocation_5fbit_58',['VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878',1,'vk_mem_alloc.h']]],
+ ['vma_5fbind_5fmemory2_59',['VMA_BIND_MEMORY2',['../vk__mem__alloc_8h.html#a88bef97f86d70a34a4c0746e09a2680d',1,'vk_mem_alloc.h']]],
+ ['vma_5fbuffer_5fdevice_5faddress_60',['VMA_BUFFER_DEVICE_ADDRESS',['../vk__mem__alloc_8h.html#a7f9d5e71b70dd1a137c303a8a8262c10',1,'vk_mem_alloc.h']]],
+ ['vma_5fdedicated_5fallocation_61',['VMA_DEDICATED_ALLOCATION',['../vk__mem__alloc_8h.html#af7b860e63b96d11e44ae8587ba06bbf4',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5fbalanced_5fbit_62',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50caec35a4138111605a6ff32ca61aa871b6',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5fextensive_5fbit_63',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cae45a9469e5337731627758671741e412',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5ffast_5fbit_64',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50ca2e6469bcf5a094776ceb5d118263f04b',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5ffull_5fbit_65',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cafa162eac5be800bcdd4011427a71156d',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5fmask_66',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cabcbbdb3bfd53c4c3ab4eaeb5fd4894e9',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5fbits_5fmax_5fenum_67',['VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cab87ec33154803bfeb5ac2b379f1d6a97',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fmove_5foperation_5fcopy_68',['VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY',['../group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257ad4a06ac46c4cb1c67b0ebc1edfab9f18',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fmove_5foperation_5fdestroy_69',['VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY',['../group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257a9786f8492a9be2c03bd26395e352ab85',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fmove_5foperation_5fignore_70',['VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE',['../group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257ad25bc6f816b226b4fd5170e845f218d2',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fbudget_71',['VMA_MEMORY_BUDGET',['../vk__mem__alloc_8h.html#a05decf1cf4ebf767beba7acca6c1ec3a',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fauto_72',['VMA_MEMORY_USAGE_AUTO',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fauto_5fprefer_5fdevice_73',['VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccae2adb696d6a73c18bb20c23666661327',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fauto_5fprefer_5fhost_74',['VMA_MEMORY_USAGE_AUTO_PREFER_HOST',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9b422585242160b8ed3418310ee6664d',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fcpu_5fcopy_75',['VMA_MEMORY_USAGE_CPU_COPY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca416a444d4d0fc20067c3f76f32ff2500',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fcpu_5fonly_76',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu_77',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fgpu_5flazily_5fallocated_78',['VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca835333d9072db63a653818030e17614d',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fgpu_5fonly_79',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fgpu_5fto_5fcpu_80',['VMA_MEMORY_USAGE_GPU_TO_CPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fmax_5fenum_81',['VMA_MEMORY_USAGE_MAX_ENUM',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5funknown_82',['VMA_MEMORY_USAGE_UNKNOWN',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5falgorithm_5fmask_83',['VMA_POOL_CREATE_ALGORITHM_MASK',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7af4d270f8f42517a0f70037ceb6ac1d9c',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5fflag_5fbits_5fmax_5fenum_84',['VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit_85',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5flinear_5falgorithm_5fbit_86',['VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726',1,'vk_mem_alloc.h']]],
+ ['vma_5fstats_5fstring_5fenabled_87',['VMA_STATS_STRING_ENABLED',['../vk__mem__alloc_8h.html#ae25f0d55fd91cb166f002b63244800e1',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum_88',['VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac1163c03ea837fa663462dc286d6a1a9',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmask_89',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac5b5e45c335368d18df59c9f27df17e3',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5fmemory_5fbit_90',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ae2a9591a62b5e3b1bdcbc81c6188a1bf',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_91',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a562d10a46012719d33167d3dc5dbbf9b',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fpacked_5fbit_92',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_PACKED_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a3c3c4952631d8c35649537a675adc401',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fupper_5faddress_5fbit_93',['VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a9524a329a55b5ec390d57d90b67ad78e',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fblock_5fcreate_5falgorithm_5fmask_94',['VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaaf9487467136e1a9e371894dc3a7c4844',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fblock_5fcreate_5fflag_5fbits_5fmax_5fenum_95',['VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa5fc0d333c3d5687a8bbf57df9b377a87',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fblock_5fcreate_5flinear_5falgorithm_5fbit_96',['VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaae6423e2fa2f3c9211b21c819e3f10f96',1,'vk_mem_alloc.h']]],
+ ['vmaallocatememory_97',['vmaAllocateMemory',['../group__group__alloc.html#gabf28077dbf82d0908b8acbe8ee8dd9b8',1,'vk_mem_alloc.h']]],
+ ['vmaallocatememoryforbuffer_98',['vmaAllocateMemoryForBuffer',['../group__group__alloc.html#ga7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
+ ['vmaallocatememoryforimage_99',['vmaAllocateMemoryForImage',['../group__group__alloc.html#ga0faa3f9e5fb233d29d1e00390650febb',1,'vk_mem_alloc.h']]],
+ ['vmaallocatememorypages_100',['vmaAllocateMemoryPages',['../group__group__alloc.html#gad37e82e492b3de38fc3f4cffd9ad0ae1',1,'vk_mem_alloc.h']]],
+ ['vmaallocation_101',['VmaAllocation',['../struct_vma_allocation.html',1,'']]],
+ ['vmaallocationcreateflagbits_102',['VmaAllocationCreateFlagBits',['../group__group__alloc.html#ga4fceecc301f4064dc808d3cd6c038941',1,'VmaAllocationCreateFlagBits(): vk_mem_alloc.h'],['../group__group__alloc.html#gad9889c10c798b040d59c92f257cae597',1,'VmaAllocationCreateFlagBits(): vk_mem_alloc.h']]],
+ ['vmaallocationcreateflags_103',['VmaAllocationCreateFlags',['../group__group__alloc.html#ga5225e5e11f8376f6a31a1791f3d6e817',1,'vk_mem_alloc.h']]],
+ ['vmaallocationcreateinfo_104',['VmaAllocationCreateInfo',['../struct_vma_allocation_create_info.html',1,'VmaAllocationCreateInfo'],['../group__group__alloc.html#ga3bf110892ea2fb4649fedb68488d026a',1,'VmaAllocationCreateInfo(): vk_mem_alloc.h']]],
+ ['vmaallocationinfo_105',['VmaAllocationInfo',['../struct_vma_allocation_info.html',1,'VmaAllocationInfo'],['../group__group__alloc.html#ga1cf7774606721026a68aabe3af2e5b50',1,'VmaAllocationInfo(): vk_mem_alloc.h']]],
+ ['vmaallocator_106',['VmaAllocator',['../struct_vma_allocator.html',1,'']]],
+ ['vmaallocatorcreateflagbits_107',['VmaAllocatorCreateFlagBits',['../group__group__init.html#ga4f87c9100d154a65a4ad495f7763cf7c',1,'VmaAllocatorCreateFlagBits(): vk_mem_alloc.h'],['../group__group__init.html#gafd73b95e737ee7e76f827cb5472f559f',1,'VmaAllocatorCreateFlagBits(): vk_mem_alloc.h']]],
+ ['vmaallocatorcreateflags_108',['VmaAllocatorCreateFlags',['../group__group__init.html#gacfe6863e160722c2c1bbcf7573fddc4d',1,'vk_mem_alloc.h']]],
+ ['vmaallocatorcreateinfo_109',['VmaAllocatorCreateInfo',['../struct_vma_allocator_create_info.html',1,'VmaAllocatorCreateInfo'],['../group__group__init.html#gaad9652301d33759b83e52d4f3605a14a',1,'VmaAllocatorCreateInfo(): vk_mem_alloc.h']]],
+ ['vmaallocatorinfo_110',['VmaAllocatorInfo',['../struct_vma_allocator_info.html',1,'VmaAllocatorInfo'],['../group__group__init.html#ga1988031b0223fdbd564250fa1edd942c',1,'VmaAllocatorInfo(): vk_mem_alloc.h']]],
+ ['vmabegindefragmentation_111',['vmaBeginDefragmentation',['../group__group__alloc.html#gac3335566858b45541fa9c0d7a6bbb57e',1,'vk_mem_alloc.h']]],
+ ['vmabegindefragmentationpass_112',['vmaBeginDefragmentationPass',['../group__group__alloc.html#ga980d7da2ce3b1fd5c8b8476bc362cc00',1,'vk_mem_alloc.h']]],
+ ['vmabindbuffermemory_113',['vmaBindBufferMemory',['../group__group__alloc.html#ga6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
+ ['vmabindbuffermemory2_114',['vmaBindBufferMemory2',['../group__group__alloc.html#ga927c944f45e0f2941182abb6f608e64a',1,'vk_mem_alloc.h']]],
+ ['vmabindimagememory_115',['vmaBindImageMemory',['../group__group__alloc.html#ga3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
+ ['vmabindimagememory2_116',['vmaBindImageMemory2',['../group__group__alloc.html#gaa8251ee81b0045a443e35b8e8aa021bc',1,'vk_mem_alloc.h']]],
+ ['vmabudget_117',['VmaBudget',['../struct_vma_budget.html',1,'VmaBudget'],['../group__group__stats.html#gaa078667e71b1ef24e87a6a30d128381d',1,'VmaBudget(): vk_mem_alloc.h']]],
+ ['vmabuildstatsstring_118',['vmaBuildStatsString',['../group__group__stats.html#gaa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
+ ['vmabuildvirtualblockstatsstring_119',['vmaBuildVirtualBlockStatsString',['../group__group__stats.html#ga52d810e1222c592e5d80556ad005f1e6',1,'vk_mem_alloc.h']]],
+ ['vmacalculatepoolstatistics_120',['vmaCalculatePoolStatistics',['../group__group__stats.html#ga50ba0eb25d2b363b792be4645ca7a380',1,'vk_mem_alloc.h']]],
+ ['vmacalculatestatistics_121',['vmaCalculateStatistics',['../group__group__stats.html#ga36f3484de7aa6cd6edc4de9edfa0ff59',1,'vk_mem_alloc.h']]],
+ ['vmacalculatevirtualblockstatistics_122',['vmaCalculateVirtualBlockStatistics',['../group__group__virtual.html#ga93c5741bca44b43e5b849cacbd616098',1,'vk_mem_alloc.h']]],
+ ['vmacheckcorruption_123',['vmaCheckCorruption',['../group__group__alloc.html#ga49329a7f030dafcf82f7b73334c22e98',1,'vk_mem_alloc.h']]],
+ ['vmacheckpoolcorruption_124',['vmaCheckPoolCorruption',['../group__group__alloc.html#gad535935619c7a549bf837e1bb0068f89',1,'vk_mem_alloc.h']]],
+ ['vmaclearvirtualblock_125',['vmaClearVirtualBlock',['../group__group__virtual.html#ga5eda6f55919fb05bd2f56a112590c571',1,'vk_mem_alloc.h']]],
+ ['vmacreateallocator_126',['vmaCreateAllocator',['../group__group__init.html#ga200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
+ ['vmacreatebuffer_127',['vmaCreateBuffer',['../group__group__alloc.html#gac72ee55598617e8eecca384e746bab51',1,'vk_mem_alloc.h']]],
+ ['vmacreatebufferwithalignment_128',['vmaCreateBufferWithAlignment',['../group__group__alloc.html#gaa06a690013a0d01e60894ac378083834',1,'vk_mem_alloc.h']]],
+ ['vmacreateimage_129',['vmaCreateImage',['../group__group__alloc.html#ga02a94f25679275851a53e82eacbcfc73',1,'vk_mem_alloc.h']]],
+ ['vmacreatepool_130',['vmaCreatePool',['../group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50',1,'vk_mem_alloc.h']]],
+ ['vmacreatevirtualblock_131',['vmaCreateVirtualBlock',['../group__group__virtual.html#gab585754076877265fdae33e5c40ef13b',1,'vk_mem_alloc.h']]],
+ ['vmadefragmentationcontext_132',['VmaDefragmentationContext',['../struct_vma_defragmentation_context.html',1,'']]],
+ ['vmadefragmentationflagbits_133',['VmaDefragmentationFlagBits',['../group__group__alloc.html#ga13415cc0b443353a7b5abda300b833fc',1,'VmaDefragmentationFlagBits(): vk_mem_alloc.h'],['../group__group__alloc.html#ga6552a65b71d16f378c6994b3ceaef50c',1,'VmaDefragmentationFlagBits(): vk_mem_alloc.h']]],
+ ['vmadefragmentationflags_134',['VmaDefragmentationFlags',['../group__group__alloc.html#ga88a77cef37e5d3c4fc9eb328885d048d',1,'vk_mem_alloc.h']]],
+ ['vmadefragmentationinfo_135',['VmaDefragmentationInfo',['../struct_vma_defragmentation_info.html',1,'VmaDefragmentationInfo'],['../group__group__alloc.html#ga2bf47f96bf92bed2a49461bd9af3acfa',1,'VmaDefragmentationInfo(): vk_mem_alloc.h']]],
+ ['vmadefragmentationmove_136',['VmaDefragmentationMove',['../struct_vma_defragmentation_move.html',1,'VmaDefragmentationMove'],['../group__group__alloc.html#ga563f4b43d3e31ed603d80cacc9ba8589',1,'VmaDefragmentationMove(): vk_mem_alloc.h']]],
+ ['vmadefragmentationmoveoperation_137',['VmaDefragmentationMoveOperation',['../group__group__alloc.html#ga2ea666deeb3c2c74806a097e27cdb4a1',1,'VmaDefragmentationMoveOperation(): vk_mem_alloc.h'],['../group__group__alloc.html#gada9e3861caf96f08894b0bcc160ec257',1,'VmaDefragmentationMoveOperation(): vk_mem_alloc.h']]],
+ ['vmadefragmentationpassmoveinfo_138',['VmaDefragmentationPassMoveInfo',['../struct_vma_defragmentation_pass_move_info.html',1,'VmaDefragmentationPassMoveInfo'],['../group__group__alloc.html#gad6799e8e2b1527abfc84d33bc44aeaf5',1,'VmaDefragmentationPassMoveInfo(): vk_mem_alloc.h']]],
+ ['vmadefragmentationstats_139',['VmaDefragmentationStats',['../struct_vma_defragmentation_stats.html',1,'VmaDefragmentationStats'],['../group__group__alloc.html#gad94034192259c2e34a4d1c5e27810403',1,'VmaDefragmentationStats(): vk_mem_alloc.h']]],
+ ['vmadestroyallocator_140',['vmaDestroyAllocator',['../group__group__init.html#gaa8d164061c88f22fb1fd3c8f3534bc1d',1,'vk_mem_alloc.h']]],
+ ['vmadestroybuffer_141',['vmaDestroyBuffer',['../group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77',1,'vk_mem_alloc.h']]],
+ ['vmadestroyimage_142',['vmaDestroyImage',['../group__group__alloc.html#gae50d2cb3b4a3bfd4dd40987234e50e7e',1,'vk_mem_alloc.h']]],
+ ['vmadestroypool_143',['vmaDestroyPool',['../group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1',1,'vk_mem_alloc.h']]],
+ ['vmadestroyvirtualblock_144',['vmaDestroyVirtualBlock',['../group__group__virtual.html#ga3795f7783ae2c182cede067d656f66a5',1,'vk_mem_alloc.h']]],
+ ['vmadetailedstatistics_145',['VmaDetailedStatistics',['../struct_vma_detailed_statistics.html',1,'VmaDetailedStatistics'],['../group__group__stats.html#ga9ab0c535a6ca655dc63b8609ab4b8394',1,'VmaDetailedStatistics(): vk_mem_alloc.h']]],
+ ['vmadevicememorycallbacks_146',['VmaDeviceMemoryCallbacks',['../struct_vma_device_memory_callbacks.html',1,'VmaDeviceMemoryCallbacks'],['../group__group__init.html#ga77692d3c8770ea8882d573206bd27b2b',1,'VmaDeviceMemoryCallbacks(): vk_mem_alloc.h']]],
+ ['vmaenddefragmentation_147',['vmaEndDefragmentation',['../group__group__alloc.html#ga729a594b45ae1681096940a44f3eb174',1,'vk_mem_alloc.h']]],
+ ['vmaenddefragmentationpass_148',['vmaEndDefragmentationPass',['../group__group__alloc.html#gaded05a445742a00718ee766144c5c226',1,'vk_mem_alloc.h']]],
+ ['vmafindmemorytypeindex_149',['vmaFindMemoryTypeIndex',['../group__group__alloc.html#gaef15a94b58fbcb0fe706d5720e84a74a',1,'vk_mem_alloc.h']]],
+ ['vmafindmemorytypeindexforbufferinfo_150',['vmaFindMemoryTypeIndexForBufferInfo',['../group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888',1,'vk_mem_alloc.h']]],
+ ['vmafindmemorytypeindexforimageinfo_151',['vmaFindMemoryTypeIndexForImageInfo',['../group__group__alloc.html#ga088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
+ ['vmaflushallocation_152',['vmaFlushAllocation',['../group__group__alloc.html#ga30c37c1eec6025f397be41644f48490f',1,'vk_mem_alloc.h']]],
+ ['vmaflushallocations_153',['vmaFlushAllocations',['../group__group__alloc.html#gac3dd00da721875ed99fa8a881922bdfc',1,'vk_mem_alloc.h']]],
+ ['vmafreememory_154',['vmaFreeMemory',['../group__group__alloc.html#ga5fea5518972ae9094b1526cbcb19b05f',1,'vk_mem_alloc.h']]],
+ ['vmafreememorypages_155',['vmaFreeMemoryPages',['../group__group__alloc.html#ga834b1e4aef395c0a1d56a28e69a4a17e',1,'vk_mem_alloc.h']]],
+ ['vmafreestatsstring_156',['vmaFreeStatsString',['../group__group__stats.html#ga3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
+ ['vmafreevirtualblockstatsstring_157',['vmaFreeVirtualBlockStatsString',['../group__group__stats.html#ga47fb8d8aa69df4a7c23a9719b4080623',1,'vk_mem_alloc.h']]],
+ ['vmagetallocationinfo_158',['vmaGetAllocationInfo',['../group__group__alloc.html#ga86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
+ ['vmagetallocationmemoryproperties_159',['vmaGetAllocationMemoryProperties',['../group__group__alloc.html#ga571e87dd38e552249b56b1b0b982fad1',1,'vk_mem_alloc.h']]],
+ ['vmagetallocatorinfo_160',['vmaGetAllocatorInfo',['../group__group__init.html#gafa02231a791b37255720d566a52683e7',1,'vk_mem_alloc.h']]],
+ ['vmagetheapbudgets_161',['vmaGetHeapBudgets',['../group__group__stats.html#ga9f88db9d46a432c0ad7278cecbc5eaa7',1,'vk_mem_alloc.h']]],
+ ['vmagetmemoryproperties_162',['vmaGetMemoryProperties',['../group__group__init.html#gab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]],
+ ['vmagetmemorytypeproperties_163',['vmaGetMemoryTypeProperties',['../group__group__init.html#ga8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]],
+ ['vmagetphysicaldeviceproperties_164',['vmaGetPhysicalDeviceProperties',['../group__group__init.html#gaecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]],
+ ['vmagetpoolname_165',['vmaGetPoolName',['../group__group__alloc.html#gaf09b4e4eafdbee812e8d73ddf960f030',1,'vk_mem_alloc.h']]],
+ ['vmagetpoolstatistics_166',['vmaGetPoolStatistics',['../group__group__stats.html#ga34d8e7d83774eed0caee5c5ae88e217d',1,'vk_mem_alloc.h']]],
+ ['vmagetvirtualallocationinfo_167',['vmaGetVirtualAllocationInfo',['../group__group__virtual.html#ga8ee14ceb1fe033ec84d8aa29e1f75afa',1,'vk_mem_alloc.h']]],
+ ['vmagetvirtualblockstatistics_168',['vmaGetVirtualBlockStatistics',['../group__group__virtual.html#ga2902aa3130866afcc64bb5f984113db3',1,'vk_mem_alloc.h']]],
+ ['vmainvalidateallocation_169',['vmaInvalidateAllocation',['../group__group__alloc.html#gaaa8412919139ef413a4215ac6a290fae',1,'vk_mem_alloc.h']]],
+ ['vmainvalidateallocations_170',['vmaInvalidateAllocations',['../group__group__alloc.html#gab25b558d75f7378ec944a1522fdcc3c5',1,'vk_mem_alloc.h']]],
+ ['vmaisvirtualblockempty_171',['vmaIsVirtualBlockEmpty',['../group__group__virtual.html#gacd53b5b1d23f8fcbad692ccfdc1811f1',1,'vk_mem_alloc.h']]],
+ ['vmamapmemory_172',['vmaMapMemory',['../group__group__alloc.html#gad5bd1243512d099706de88168992f069',1,'vk_mem_alloc.h']]],
+ ['vmamemoryusage_173',['VmaMemoryUsage',['../group__group__alloc.html#gaa5846affa1e9da3800e3e78fae2305cc',1,'VmaMemoryUsage(): vk_mem_alloc.h'],['../group__group__alloc.html#ga806e8499dde802e59eb72a1dc811c35f',1,'VmaMemoryUsage(): vk_mem_alloc.h']]],
+ ['vmapool_174',['VmaPool',['../struct_vma_pool.html',1,'']]],
+ ['vmapoolcreateflagbits_175',['VmaPoolCreateFlagBits',['../group__group__alloc.html#ga4d4f2efc2509157a9e4ecd4fd7942303',1,'VmaPoolCreateFlagBits(): vk_mem_alloc.h'],['../group__group__alloc.html#ga9a7c45f9c863695d98c83fa5ac940fe7',1,'VmaPoolCreateFlagBits(): vk_mem_alloc.h']]],
+ ['vmapoolcreateflags_176',['VmaPoolCreateFlags',['../group__group__alloc.html#ga2770e325ea42e087c1b91fdf46d0292a',1,'vk_mem_alloc.h']]],
+ ['vmapoolcreateinfo_177',['VmaPoolCreateInfo',['../struct_vma_pool_create_info.html',1,'VmaPoolCreateInfo'],['../group__group__alloc.html#ga1017aa83489c0eee8d2163d2bf253f67',1,'VmaPoolCreateInfo(): vk_mem_alloc.h']]],
+ ['vmasetallocationuserdata_178',['vmaSetAllocationUserData',['../group__group__alloc.html#gaf9147d31ffc11d62fc187bde283ed14f',1,'vk_mem_alloc.h']]],
+ ['vmasetcurrentframeindex_179',['vmaSetCurrentFrameIndex',['../group__group__init.html#gade56bf8dc9f5a5eaddf5f119ed525236',1,'vk_mem_alloc.h']]],
+ ['vmasetpoolname_180',['vmaSetPoolName',['../group__group__alloc.html#gadbae3a0b4ab078024462fc85c37f3b58',1,'vk_mem_alloc.h']]],
+ ['vmasetvirtualallocationuserdata_181',['vmaSetVirtualAllocationUserData',['../group__group__virtual.html#ga001ea1850458a4062b829e09c303fca2',1,'vk_mem_alloc.h']]],
+ ['vmastatistics_182',['VmaStatistics',['../struct_vma_statistics.html',1,'VmaStatistics'],['../group__group__stats.html#gac94bd1a382a3922ddc8de3af4d3ddd06',1,'VmaStatistics(): vk_mem_alloc.h']]],
+ ['vmatotalstatistics_183',['VmaTotalStatistics',['../group__group__stats.html#ga68916e729e55d513f88ffafbadddb770',1,'VmaTotalStatistics(): vk_mem_alloc.h'],['../struct_vma_total_statistics.html',1,'VmaTotalStatistics']]],
+ ['vmaunmapmemory_184',['vmaUnmapMemory',['../group__group__alloc.html#ga9bc268595cb33f6ec4d519cfce81ff45',1,'vk_mem_alloc.h']]],
+ ['vmavirtualallocate_185',['vmaVirtualAllocate',['../group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01',1,'vk_mem_alloc.h']]],
+ ['vmavirtualallocation_186',['VmaVirtualAllocation',['../struct_vma_virtual_allocation.html',1,'']]],
+ ['vmavirtualallocationcreateflagbits_187',['VmaVirtualAllocationCreateFlagBits',['../group__group__virtual.html#ga2e9c64d405b14156fea7e10c4ad06cb6',1,'VmaVirtualAllocationCreateFlagBits(): vk_mem_alloc.h'],['../group__group__virtual.html#ga936815e64946a6b6d812d08d10184c23',1,'VmaVirtualAllocationCreateFlagBits(): vk_mem_alloc.h']]],
+ ['vmavirtualallocationcreateflags_188',['VmaVirtualAllocationCreateFlags',['../group__group__virtual.html#gae96ffc099bf898257fb19e9410ed08a7',1,'vk_mem_alloc.h']]],
+ ['vmavirtualallocationcreateinfo_189',['VmaVirtualAllocationCreateInfo',['../struct_vma_virtual_allocation_create_info.html',1,'VmaVirtualAllocationCreateInfo'],['../group__group__virtual.html#gac3c90d80bedc6847a41b82d0e2158c9e',1,'VmaVirtualAllocationCreateInfo(): vk_mem_alloc.h']]],
+ ['vmavirtualallocationinfo_190',['VmaVirtualAllocationInfo',['../struct_vma_virtual_allocation_info.html',1,'VmaVirtualAllocationInfo'],['../group__group__virtual.html#ga75bc33ff7cf18c98e101f570dc2a5ebc',1,'VmaVirtualAllocationInfo(): vk_mem_alloc.h']]],
+ ['vmavirtualblock_191',['VmaVirtualBlock',['../struct_vma_virtual_block.html',1,'']]],
+ ['vmavirtualblockcreateflagbits_192',['VmaVirtualBlockCreateFlagBits',['../group__group__virtual.html#ga88bcf8c1cd3bb1610ff7343811c65bca',1,'VmaVirtualBlockCreateFlagBits(): vk_mem_alloc.h'],['../group__group__virtual.html#ga0860ba1c0a67178fae4aecb63a78573e',1,'VmaVirtualBlockCreateFlagBits(): vk_mem_alloc.h']]],
+ ['vmavirtualblockcreateflags_193',['VmaVirtualBlockCreateFlags',['../group__group__virtual.html#ga4e49c2f0ab7f6b4868833e5bac78d91e',1,'vk_mem_alloc.h']]],
+ ['vmavirtualblockcreateinfo_194',['VmaVirtualBlockCreateInfo',['../group__group__virtual.html#ga4753d42d40217a3a652a3cdf253ad773',1,'VmaVirtualBlockCreateInfo(): vk_mem_alloc.h'],['../struct_vma_virtual_block_create_info.html',1,'VmaVirtualBlockCreateInfo']]],
+ ['vmavirtualfree_195',['vmaVirtualFree',['../group__group__virtual.html#ga09fc688c0c3653ff23723b037e5d5033',1,'vk_mem_alloc.h']]],
+ ['vmavulkanfunctions_196',['VmaVulkanFunctions',['../group__group__init.html#gabb0a8e3b5040d847571cca6c7f9a8074',1,'VmaVulkanFunctions(): vk_mem_alloc.h'],['../struct_vma_vulkan_functions.html',1,'VmaVulkanFunctions']]],
+ ['vulkan_20memory_20allocator_197',['Vulkan Memory Allocator',['../index.html',1,'']]],
+ ['vulkanapiversion_198',['vulkanApiVersion',['../struct_vma_allocator_create_info.html#ae0ffc55139b54520a6bb704b29ffc285',1,'VmaAllocatorCreateInfo']]]
];
diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js
index d1c3dd6..c6b8c74 100644
--- a/docs/html/search/all_2.js
+++ b/docs/html/search/all_2.js
@@ -1,7 +1,6 @@
var searchData=
[
['choosing_20memory_20type_0',['Choosing memory type',['../choosing_memory_type.html',1,'index']]],
- ['commandbuffer_1',['commandBuffer',['../struct_vma_defragmentation_info2.html#a7f71f39590c5316771493d2333f9c1bd',1,'VmaDefragmentationInfo2']]],
- ['configuration_2',['Configuration',['../configuration.html',1,'index']]],
- ['custom_20memory_20pools_3',['Custom memory pools',['../custom_memory_pools.html',1,'index']]]
+ ['configuration_1',['Configuration',['../configuration.html',1,'index']]],
+ ['custom_20memory_20pools_2',['Custom memory pools',['../custom_memory_pools.html',1,'index']]]
];
diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js
index 29694e9..bc4a061 100644
--- a/docs/html/search/all_3.js
+++ b/docs/html/search/all_3.js
@@ -5,5 +5,7 @@ var searchData=
['deprecated_20list_2',['Deprecated List',['../deprecated.html',1,'']]],
['device_3',['device',['../struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500',1,'VmaAllocatorCreateInfo::device()'],['../struct_vma_allocator_info.html#a012b4c485bf3b0ea8921352c5ee0c357',1,'VmaAllocatorInfo::device()']]],
['devicememory_4',['deviceMemory',['../struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67',1,'VmaAllocationInfo']]],
- ['devicememoryblocksfreed_5',['deviceMemoryBlocksFreed',['../struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b',1,'VmaDefragmentationStats']]]
+ ['devicememoryblocksfreed_5',['deviceMemoryBlocksFreed',['../struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b',1,'VmaDefragmentationStats']]],
+ ['dstmemory_6',['dstMemory',['../struct_vma_defragmentation_move.html#a382fbec8dac2747abdc1883b69ef9458',1,'VmaDefragmentationMove']]],
+ ['dstoffset_7',['dstOffset',['../struct_vma_defragmentation_move.html#a80c466b445bc272f82c7dbf1a971ba18',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js
index 00173a3..ed45c51 100644
--- a/docs/html/search/all_5.js
+++ b/docs/html/search/all_5.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['flags_0',['flags',['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()'],['../struct_vma_defragmentation_info2.html#a53e844ee5633e229cf6daf14b2d9fff9',1,'VmaDefragmentationInfo2::flags()'],['../struct_vma_virtual_block_create_info.html#aaab9bf7e2d228c02ab6d90a72a6e6912',1,'VmaVirtualBlockCreateInfo::flags()'],['../struct_vma_virtual_allocation_create_info.html#ab10e16956cc4bf20ced9de77d1129ea4',1,'VmaVirtualAllocationCreateInfo::flags()']]]
+ ['flags_0',['flags',['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()'],['../struct_vma_defragmentation_info.html#a3e23080c978ecf3abb3180f5b2069da7',1,'VmaDefragmentationInfo::flags()'],['../struct_vma_virtual_block_create_info.html#aaab9bf7e2d228c02ab6d90a72a6e6912',1,'VmaVirtualBlockCreateInfo::flags()'],['../struct_vma_virtual_allocation_create_info.html#ab10e16956cc4bf20ced9de77d1129ea4',1,'VmaVirtualAllocationCreateInfo::flags()']]]
];
diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js
index de9b72c..be9f324 100644
--- a/docs/html/search/all_7.js
+++ b/docs/html/search/all_7.js
@@ -1,4 +1,5 @@
var searchData=
[
- ['instance_0',['instance',['../struct_vma_allocator_create_info.html#a70dd42e29b1df1d1b9b61532ae0b370b',1,'VmaAllocatorCreateInfo::instance()'],['../struct_vma_allocator_info.html#a2ed6a4d2d3fea039d66a13f15d0ce5fe',1,'VmaAllocatorInfo::instance()']]]
+ ['instance_0',['instance',['../struct_vma_allocator_create_info.html#a70dd42e29b1df1d1b9b61532ae0b370b',1,'VmaAllocatorCreateInfo::instance()'],['../struct_vma_allocator_info.html#a2ed6a4d2d3fea039d66a13f15d0ce5fe',1,'VmaAllocatorInfo::instance()']]],
+ ['internaldata_1',['internalData',['../struct_vma_defragmentation_move.html#a4f3637400767f3e642b3936e18b00e0f',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js
index 06194dd..f2c1a34 100644
--- a/docs/html/search/all_9.js
+++ b/docs/html/search/all_9.js
@@ -1,20 +1,15 @@
var searchData=
[
- ['maxallocationstomove_0',['maxAllocationsToMove',['../struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc',1,'VmaDefragmentationInfo']]],
+ ['maxallocationsperpass_0',['maxAllocationsPerPass',['../struct_vma_defragmentation_info.html#ac2db29d309bebc4f7d55041416e9694b',1,'VmaDefragmentationInfo']]],
['maxblockcount_1',['maxBlockCount',['../struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c',1,'VmaPoolCreateInfo']]],
- ['maxbytestomove_2',['maxBytesToMove',['../struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d',1,'VmaDefragmentationInfo']]],
- ['maxcpuallocationstomove_3',['maxCpuAllocationsToMove',['../struct_vma_defragmentation_info2.html#a94c2c7223d52878445a8cccce396b671',1,'VmaDefragmentationInfo2']]],
- ['maxcpubytestomove_4',['maxCpuBytesToMove',['../struct_vma_defragmentation_info2.html#af78e1ea40c22d85137b65f6b384a4d0a',1,'VmaDefragmentationInfo2']]],
- ['maxgpuallocationstomove_5',['maxGpuAllocationsToMove',['../struct_vma_defragmentation_info2.html#a40d53d33e71ba0b66f844ed63c05a3f6',1,'VmaDefragmentationInfo2']]],
- ['maxgpubytestomove_6',['maxGpuBytesToMove',['../struct_vma_defragmentation_info2.html#a4ddbc898d0afe1518f863a3763628f08',1,'VmaDefragmentationInfo2']]],
- ['memory_7',['memory',['../struct_vma_defragmentation_pass_move_info.html#a06eb0c8690aa0d3478a036753492e769',1,'VmaDefragmentationPassMoveInfo']]],
- ['memory_20allocation_8',['Memory allocation',['../group__group__alloc.html',1,'']]],
- ['memory_20mapping_9',['Memory mapping',['../memory_mapping.html',1,'index']]],
- ['memoryheap_10',['memoryHeap',['../struct_vma_total_statistics.html#a39beeba5b3a2e7cfe5f5e2331a2705ce',1,'VmaTotalStatistics']]],
- ['memorytype_11',['memoryType',['../struct_vma_total_statistics.html#acb70e5b7fe543813ed8ba9282640969d',1,'VmaTotalStatistics::memoryType()'],['../struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5',1,'VmaAllocationInfo::memoryType()']]],
- ['memorytypebits_12',['memoryTypeBits',['../struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055',1,'VmaAllocationCreateInfo']]],
- ['memorytypeindex_13',['memoryTypeIndex',['../struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319',1,'VmaPoolCreateInfo']]],
- ['minallocationalignment_14',['minAllocationAlignment',['../struct_vma_pool_create_info.html#ade3eca546f0c6ab4e8fbf20eb6d854cb',1,'VmaPoolCreateInfo']]],
- ['minblockcount_15',['minBlockCount',['../struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae',1,'VmaPoolCreateInfo']]],
- ['movecount_16',['moveCount',['../struct_vma_defragmentation_pass_info.html#ac1086e657ba995f8d1f4e49b83dcfb6c',1,'VmaDefragmentationPassInfo']]]
+ ['maxbytesperpass_2',['maxBytesPerPass',['../struct_vma_defragmentation_info.html#a637ada77b02179a27fa92290000afac4',1,'VmaDefragmentationInfo']]],
+ ['memory_20allocation_3',['Memory allocation',['../group__group__alloc.html',1,'']]],
+ ['memory_20mapping_4',['Memory mapping',['../memory_mapping.html',1,'index']]],
+ ['memoryheap_5',['memoryHeap',['../struct_vma_total_statistics.html#a39beeba5b3a2e7cfe5f5e2331a2705ce',1,'VmaTotalStatistics']]],
+ ['memorytype_6',['memoryType',['../struct_vma_total_statistics.html#acb70e5b7fe543813ed8ba9282640969d',1,'VmaTotalStatistics::memoryType()'],['../struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5',1,'VmaAllocationInfo::memoryType()']]],
+ ['memorytypebits_7',['memoryTypeBits',['../struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055',1,'VmaAllocationCreateInfo']]],
+ ['memorytypeindex_8',['memoryTypeIndex',['../struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319',1,'VmaPoolCreateInfo']]],
+ ['minallocationalignment_9',['minAllocationAlignment',['../struct_vma_pool_create_info.html#ade3eca546f0c6ab4e8fbf20eb6d854cb',1,'VmaPoolCreateInfo']]],
+ ['minblockcount_10',['minBlockCount',['../struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae',1,'VmaPoolCreateInfo']]],
+ ['movecount_11',['moveCount',['../struct_vma_defragmentation_pass_move_info.html#a1b3e18c23f9691f35baf183e615c4408',1,'VmaDefragmentationPassMoveInfo']]]
];
diff --git a/docs/html/search/all_a.js b/docs/html/search/all_a.js
index c3267c0..463ec49 100644
--- a/docs/html/search/all_a.js
+++ b/docs/html/search/all_a.js
@@ -1,5 +1,6 @@
var searchData=
[
- ['offset_0',['offset',['../struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268',1,'VmaAllocationInfo::offset()'],['../struct_vma_defragmentation_pass_move_info.html#a8ab4508bc03625b0653c880576be96c6',1,'VmaDefragmentationPassMoveInfo::offset()'],['../struct_vma_virtual_allocation_info.html#accb40a8205f49ccca3de975da7d1a2b5',1,'VmaVirtualAllocationInfo::offset()']]],
- ['opengl_20interop_1',['OpenGL Interop',['../opengl_interop.html',1,'index']]]
+ ['offset_0',['offset',['../struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268',1,'VmaAllocationInfo::offset()'],['../struct_vma_virtual_allocation_info.html#accb40a8205f49ccca3de975da7d1a2b5',1,'VmaVirtualAllocationInfo::offset()']]],
+ ['opengl_20interop_1',['OpenGL Interop',['../opengl_interop.html',1,'index']]],
+ ['operation_2',['operation',['../struct_vma_defragmentation_move.html#a20996a4686c9246dff77b375ac4a91e2',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js
index 6d50231..a2266bc 100644
--- a/docs/html/search/all_b.js
+++ b/docs/html/search/all_b.js
@@ -1,25 +1,21 @@
var searchData=
[
['pallocationcallbacks_0',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo::pAllocationCallbacks()'],['../struct_vma_virtual_block_create_info.html#a290283bf915c257d24584872d793ad30',1,'VmaVirtualBlockCreateInfo::pAllocationCallbacks()']]],
- ['pallocations_1',['pAllocations',['../struct_vma_defragmentation_info2.html#ab6d288f29d028156cf73542d630a2e32',1,'VmaDefragmentationInfo2']]],
- ['pallocationschanged_2',['pAllocationsChanged',['../struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc',1,'VmaDefragmentationInfo2']]],
- ['pdevicememorycallbacks_3',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
- ['pfn_5fvmaallocatedevicememoryfunction_4',['PFN_vmaAllocateDeviceMemoryFunction',['../group__group__init.html#ga7e1ed85f7799600b03ad51a77acc21f3',1,'vk_mem_alloc.h']]],
- ['pfn_5fvmafreedevicememoryfunction_5',['PFN_vmaFreeDeviceMemoryFunction',['../group__group__init.html#ga154ccaaf53dc2c36378f80f0c4f3679b',1,'vk_mem_alloc.h']]],
- ['pfnallocate_6',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
- ['pfnfree_7',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
- ['pheapsizelimit_8',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
- ['physicaldevice_9',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo::physicalDevice()'],['../struct_vma_allocator_info.html#aba2b703f96e51d567717e1fb2935b47a',1,'VmaAllocatorInfo::physicalDevice()']]],
- ['pmappeddata_10',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
- ['pmemoryallocatenext_11',['pMemoryAllocateNext',['../struct_vma_pool_create_info.html#af0f8c58f51a2a7a0a389dc79565044d7',1,'VmaPoolCreateInfo']]],
- ['pmoves_12',['pMoves',['../struct_vma_defragmentation_pass_info.html#acbd42d4a3357999da130a95cd99a3792',1,'VmaDefragmentationPassInfo']]],
- ['pool_13',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
- ['poolcount_14',['poolCount',['../struct_vma_defragmentation_info2.html#a7e70aa2a1081d849dcc7829b19d3ec9d',1,'VmaDefragmentationInfo2']]],
- ['ppools_15',['pPools',['../struct_vma_defragmentation_info2.html#a3c9c6aa5c97d5670f8e362b3a6f3029b',1,'VmaDefragmentationInfo2']]],
- ['preferredflags_16',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
- ['preferredlargeheapblocksize_17',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
- ['priority_18',['priority',['../struct_vma_allocation_create_info.html#a983d39e1a2e63649d78a960aa2fdd0f7',1,'VmaAllocationCreateInfo::priority()'],['../struct_vma_pool_create_info.html#a16e686c688f6725f119ebf6e24ab5274',1,'VmaPoolCreateInfo::priority()']]],
- ['ptypeexternalmemoryhandletypes_19',['pTypeExternalMemoryHandleTypes',['../struct_vma_allocator_create_info.html#ae8f0db05e5cb4c43d7713bf4a49a736b',1,'VmaAllocatorCreateInfo']]],
- ['puserdata_20',['pUserData',['../struct_vma_device_memory_callbacks.html#a24052de0937ddd54015a2df0363903c6',1,'VmaDeviceMemoryCallbacks::pUserData()'],['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()'],['../struct_vma_virtual_allocation_create_info.html#a015f8544ca51a7350f7434d42d0587bb',1,'VmaVirtualAllocationCreateInfo::pUserData()'],['../struct_vma_virtual_allocation_info.html#a41d5cb09357656411653d82fee436f45',1,'VmaVirtualAllocationInfo::pUserData()']]],
- ['pvulkanfunctions_21',['pVulkanFunctions',['../struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd',1,'VmaAllocatorCreateInfo']]]
+ ['pdevicememorycallbacks_1',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
+ ['pfn_5fvmaallocatedevicememoryfunction_2',['PFN_vmaAllocateDeviceMemoryFunction',['../group__group__init.html#ga7e1ed85f7799600b03ad51a77acc21f3',1,'vk_mem_alloc.h']]],
+ ['pfn_5fvmafreedevicememoryfunction_3',['PFN_vmaFreeDeviceMemoryFunction',['../group__group__init.html#ga154ccaaf53dc2c36378f80f0c4f3679b',1,'vk_mem_alloc.h']]],
+ ['pfnallocate_4',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
+ ['pfnfree_5',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
+ ['pheapsizelimit_6',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
+ ['physicaldevice_7',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo::physicalDevice()'],['../struct_vma_allocator_info.html#aba2b703f96e51d567717e1fb2935b47a',1,'VmaAllocatorInfo::physicalDevice()']]],
+ ['pmappeddata_8',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
+ ['pmemoryallocatenext_9',['pMemoryAllocateNext',['../struct_vma_pool_create_info.html#af0f8c58f51a2a7a0a389dc79565044d7',1,'VmaPoolCreateInfo']]],
+ ['pmoves_10',['pMoves',['../struct_vma_defragmentation_pass_move_info.html#adfa7a4994afd9b940e7f1dfaf436a725',1,'VmaDefragmentationPassMoveInfo']]],
+ ['pool_11',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo::pool()'],['../struct_vma_defragmentation_info.html#a18dd2097d8ab2976cdc7dd3e7b978bd4',1,'VmaDefragmentationInfo::pool()']]],
+ ['preferredflags_12',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
+ ['preferredlargeheapblocksize_13',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
+ ['priority_14',['priority',['../struct_vma_allocation_create_info.html#a983d39e1a2e63649d78a960aa2fdd0f7',1,'VmaAllocationCreateInfo::priority()'],['../struct_vma_pool_create_info.html#a16e686c688f6725f119ebf6e24ab5274',1,'VmaPoolCreateInfo::priority()']]],
+ ['ptypeexternalmemoryhandletypes_15',['pTypeExternalMemoryHandleTypes',['../struct_vma_allocator_create_info.html#ae8f0db05e5cb4c43d7713bf4a49a736b',1,'VmaAllocatorCreateInfo']]],
+ ['puserdata_16',['pUserData',['../struct_vma_device_memory_callbacks.html#a24052de0937ddd54015a2df0363903c6',1,'VmaDeviceMemoryCallbacks::pUserData()'],['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()'],['../struct_vma_virtual_allocation_create_info.html#a015f8544ca51a7350f7434d42d0587bb',1,'VmaVirtualAllocationCreateInfo::pUserData()'],['../struct_vma_virtual_allocation_info.html#a41d5cb09357656411653d82fee436f45',1,'VmaVirtualAllocationInfo::pUserData()']]],
+ ['pvulkanfunctions_17',['pVulkanFunctions',['../struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd',1,'VmaAllocatorCreateInfo']]]
];
diff --git a/docs/html/search/all_e.js b/docs/html/search/all_e.js
index d5d2df6..c6884fa 100644
--- a/docs/html/search/all_e.js
+++ b/docs/html/search/all_e.js
@@ -1,8 +1,9 @@
var searchData=
[
['size_0',['size',['../struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f',1,'VmaAllocationInfo::size()'],['../struct_vma_virtual_block_create_info.html#a670ab8c6a6e822f3c36781d79e8824e9',1,'VmaVirtualBlockCreateInfo::size()'],['../struct_vma_virtual_allocation_create_info.html#aae08752b86817abd0d944c6025dc603e',1,'VmaVirtualAllocationCreateInfo::size()'],['../struct_vma_virtual_allocation_info.html#afb6d6bd0a6813869ea0842048d40aa2b',1,'VmaVirtualAllocationInfo::size()']]],
- ['statistics_1',['Statistics',['../group__group__stats.html',1,'']]],
- ['statistics_2',['statistics',['../struct_vma_detailed_statistics.html#a13efbdb35bd1291191d275f43e96d360',1,'VmaDetailedStatistics::statistics()'],['../struct_vma_budget.html#a6d15ab3a798fd62d9efa3a1e1f83bf54',1,'VmaBudget::statistics()']]],
- ['statistics_3',['Statistics',['../statistics.html',1,'index']]],
- ['staying_20within_20budget_4',['Staying within budget',['../staying_within_budget.html',1,'index']]]
+ ['srcallocation_1',['srcAllocation',['../struct_vma_defragmentation_move.html#a25aa1bb64efc507a49c6cbc50689f862',1,'VmaDefragmentationMove']]],
+ ['statistics_2',['Statistics',['../group__group__stats.html',1,'']]],
+ ['statistics_3',['statistics',['../struct_vma_detailed_statistics.html#a13efbdb35bd1291191d275f43e96d360',1,'VmaDetailedStatistics::statistics()'],['../struct_vma_budget.html#a6d15ab3a798fd62d9efa3a1e1f83bf54',1,'VmaBudget::statistics()']]],
+ ['statistics_4',['Statistics',['../statistics.html',1,'index']]],
+ ['staying_20within_20budget_5',['Staying within budget',['../staying_within_budget.html',1,'index']]]
];
diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js
index 9f61ea0..76cfeb7 100644
--- a/docs/html/search/classes_0.js
+++ b/docs/html/search/classes_0.js
@@ -9,20 +9,19 @@ var searchData=
['vmabudget_6',['VmaBudget',['../struct_vma_budget.html',1,'']]],
['vmadefragmentationcontext_7',['VmaDefragmentationContext',['../struct_vma_defragmentation_context.html',1,'']]],
['vmadefragmentationinfo_8',['VmaDefragmentationInfo',['../struct_vma_defragmentation_info.html',1,'']]],
- ['vmadefragmentationinfo2_9',['VmaDefragmentationInfo2',['../struct_vma_defragmentation_info2.html',1,'']]],
- ['vmadefragmentationpassinfo_10',['VmaDefragmentationPassInfo',['../struct_vma_defragmentation_pass_info.html',1,'']]],
- ['vmadefragmentationpassmoveinfo_11',['VmaDefragmentationPassMoveInfo',['../struct_vma_defragmentation_pass_move_info.html',1,'']]],
- ['vmadefragmentationstats_12',['VmaDefragmentationStats',['../struct_vma_defragmentation_stats.html',1,'']]],
- ['vmadetailedstatistics_13',['VmaDetailedStatistics',['../struct_vma_detailed_statistics.html',1,'']]],
- ['vmadevicememorycallbacks_14',['VmaDeviceMemoryCallbacks',['../struct_vma_device_memory_callbacks.html',1,'']]],
- ['vmapool_15',['VmaPool',['../struct_vma_pool.html',1,'']]],
- ['vmapoolcreateinfo_16',['VmaPoolCreateInfo',['../struct_vma_pool_create_info.html',1,'']]],
- ['vmastatistics_17',['VmaStatistics',['../struct_vma_statistics.html',1,'']]],
- ['vmatotalstatistics_18',['VmaTotalStatistics',['../struct_vma_total_statistics.html',1,'']]],
- ['vmavirtualallocation_19',['VmaVirtualAllocation',['../struct_vma_virtual_allocation.html',1,'']]],
- ['vmavirtualallocationcreateinfo_20',['VmaVirtualAllocationCreateInfo',['../struct_vma_virtual_allocation_create_info.html',1,'']]],
- ['vmavirtualallocationinfo_21',['VmaVirtualAllocationInfo',['../struct_vma_virtual_allocation_info.html',1,'']]],
- ['vmavirtualblock_22',['VmaVirtualBlock',['../struct_vma_virtual_block.html',1,'']]],
- ['vmavirtualblockcreateinfo_23',['VmaVirtualBlockCreateInfo',['../struct_vma_virtual_block_create_info.html',1,'']]],
- ['vmavulkanfunctions_24',['VmaVulkanFunctions',['../struct_vma_vulkan_functions.html',1,'']]]
+ ['vmadefragmentationmove_9',['VmaDefragmentationMove',['../struct_vma_defragmentation_move.html',1,'']]],
+ ['vmadefragmentationpassmoveinfo_10',['VmaDefragmentationPassMoveInfo',['../struct_vma_defragmentation_pass_move_info.html',1,'']]],
+ ['vmadefragmentationstats_11',['VmaDefragmentationStats',['../struct_vma_defragmentation_stats.html',1,'']]],
+ ['vmadetailedstatistics_12',['VmaDetailedStatistics',['../struct_vma_detailed_statistics.html',1,'']]],
+ ['vmadevicememorycallbacks_13',['VmaDeviceMemoryCallbacks',['../struct_vma_device_memory_callbacks.html',1,'']]],
+ ['vmapool_14',['VmaPool',['../struct_vma_pool.html',1,'']]],
+ ['vmapoolcreateinfo_15',['VmaPoolCreateInfo',['../struct_vma_pool_create_info.html',1,'']]],
+ ['vmastatistics_16',['VmaStatistics',['../struct_vma_statistics.html',1,'']]],
+ ['vmatotalstatistics_17',['VmaTotalStatistics',['../struct_vma_total_statistics.html',1,'']]],
+ ['vmavirtualallocation_18',['VmaVirtualAllocation',['../struct_vma_virtual_allocation.html',1,'']]],
+ ['vmavirtualallocationcreateinfo_19',['VmaVirtualAllocationCreateInfo',['../struct_vma_virtual_allocation_create_info.html',1,'']]],
+ ['vmavirtualallocationinfo_20',['VmaVirtualAllocationInfo',['../struct_vma_virtual_allocation_info.html',1,'']]],
+ ['vmavirtualblock_21',['VmaVirtualBlock',['../struct_vma_virtual_block.html',1,'']]],
+ ['vmavirtualblockcreateinfo_22',['VmaVirtualBlockCreateInfo',['../struct_vma_virtual_block_create_info.html',1,'']]],
+ ['vmavulkanfunctions_23',['VmaVulkanFunctions',['../struct_vma_vulkan_functions.html',1,'']]]
];
diff --git a/docs/html/search/enums_0.js b/docs/html/search/enums_0.js
index 385d710..fd327ce 100644
--- a/docs/html/search/enums_0.js
+++ b/docs/html/search/enums_0.js
@@ -3,8 +3,9 @@ var searchData=
['vmaallocationcreateflagbits_0',['VmaAllocationCreateFlagBits',['../group__group__alloc.html#gad9889c10c798b040d59c92f257cae597',1,'vk_mem_alloc.h']]],
['vmaallocatorcreateflagbits_1',['VmaAllocatorCreateFlagBits',['../group__group__init.html#ga4f87c9100d154a65a4ad495f7763cf7c',1,'vk_mem_alloc.h']]],
['vmadefragmentationflagbits_2',['VmaDefragmentationFlagBits',['../group__group__alloc.html#ga6552a65b71d16f378c6994b3ceaef50c',1,'vk_mem_alloc.h']]],
- ['vmamemoryusage_3',['VmaMemoryUsage',['../group__group__alloc.html#gaa5846affa1e9da3800e3e78fae2305cc',1,'vk_mem_alloc.h']]],
- ['vmapoolcreateflagbits_4',['VmaPoolCreateFlagBits',['../group__group__alloc.html#ga9a7c45f9c863695d98c83fa5ac940fe7',1,'vk_mem_alloc.h']]],
- ['vmavirtualallocationcreateflagbits_5',['VmaVirtualAllocationCreateFlagBits',['../group__group__virtual.html#ga2e9c64d405b14156fea7e10c4ad06cb6',1,'vk_mem_alloc.h']]],
- ['vmavirtualblockcreateflagbits_6',['VmaVirtualBlockCreateFlagBits',['../group__group__virtual.html#ga88bcf8c1cd3bb1610ff7343811c65bca',1,'vk_mem_alloc.h']]]
+ ['vmadefragmentationmoveoperation_3',['VmaDefragmentationMoveOperation',['../group__group__alloc.html#gada9e3861caf96f08894b0bcc160ec257',1,'vk_mem_alloc.h']]],
+ ['vmamemoryusage_4',['VmaMemoryUsage',['../group__group__alloc.html#gaa5846affa1e9da3800e3e78fae2305cc',1,'vk_mem_alloc.h']]],
+ ['vmapoolcreateflagbits_5',['VmaPoolCreateFlagBits',['../group__group__alloc.html#ga9a7c45f9c863695d98c83fa5ac940fe7',1,'vk_mem_alloc.h']]],
+ ['vmavirtualallocationcreateflagbits_6',['VmaVirtualAllocationCreateFlagBits',['../group__group__virtual.html#ga2e9c64d405b14156fea7e10c4ad06cb6',1,'vk_mem_alloc.h']]],
+ ['vmavirtualblockcreateflagbits_7',['VmaVirtualBlockCreateFlagBits',['../group__group__virtual.html#ga88bcf8c1cd3bb1610ff7343811c65bca',1,'vk_mem_alloc.h']]]
];
diff --git a/docs/html/search/enumvalues_0.js b/docs/html/search/enumvalues_0.js
index 2929789..68cab3d 100644
--- a/docs/html/search/enumvalues_0.js
+++ b/docs/html/search/enumvalues_0.js
@@ -15,45 +15,50 @@ var searchData=
['vma_5fallocation_5fcreate_5fstrategy_5ffirst_5ffit_5fbit_12',['VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a33eb2052674f3ad92386c714a65fb777',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fstrategy_5fmask_13',['VMA_ALLOCATION_CREATE_STRATEGY_MASK',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a8e16845d81ae3d27c47106d4770d5c7e',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fstrategy_5fmin_5fmemory_5fbit_14',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a8af1210cf591784afa026d94998f735d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_15',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a0729e932b7ea170e3a128cad96c5cf6d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fupper_5faddress_5fbit_16',['VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fuser_5fdata_5fcopy_5fstring_5fbit_17',['VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520',1,'vk_mem_alloc.h']]],
- ['vma_5fallocation_5fcreate_5fwithin_5fbudget_5fbit_18',['VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597ab8b1764f3e9022368e440c057783b92d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5famd_5fdevice_5fcoherent_5fmemory_5fbit_19',['VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca2acce4886d8078552efa38878413970f',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fbuffer_5fdevice_5faddress_5fbit_20',['VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca5f1b28b0414319d1687e1f2b30ab0089',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fext_5fmemory_5fbudget_5fbit_21',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4d4687863f7bd4b418c6006dc04400b0',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fext_5fmemory_5fpriority_5fbit_22',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7caffdd7a5169be3dbd7cbf6b3619e4f78a',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fexternally_5fsynchronized_5fbit_23',['VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fflag_5fbits_5fmax_5fenum_24',['VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fkhr_5fbind_5fmemory2_5fbit_25',['VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca8fb75bf07cd184ab903596295e863dee',1,'vk_mem_alloc.h']]],
- ['vma_5fallocator_5fcreate_5fkhr_5fdedicated_5fallocation_5fbit_26',['VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878',1,'vk_mem_alloc.h']]],
- ['vma_5fdefragmentation_5fflag_5fbits_5fmax_5fenum_27',['VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cab87ec33154803bfeb5ac2b379f1d6a97',1,'vk_mem_alloc.h']]],
- ['vma_5fdefragmentation_5fflag_5fincremental_28',['VMA_DEFRAGMENTATION_FLAG_INCREMENTAL',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50ca31af49446af2459284a568ce2f3fdd33',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fauto_29',['VMA_MEMORY_USAGE_AUTO',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fauto_5fprefer_5fdevice_30',['VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccae2adb696d6a73c18bb20c23666661327',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fauto_5fprefer_5fhost_31',['VMA_MEMORY_USAGE_AUTO_PREFER_HOST',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9b422585242160b8ed3418310ee6664d',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fcpu_5fcopy_32',['VMA_MEMORY_USAGE_CPU_COPY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca416a444d4d0fc20067c3f76f32ff2500',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fcpu_5fonly_33',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu_34',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fgpu_5flazily_5fallocated_35',['VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca835333d9072db63a653818030e17614d',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fgpu_5fonly_36',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fgpu_5fto_5fcpu_37',['VMA_MEMORY_USAGE_GPU_TO_CPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5fmax_5fenum_38',['VMA_MEMORY_USAGE_MAX_ENUM',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]],
- ['vma_5fmemory_5fusage_5funknown_39',['VMA_MEMORY_USAGE_UNKNOWN',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5falgorithm_5fmask_40',['VMA_POOL_CREATE_ALGORITHM_MASK',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7af4d270f8f42517a0f70037ceb6ac1d9c',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5fbuddy_5falgorithm_5fbit_41',['VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a97a0dc38e5161b780594d998d313d35e',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5fflag_5fbits_5fmax_5fenum_42',['VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit_43',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5flinear_5falgorithm_5fbit_44',['VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726',1,'vk_mem_alloc.h']]],
- ['vma_5fpool_5fcreate_5ftlsf_5falgorithm_5fbit_45',['VMA_POOL_CREATE_TLSF_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a855ee6e02e46d835ee28c8cd596b7e32',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum_46',['VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac1163c03ea837fa663462dc286d6a1a9',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmask_47',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac5b5e45c335368d18df59c9f27df17e3',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5fmemory_5fbit_48',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ae2a9591a62b5e3b1bdcbc81c6188a1bf',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_49',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a562d10a46012719d33167d3dc5dbbf9b',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fallocation_5fcreate_5fupper_5faddress_5fbit_50',['VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a9524a329a55b5ec390d57d90b67ad78e',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5falgorithm_5fmask_51',['VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaaf9487467136e1a9e371894dc3a7c4844',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5fbuddy_5falgorithm_5fbit_52',['VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa923116612509e26bf84982b9baf25c63',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5fflag_5fbits_5fmax_5fenum_53',['VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa5fc0d333c3d5687a8bbf57df9b377a87',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5flinear_5falgorithm_5fbit_54',['VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaae6423e2fa2f3c9211b21c819e3f10f96',1,'vk_mem_alloc.h']]],
- ['vma_5fvirtual_5fblock_5fcreate_5ftlsf_5falgorithm_5fbit_55',['VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa4db7cb39f9c0f1a4b71c5f76b4cfa691',1,'vk_mem_alloc.h']]]
+ ['vma_5fallocation_5fcreate_5fstrategy_5fmin_5foffset_5fbit_15',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a8099acedc0d04cdccaaddcfe37fd227d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_16',['VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a0729e932b7ea170e3a128cad96c5cf6d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fupper_5faddress_5fbit_17',['VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fuser_5fdata_5fcopy_5fstring_5fbit_18',['VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocation_5fcreate_5fwithin_5fbudget_5fbit_19',['VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT',['../group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597ab8b1764f3e9022368e440c057783b92d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5famd_5fdevice_5fcoherent_5fmemory_5fbit_20',['VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca2acce4886d8078552efa38878413970f',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fbuffer_5fdevice_5faddress_5fbit_21',['VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca5f1b28b0414319d1687e1f2b30ab0089',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fext_5fmemory_5fbudget_5fbit_22',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4d4687863f7bd4b418c6006dc04400b0',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fext_5fmemory_5fpriority_5fbit_23',['VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7caffdd7a5169be3dbd7cbf6b3619e4f78a',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fexternally_5fsynchronized_5fbit_24',['VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fflag_5fbits_5fmax_5fenum_25',['VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cae4d5ad929caba5f23eb502b13bd5286c',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fkhr_5fbind_5fmemory2_5fbit_26',['VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca8fb75bf07cd184ab903596295e863dee',1,'vk_mem_alloc.h']]],
+ ['vma_5fallocator_5fcreate_5fkhr_5fdedicated_5fallocation_5fbit_27',['VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT',['../group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5fbalanced_5fbit_28',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50caec35a4138111605a6ff32ca61aa871b6',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5fextensive_5fbit_29',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cae45a9469e5337731627758671741e412',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5ffast_5fbit_30',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50ca2e6469bcf5a094776ceb5d118263f04b',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5ffull_5fbit_31',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cafa162eac5be800bcdd4011427a71156d',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5falgorithm_5fmask_32',['VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cabcbbdb3bfd53c4c3ab4eaeb5fd4894e9',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fflag_5fbits_5fmax_5fenum_33',['VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50cab87ec33154803bfeb5ac2b379f1d6a97',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fmove_5foperation_5fcopy_34',['VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY',['../group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257ad4a06ac46c4cb1c67b0ebc1edfab9f18',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fmove_5foperation_5fdestroy_35',['VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY',['../group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257a9786f8492a9be2c03bd26395e352ab85',1,'vk_mem_alloc.h']]],
+ ['vma_5fdefragmentation_5fmove_5foperation_5fignore_36',['VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE',['../group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257ad25bc6f816b226b4fd5170e845f218d2',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fauto_37',['VMA_MEMORY_USAGE_AUTO',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fauto_5fprefer_5fdevice_38',['VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccae2adb696d6a73c18bb20c23666661327',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fauto_5fprefer_5fhost_39',['VMA_MEMORY_USAGE_AUTO_PREFER_HOST',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9b422585242160b8ed3418310ee6664d',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fcpu_5fcopy_40',['VMA_MEMORY_USAGE_CPU_COPY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca416a444d4d0fc20067c3f76f32ff2500',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fcpu_5fonly_41',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu_42',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fgpu_5flazily_5fallocated_43',['VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca835333d9072db63a653818030e17614d',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fgpu_5fonly_44',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fgpu_5fto_5fcpu_45',['VMA_MEMORY_USAGE_GPU_TO_CPU',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca7b586d2fdaf82a463b58f581ed72be27',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5fmax_5fenum_46',['VMA_MEMORY_USAGE_MAX_ENUM',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca091e69437ef693e8d0d287f1c719ba6e',1,'vk_mem_alloc.h']]],
+ ['vma_5fmemory_5fusage_5funknown_47',['VMA_MEMORY_USAGE_UNKNOWN',['../group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5falgorithm_5fmask_48',['VMA_POOL_CREATE_ALGORITHM_MASK',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7af4d270f8f42517a0f70037ceb6ac1d9c',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5fflag_5fbits_5fmax_5fenum_49',['VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a1c7312bea9ea246846b9054fd6bd6aec',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5fignore_5fbuffer_5fimage_5fgranularity_5fbit_50',['VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a9f1a499508a8edb4e8ba40aa0290a3d2',1,'vk_mem_alloc.h']]],
+ ['vma_5fpool_5fcreate_5flinear_5falgorithm_5fbit_51',['VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum_52',['VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac1163c03ea837fa663462dc286d6a1a9',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmask_53',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ac5b5e45c335368d18df59c9f27df17e3',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5fmemory_5fbit_54',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6ae2a9591a62b5e3b1bdcbc81c6188a1bf',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fmin_5ftime_5fbit_55',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a562d10a46012719d33167d3dc5dbbf9b',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fstrategy_5fpacked_5fbit_56',['VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_PACKED_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a3c3c4952631d8c35649537a675adc401',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fallocation_5fcreate_5fupper_5faddress_5fbit_57',['VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT',['../group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a9524a329a55b5ec390d57d90b67ad78e',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fblock_5fcreate_5falgorithm_5fmask_58',['VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaaf9487467136e1a9e371894dc3a7c4844',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fblock_5fcreate_5fflag_5fbits_5fmax_5fenum_59',['VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaa5fc0d333c3d5687a8bbf57df9b377a87',1,'vk_mem_alloc.h']]],
+ ['vma_5fvirtual_5fblock_5fcreate_5flinear_5falgorithm_5fbit_60',['VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT',['../group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaae6423e2fa2f3c9211b21c819e3f10f96',1,'vk_mem_alloc.h']]]
];
diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js
index 45e65be..4866904 100644
--- a/docs/html/search/functions_0.js
+++ b/docs/html/search/functions_0.js
@@ -5,63 +5,62 @@ var searchData=
['vmaallocatememoryforbuffer_2',['vmaAllocateMemoryForBuffer',['../group__group__alloc.html#ga7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
['vmaallocatememoryforimage_3',['vmaAllocateMemoryForImage',['../group__group__alloc.html#ga0faa3f9e5fb233d29d1e00390650febb',1,'vk_mem_alloc.h']]],
['vmaallocatememorypages_4',['vmaAllocateMemoryPages',['../group__group__alloc.html#gad37e82e492b3de38fc3f4cffd9ad0ae1',1,'vk_mem_alloc.h']]],
- ['vmabegindefragmentationpass_5',['vmaBeginDefragmentationPass',['../group__group__alloc.html#gac0f01545b6262f7d4d128fc8f8e5c77b',1,'vk_mem_alloc.h']]],
- ['vmabindbuffermemory_6',['vmaBindBufferMemory',['../group__group__alloc.html#ga6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
- ['vmabindbuffermemory2_7',['vmaBindBufferMemory2',['../group__group__alloc.html#ga927c944f45e0f2941182abb6f608e64a',1,'vk_mem_alloc.h']]],
- ['vmabindimagememory_8',['vmaBindImageMemory',['../group__group__alloc.html#ga3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
- ['vmabindimagememory2_9',['vmaBindImageMemory2',['../group__group__alloc.html#gaa8251ee81b0045a443e35b8e8aa021bc',1,'vk_mem_alloc.h']]],
- ['vmabuildstatsstring_10',['vmaBuildStatsString',['../group__group__stats.html#gaa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
- ['vmabuildvirtualblockstatsstring_11',['vmaBuildVirtualBlockStatsString',['../group__group__stats.html#ga52d810e1222c592e5d80556ad005f1e6',1,'vk_mem_alloc.h']]],
- ['vmacalculatepoolstatistics_12',['vmaCalculatePoolStatistics',['../group__group__stats.html#ga50ba0eb25d2b363b792be4645ca7a380',1,'vk_mem_alloc.h']]],
- ['vmacalculatestatistics_13',['vmaCalculateStatistics',['../group__group__stats.html#ga36f3484de7aa6cd6edc4de9edfa0ff59',1,'vk_mem_alloc.h']]],
- ['vmacalculatevirtualblockstatistics_14',['vmaCalculateVirtualBlockStatistics',['../group__group__virtual.html#ga93c5741bca44b43e5b849cacbd616098',1,'vk_mem_alloc.h']]],
- ['vmacheckcorruption_15',['vmaCheckCorruption',['../group__group__alloc.html#ga49329a7f030dafcf82f7b73334c22e98',1,'vk_mem_alloc.h']]],
- ['vmacheckpoolcorruption_16',['vmaCheckPoolCorruption',['../group__group__alloc.html#gad535935619c7a549bf837e1bb0068f89',1,'vk_mem_alloc.h']]],
- ['vmaclearvirtualblock_17',['vmaClearVirtualBlock',['../group__group__virtual.html#ga5eda6f55919fb05bd2f56a112590c571',1,'vk_mem_alloc.h']]],
- ['vmacreateallocator_18',['vmaCreateAllocator',['../group__group__init.html#ga200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
- ['vmacreatebuffer_19',['vmaCreateBuffer',['../group__group__alloc.html#gac72ee55598617e8eecca384e746bab51',1,'vk_mem_alloc.h']]],
- ['vmacreatebufferwithalignment_20',['vmaCreateBufferWithAlignment',['../group__group__alloc.html#gaa06a690013a0d01e60894ac378083834',1,'vk_mem_alloc.h']]],
- ['vmacreateimage_21',['vmaCreateImage',['../group__group__alloc.html#ga02a94f25679275851a53e82eacbcfc73',1,'vk_mem_alloc.h']]],
- ['vmacreatepool_22',['vmaCreatePool',['../group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50',1,'vk_mem_alloc.h']]],
- ['vmacreatevirtualblock_23',['vmaCreateVirtualBlock',['../group__group__virtual.html#gab585754076877265fdae33e5c40ef13b',1,'vk_mem_alloc.h']]],
- ['vmadefragment_24',['vmaDefragment',['../group__group__alloc.html#ga9f0f8f56db5f7f57fe4454f465142dac',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationbegin_25',['vmaDefragmentationBegin',['../group__group__alloc.html#ga36ba776fd7fd5cb1e9359fdc0d8e6e8a',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationend_26',['vmaDefragmentationEnd',['../group__group__alloc.html#ga8774e20e91e245aae959ba63efa15dd2',1,'vk_mem_alloc.h']]],
- ['vmadestroyallocator_27',['vmaDestroyAllocator',['../group__group__init.html#gaa8d164061c88f22fb1fd3c8f3534bc1d',1,'vk_mem_alloc.h']]],
- ['vmadestroybuffer_28',['vmaDestroyBuffer',['../group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77',1,'vk_mem_alloc.h']]],
- ['vmadestroyimage_29',['vmaDestroyImage',['../group__group__alloc.html#gae50d2cb3b4a3bfd4dd40987234e50e7e',1,'vk_mem_alloc.h']]],
- ['vmadestroypool_30',['vmaDestroyPool',['../group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1',1,'vk_mem_alloc.h']]],
- ['vmadestroyvirtualblock_31',['vmaDestroyVirtualBlock',['../group__group__virtual.html#ga3795f7783ae2c182cede067d656f66a5',1,'vk_mem_alloc.h']]],
- ['vmaenddefragmentationpass_32',['vmaEndDefragmentationPass',['../group__group__alloc.html#ga1b9ffa538bed905af55c747cc48963bd',1,'vk_mem_alloc.h']]],
- ['vmafindmemorytypeindex_33',['vmaFindMemoryTypeIndex',['../group__group__alloc.html#gaef15a94b58fbcb0fe706d5720e84a74a',1,'vk_mem_alloc.h']]],
- ['vmafindmemorytypeindexforbufferinfo_34',['vmaFindMemoryTypeIndexForBufferInfo',['../group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888',1,'vk_mem_alloc.h']]],
- ['vmafindmemorytypeindexforimageinfo_35',['vmaFindMemoryTypeIndexForImageInfo',['../group__group__alloc.html#ga088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
- ['vmaflushallocation_36',['vmaFlushAllocation',['../group__group__alloc.html#ga30c37c1eec6025f397be41644f48490f',1,'vk_mem_alloc.h']]],
- ['vmaflushallocations_37',['vmaFlushAllocations',['../group__group__alloc.html#gac3dd00da721875ed99fa8a881922bdfc',1,'vk_mem_alloc.h']]],
- ['vmafreememory_38',['vmaFreeMemory',['../group__group__alloc.html#ga5fea5518972ae9094b1526cbcb19b05f',1,'vk_mem_alloc.h']]],
- ['vmafreememorypages_39',['vmaFreeMemoryPages',['../group__group__alloc.html#ga834b1e4aef395c0a1d56a28e69a4a17e',1,'vk_mem_alloc.h']]],
- ['vmafreestatsstring_40',['vmaFreeStatsString',['../group__group__stats.html#ga3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
- ['vmafreevirtualblockstatsstring_41',['vmaFreeVirtualBlockStatsString',['../group__group__stats.html#ga47fb8d8aa69df4a7c23a9719b4080623',1,'vk_mem_alloc.h']]],
- ['vmagetallocationinfo_42',['vmaGetAllocationInfo',['../group__group__alloc.html#ga86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
- ['vmagetallocationmemoryproperties_43',['vmaGetAllocationMemoryProperties',['../group__group__alloc.html#ga571e87dd38e552249b56b1b0b982fad1',1,'vk_mem_alloc.h']]],
- ['vmagetallocatorinfo_44',['vmaGetAllocatorInfo',['../group__group__init.html#gafa02231a791b37255720d566a52683e7',1,'vk_mem_alloc.h']]],
- ['vmagetheapbudgets_45',['vmaGetHeapBudgets',['../group__group__stats.html#ga9f88db9d46a432c0ad7278cecbc5eaa7',1,'vk_mem_alloc.h']]],
- ['vmagetmemoryproperties_46',['vmaGetMemoryProperties',['../group__group__init.html#gab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]],
- ['vmagetmemorytypeproperties_47',['vmaGetMemoryTypeProperties',['../group__group__init.html#ga8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]],
- ['vmagetphysicaldeviceproperties_48',['vmaGetPhysicalDeviceProperties',['../group__group__init.html#gaecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]],
- ['vmagetpoolname_49',['vmaGetPoolName',['../group__group__alloc.html#gaf09b4e4eafdbee812e8d73ddf960f030',1,'vk_mem_alloc.h']]],
- ['vmagetpoolstatistics_50',['vmaGetPoolStatistics',['../group__group__stats.html#ga34d8e7d83774eed0caee5c5ae88e217d',1,'vk_mem_alloc.h']]],
- ['vmagetvirtualallocationinfo_51',['vmaGetVirtualAllocationInfo',['../group__group__virtual.html#ga8ee14ceb1fe033ec84d8aa29e1f75afa',1,'vk_mem_alloc.h']]],
- ['vmagetvirtualblockstatistics_52',['vmaGetVirtualBlockStatistics',['../group__group__virtual.html#ga2902aa3130866afcc64bb5f984113db3',1,'vk_mem_alloc.h']]],
- ['vmainvalidateallocation_53',['vmaInvalidateAllocation',['../group__group__alloc.html#gaaa8412919139ef413a4215ac6a290fae',1,'vk_mem_alloc.h']]],
- ['vmainvalidateallocations_54',['vmaInvalidateAllocations',['../group__group__alloc.html#gab25b558d75f7378ec944a1522fdcc3c5',1,'vk_mem_alloc.h']]],
- ['vmaisvirtualblockempty_55',['vmaIsVirtualBlockEmpty',['../group__group__virtual.html#gacd53b5b1d23f8fcbad692ccfdc1811f1',1,'vk_mem_alloc.h']]],
- ['vmamapmemory_56',['vmaMapMemory',['../group__group__alloc.html#gad5bd1243512d099706de88168992f069',1,'vk_mem_alloc.h']]],
- ['vmasetallocationuserdata_57',['vmaSetAllocationUserData',['../group__group__alloc.html#gaf9147d31ffc11d62fc187bde283ed14f',1,'vk_mem_alloc.h']]],
- ['vmasetcurrentframeindex_58',['vmaSetCurrentFrameIndex',['../group__group__init.html#gade56bf8dc9f5a5eaddf5f119ed525236',1,'vk_mem_alloc.h']]],
- ['vmasetpoolname_59',['vmaSetPoolName',['../group__group__alloc.html#gadbae3a0b4ab078024462fc85c37f3b58',1,'vk_mem_alloc.h']]],
- ['vmasetvirtualallocationuserdata_60',['vmaSetVirtualAllocationUserData',['../group__group__virtual.html#ga001ea1850458a4062b829e09c303fca2',1,'vk_mem_alloc.h']]],
- ['vmaunmapmemory_61',['vmaUnmapMemory',['../group__group__alloc.html#ga9bc268595cb33f6ec4d519cfce81ff45',1,'vk_mem_alloc.h']]],
- ['vmavirtualallocate_62',['vmaVirtualAllocate',['../group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01',1,'vk_mem_alloc.h']]],
- ['vmavirtualfree_63',['vmaVirtualFree',['../group__group__virtual.html#ga09fc688c0c3653ff23723b037e5d5033',1,'vk_mem_alloc.h']]]
+ ['vmabegindefragmentation_5',['vmaBeginDefragmentation',['../group__group__alloc.html#gac3335566858b45541fa9c0d7a6bbb57e',1,'vk_mem_alloc.h']]],
+ ['vmabegindefragmentationpass_6',['vmaBeginDefragmentationPass',['../group__group__alloc.html#ga980d7da2ce3b1fd5c8b8476bc362cc00',1,'vk_mem_alloc.h']]],
+ ['vmabindbuffermemory_7',['vmaBindBufferMemory',['../group__group__alloc.html#ga6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
+ ['vmabindbuffermemory2_8',['vmaBindBufferMemory2',['../group__group__alloc.html#ga927c944f45e0f2941182abb6f608e64a',1,'vk_mem_alloc.h']]],
+ ['vmabindimagememory_9',['vmaBindImageMemory',['../group__group__alloc.html#ga3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
+ ['vmabindimagememory2_10',['vmaBindImageMemory2',['../group__group__alloc.html#gaa8251ee81b0045a443e35b8e8aa021bc',1,'vk_mem_alloc.h']]],
+ ['vmabuildstatsstring_11',['vmaBuildStatsString',['../group__group__stats.html#gaa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
+ ['vmabuildvirtualblockstatsstring_12',['vmaBuildVirtualBlockStatsString',['../group__group__stats.html#ga52d810e1222c592e5d80556ad005f1e6',1,'vk_mem_alloc.h']]],
+ ['vmacalculatepoolstatistics_13',['vmaCalculatePoolStatistics',['../group__group__stats.html#ga50ba0eb25d2b363b792be4645ca7a380',1,'vk_mem_alloc.h']]],
+ ['vmacalculatestatistics_14',['vmaCalculateStatistics',['../group__group__stats.html#ga36f3484de7aa6cd6edc4de9edfa0ff59',1,'vk_mem_alloc.h']]],
+ ['vmacalculatevirtualblockstatistics_15',['vmaCalculateVirtualBlockStatistics',['../group__group__virtual.html#ga93c5741bca44b43e5b849cacbd616098',1,'vk_mem_alloc.h']]],
+ ['vmacheckcorruption_16',['vmaCheckCorruption',['../group__group__alloc.html#ga49329a7f030dafcf82f7b73334c22e98',1,'vk_mem_alloc.h']]],
+ ['vmacheckpoolcorruption_17',['vmaCheckPoolCorruption',['../group__group__alloc.html#gad535935619c7a549bf837e1bb0068f89',1,'vk_mem_alloc.h']]],
+ ['vmaclearvirtualblock_18',['vmaClearVirtualBlock',['../group__group__virtual.html#ga5eda6f55919fb05bd2f56a112590c571',1,'vk_mem_alloc.h']]],
+ ['vmacreateallocator_19',['vmaCreateAllocator',['../group__group__init.html#ga200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
+ ['vmacreatebuffer_20',['vmaCreateBuffer',['../group__group__alloc.html#gac72ee55598617e8eecca384e746bab51',1,'vk_mem_alloc.h']]],
+ ['vmacreatebufferwithalignment_21',['vmaCreateBufferWithAlignment',['../group__group__alloc.html#gaa06a690013a0d01e60894ac378083834',1,'vk_mem_alloc.h']]],
+ ['vmacreateimage_22',['vmaCreateImage',['../group__group__alloc.html#ga02a94f25679275851a53e82eacbcfc73',1,'vk_mem_alloc.h']]],
+ ['vmacreatepool_23',['vmaCreatePool',['../group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50',1,'vk_mem_alloc.h']]],
+ ['vmacreatevirtualblock_24',['vmaCreateVirtualBlock',['../group__group__virtual.html#gab585754076877265fdae33e5c40ef13b',1,'vk_mem_alloc.h']]],
+ ['vmadestroyallocator_25',['vmaDestroyAllocator',['../group__group__init.html#gaa8d164061c88f22fb1fd3c8f3534bc1d',1,'vk_mem_alloc.h']]],
+ ['vmadestroybuffer_26',['vmaDestroyBuffer',['../group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77',1,'vk_mem_alloc.h']]],
+ ['vmadestroyimage_27',['vmaDestroyImage',['../group__group__alloc.html#gae50d2cb3b4a3bfd4dd40987234e50e7e',1,'vk_mem_alloc.h']]],
+ ['vmadestroypool_28',['vmaDestroyPool',['../group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1',1,'vk_mem_alloc.h']]],
+ ['vmadestroyvirtualblock_29',['vmaDestroyVirtualBlock',['../group__group__virtual.html#ga3795f7783ae2c182cede067d656f66a5',1,'vk_mem_alloc.h']]],
+ ['vmaenddefragmentation_30',['vmaEndDefragmentation',['../group__group__alloc.html#ga729a594b45ae1681096940a44f3eb174',1,'vk_mem_alloc.h']]],
+ ['vmaenddefragmentationpass_31',['vmaEndDefragmentationPass',['../group__group__alloc.html#gaded05a445742a00718ee766144c5c226',1,'vk_mem_alloc.h']]],
+ ['vmafindmemorytypeindex_32',['vmaFindMemoryTypeIndex',['../group__group__alloc.html#gaef15a94b58fbcb0fe706d5720e84a74a',1,'vk_mem_alloc.h']]],
+ ['vmafindmemorytypeindexforbufferinfo_33',['vmaFindMemoryTypeIndexForBufferInfo',['../group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888',1,'vk_mem_alloc.h']]],
+ ['vmafindmemorytypeindexforimageinfo_34',['vmaFindMemoryTypeIndexForImageInfo',['../group__group__alloc.html#ga088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
+ ['vmaflushallocation_35',['vmaFlushAllocation',['../group__group__alloc.html#ga30c37c1eec6025f397be41644f48490f',1,'vk_mem_alloc.h']]],
+ ['vmaflushallocations_36',['vmaFlushAllocations',['../group__group__alloc.html#gac3dd00da721875ed99fa8a881922bdfc',1,'vk_mem_alloc.h']]],
+ ['vmafreememory_37',['vmaFreeMemory',['../group__group__alloc.html#ga5fea5518972ae9094b1526cbcb19b05f',1,'vk_mem_alloc.h']]],
+ ['vmafreememorypages_38',['vmaFreeMemoryPages',['../group__group__alloc.html#ga834b1e4aef395c0a1d56a28e69a4a17e',1,'vk_mem_alloc.h']]],
+ ['vmafreestatsstring_39',['vmaFreeStatsString',['../group__group__stats.html#ga3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
+ ['vmafreevirtualblockstatsstring_40',['vmaFreeVirtualBlockStatsString',['../group__group__stats.html#ga47fb8d8aa69df4a7c23a9719b4080623',1,'vk_mem_alloc.h']]],
+ ['vmagetallocationinfo_41',['vmaGetAllocationInfo',['../group__group__alloc.html#ga86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
+ ['vmagetallocationmemoryproperties_42',['vmaGetAllocationMemoryProperties',['../group__group__alloc.html#ga571e87dd38e552249b56b1b0b982fad1',1,'vk_mem_alloc.h']]],
+ ['vmagetallocatorinfo_43',['vmaGetAllocatorInfo',['../group__group__init.html#gafa02231a791b37255720d566a52683e7',1,'vk_mem_alloc.h']]],
+ ['vmagetheapbudgets_44',['vmaGetHeapBudgets',['../group__group__stats.html#ga9f88db9d46a432c0ad7278cecbc5eaa7',1,'vk_mem_alloc.h']]],
+ ['vmagetmemoryproperties_45',['vmaGetMemoryProperties',['../group__group__init.html#gab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]],
+ ['vmagetmemorytypeproperties_46',['vmaGetMemoryTypeProperties',['../group__group__init.html#ga8701444752eb5de4464adb5a2b514bca',1,'vk_mem_alloc.h']]],
+ ['vmagetphysicaldeviceproperties_47',['vmaGetPhysicalDeviceProperties',['../group__group__init.html#gaecabf7b6e91ea87d0316fa0a9e014fe0',1,'vk_mem_alloc.h']]],
+ ['vmagetpoolname_48',['vmaGetPoolName',['../group__group__alloc.html#gaf09b4e4eafdbee812e8d73ddf960f030',1,'vk_mem_alloc.h']]],
+ ['vmagetpoolstatistics_49',['vmaGetPoolStatistics',['../group__group__stats.html#ga34d8e7d83774eed0caee5c5ae88e217d',1,'vk_mem_alloc.h']]],
+ ['vmagetvirtualallocationinfo_50',['vmaGetVirtualAllocationInfo',['../group__group__virtual.html#ga8ee14ceb1fe033ec84d8aa29e1f75afa',1,'vk_mem_alloc.h']]],
+ ['vmagetvirtualblockstatistics_51',['vmaGetVirtualBlockStatistics',['../group__group__virtual.html#ga2902aa3130866afcc64bb5f984113db3',1,'vk_mem_alloc.h']]],
+ ['vmainvalidateallocation_52',['vmaInvalidateAllocation',['../group__group__alloc.html#gaaa8412919139ef413a4215ac6a290fae',1,'vk_mem_alloc.h']]],
+ ['vmainvalidateallocations_53',['vmaInvalidateAllocations',['../group__group__alloc.html#gab25b558d75f7378ec944a1522fdcc3c5',1,'vk_mem_alloc.h']]],
+ ['vmaisvirtualblockempty_54',['vmaIsVirtualBlockEmpty',['../group__group__virtual.html#gacd53b5b1d23f8fcbad692ccfdc1811f1',1,'vk_mem_alloc.h']]],
+ ['vmamapmemory_55',['vmaMapMemory',['../group__group__alloc.html#gad5bd1243512d099706de88168992f069',1,'vk_mem_alloc.h']]],
+ ['vmasetallocationuserdata_56',['vmaSetAllocationUserData',['../group__group__alloc.html#gaf9147d31ffc11d62fc187bde283ed14f',1,'vk_mem_alloc.h']]],
+ ['vmasetcurrentframeindex_57',['vmaSetCurrentFrameIndex',['../group__group__init.html#gade56bf8dc9f5a5eaddf5f119ed525236',1,'vk_mem_alloc.h']]],
+ ['vmasetpoolname_58',['vmaSetPoolName',['../group__group__alloc.html#gadbae3a0b4ab078024462fc85c37f3b58',1,'vk_mem_alloc.h']]],
+ ['vmasetvirtualallocationuserdata_59',['vmaSetVirtualAllocationUserData',['../group__group__virtual.html#ga001ea1850458a4062b829e09c303fca2',1,'vk_mem_alloc.h']]],
+ ['vmaunmapmemory_60',['vmaUnmapMemory',['../group__group__alloc.html#ga9bc268595cb33f6ec4d519cfce81ff45',1,'vk_mem_alloc.h']]],
+ ['vmavirtualallocate_61',['vmaVirtualAllocate',['../group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01',1,'vk_mem_alloc.h']]],
+ ['vmavirtualfree_62',['vmaVirtualFree',['../group__group__virtual.html#ga09fc688c0c3653ff23723b037e5d5033',1,'vk_mem_alloc.h']]]
];
diff --git a/docs/html/search/searchdata.js b/docs/html/search/searchdata.js
index 1e1ddfd..bca200b 100644
--- a/docs/html/search/searchdata.js
+++ b/docs/html/search/searchdata.js
@@ -4,7 +4,7 @@ var indexSectionsWithContent =
1: "v",
2: "v",
3: "v",
- 4: "abcdfimoprstuv",
+ 4: "abdfimoprstuv",
5: "pv",
6: "v",
7: "v",
diff --git a/docs/html/search/typedefs_1.js b/docs/html/search/typedefs_1.js
index 2f7804d..7c0f4cc 100644
--- a/docs/html/search/typedefs_1.js
+++ b/docs/html/search/typedefs_1.js
@@ -12,8 +12,8 @@ var searchData=
['vmadefragmentationflagbits_9',['VmaDefragmentationFlagBits',['../group__group__alloc.html#ga13415cc0b443353a7b5abda300b833fc',1,'vk_mem_alloc.h']]],
['vmadefragmentationflags_10',['VmaDefragmentationFlags',['../group__group__alloc.html#ga88a77cef37e5d3c4fc9eb328885d048d',1,'vk_mem_alloc.h']]],
['vmadefragmentationinfo_11',['VmaDefragmentationInfo',['../group__group__alloc.html#ga2bf47f96bf92bed2a49461bd9af3acfa',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationinfo2_12',['VmaDefragmentationInfo2',['../group__group__alloc.html#gad6daeffaa670ce6d11a203a6224c9937',1,'vk_mem_alloc.h']]],
- ['vmadefragmentationpassinfo_13',['VmaDefragmentationPassInfo',['../group__group__alloc.html#ga72aebd522242d56abea67b4f47f6549e',1,'vk_mem_alloc.h']]],
+ ['vmadefragmentationmove_12',['VmaDefragmentationMove',['../group__group__alloc.html#ga563f4b43d3e31ed603d80cacc9ba8589',1,'vk_mem_alloc.h']]],
+ ['vmadefragmentationmoveoperation_13',['VmaDefragmentationMoveOperation',['../group__group__alloc.html#ga2ea666deeb3c2c74806a097e27cdb4a1',1,'vk_mem_alloc.h']]],
['vmadefragmentationpassmoveinfo_14',['VmaDefragmentationPassMoveInfo',['../group__group__alloc.html#gad6799e8e2b1527abfc84d33bc44aeaf5',1,'vk_mem_alloc.h']]],
['vmadefragmentationstats_15',['VmaDefragmentationStats',['../group__group__alloc.html#gad94034192259c2e34a4d1c5e27810403',1,'vk_mem_alloc.h']]],
['vmadetailedstatistics_16',['VmaDetailedStatistics',['../group__group__stats.html#ga9ab0c535a6ca655dc63b8609ab4b8394',1,'vk_mem_alloc.h']]],
diff --git a/docs/html/search/variables_0.js b/docs/html/search/variables_0.js
index 7f847e7..4b35f54 100644
--- a/docs/html/search/variables_0.js
+++ b/docs/html/search/variables_0.js
@@ -1,10 +1,9 @@
var searchData=
[
['alignment_0',['alignment',['../struct_vma_virtual_allocation_create_info.html#a9d19709872fc1904a105079e1c885821',1,'VmaVirtualAllocationCreateInfo']]],
- ['allocation_1',['allocation',['../struct_vma_defragmentation_pass_move_info.html#ae885c861c2dd8d622e6c19e281d035cc',1,'VmaDefragmentationPassMoveInfo']]],
- ['allocationbytes_2',['allocationBytes',['../struct_vma_statistics.html#a21db06eba3422f87a2b4b4703d879c16',1,'VmaStatistics']]],
- ['allocationcount_3',['allocationCount',['../struct_vma_statistics.html#ab0ff76e50f58f9f54b6f265e5bf5dde2',1,'VmaStatistics::allocationCount()'],['../struct_vma_defragmentation_info2.html#a3cf86ab32c1da779b4923d301a3056ba',1,'VmaDefragmentationInfo2::allocationCount()']]],
- ['allocationsizemax_4',['allocationSizeMax',['../struct_vma_detailed_statistics.html#a06b2add24eed3449a66ff151979a0201',1,'VmaDetailedStatistics']]],
- ['allocationsizemin_5',['allocationSizeMin',['../struct_vma_detailed_statistics.html#a6fb397e7487e10f2a52e241577d2a2b8',1,'VmaDetailedStatistics']]],
- ['allocationsmoved_6',['allocationsMoved',['../struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9',1,'VmaDefragmentationStats']]]
+ ['allocationbytes_1',['allocationBytes',['../struct_vma_statistics.html#a21db06eba3422f87a2b4b4703d879c16',1,'VmaStatistics']]],
+ ['allocationcount_2',['allocationCount',['../struct_vma_statistics.html#ab0ff76e50f58f9f54b6f265e5bf5dde2',1,'VmaStatistics']]],
+ ['allocationsizemax_3',['allocationSizeMax',['../struct_vma_detailed_statistics.html#a06b2add24eed3449a66ff151979a0201',1,'VmaDetailedStatistics']]],
+ ['allocationsizemin_4',['allocationSizeMin',['../struct_vma_detailed_statistics.html#a6fb397e7487e10f2a52e241577d2a2b8',1,'VmaDetailedStatistics']]],
+ ['allocationsmoved_5',['allocationsMoved',['../struct_vma_defragmentation_stats.html#aefeabf130022008eadd75999478af3f9',1,'VmaDefragmentationStats']]]
];
diff --git a/docs/html/search/variables_2.js b/docs/html/search/variables_2.js
index 2162c2a..b763c1a 100644
--- a/docs/html/search/variables_2.js
+++ b/docs/html/search/variables_2.js
@@ -1,4 +1,8 @@
var searchData=
[
- ['commandbuffer_0',['commandBuffer',['../struct_vma_defragmentation_info2.html#a7f71f39590c5316771493d2333f9c1bd',1,'VmaDefragmentationInfo2']]]
+ ['device_0',['device',['../struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500',1,'VmaAllocatorCreateInfo::device()'],['../struct_vma_allocator_info.html#a012b4c485bf3b0ea8921352c5ee0c357',1,'VmaAllocatorInfo::device()']]],
+ ['devicememory_1',['deviceMemory',['../struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67',1,'VmaAllocationInfo']]],
+ ['devicememoryblocksfreed_2',['deviceMemoryBlocksFreed',['../struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b',1,'VmaDefragmentationStats']]],
+ ['dstmemory_3',['dstMemory',['../struct_vma_defragmentation_move.html#a382fbec8dac2747abdc1883b69ef9458',1,'VmaDefragmentationMove']]],
+ ['dstoffset_4',['dstOffset',['../struct_vma_defragmentation_move.html#a80c466b445bc272f82c7dbf1a971ba18',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/variables_3.js b/docs/html/search/variables_3.js
index c71cdf3..ed45c51 100644
--- a/docs/html/search/variables_3.js
+++ b/docs/html/search/variables_3.js
@@ -1,6 +1,4 @@
var searchData=
[
- ['device_0',['device',['../struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500',1,'VmaAllocatorCreateInfo::device()'],['../struct_vma_allocator_info.html#a012b4c485bf3b0ea8921352c5ee0c357',1,'VmaAllocatorInfo::device()']]],
- ['devicememory_1',['deviceMemory',['../struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67',1,'VmaAllocationInfo']]],
- ['devicememoryblocksfreed_2',['deviceMemoryBlocksFreed',['../struct_vma_defragmentation_stats.html#a0113f1877904a5d1ee8f409216ff276b',1,'VmaDefragmentationStats']]]
+ ['flags_0',['flags',['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()'],['../struct_vma_defragmentation_info.html#a3e23080c978ecf3abb3180f5b2069da7',1,'VmaDefragmentationInfo::flags()'],['../struct_vma_virtual_block_create_info.html#aaab9bf7e2d228c02ab6d90a72a6e6912',1,'VmaVirtualBlockCreateInfo::flags()'],['../struct_vma_virtual_allocation_create_info.html#ab10e16956cc4bf20ced9de77d1129ea4',1,'VmaVirtualAllocationCreateInfo::flags()']]]
];
diff --git a/docs/html/search/variables_4.js b/docs/html/search/variables_4.js
index 00173a3..be9f324 100644
--- a/docs/html/search/variables_4.js
+++ b/docs/html/search/variables_4.js
@@ -1,4 +1,5 @@
var searchData=
[
- ['flags_0',['flags',['../struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346',1,'VmaAllocatorCreateInfo::flags()'],['../struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b',1,'VmaAllocationCreateInfo::flags()'],['../struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446',1,'VmaPoolCreateInfo::flags()'],['../struct_vma_defragmentation_info2.html#a53e844ee5633e229cf6daf14b2d9fff9',1,'VmaDefragmentationInfo2::flags()'],['../struct_vma_virtual_block_create_info.html#aaab9bf7e2d228c02ab6d90a72a6e6912',1,'VmaVirtualBlockCreateInfo::flags()'],['../struct_vma_virtual_allocation_create_info.html#ab10e16956cc4bf20ced9de77d1129ea4',1,'VmaVirtualAllocationCreateInfo::flags()']]]
+ ['instance_0',['instance',['../struct_vma_allocator_create_info.html#a70dd42e29b1df1d1b9b61532ae0b370b',1,'VmaAllocatorCreateInfo::instance()'],['../struct_vma_allocator_info.html#a2ed6a4d2d3fea039d66a13f15d0ce5fe',1,'VmaAllocatorInfo::instance()']]],
+ ['internaldata_1',['internalData',['../struct_vma_defragmentation_move.html#a4f3637400767f3e642b3936e18b00e0f',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/variables_5.js b/docs/html/search/variables_5.js
index de9b72c..ef542b0 100644
--- a/docs/html/search/variables_5.js
+++ b/docs/html/search/variables_5.js
@@ -1,4 +1,13 @@
var searchData=
[
- ['instance_0',['instance',['../struct_vma_allocator_create_info.html#a70dd42e29b1df1d1b9b61532ae0b370b',1,'VmaAllocatorCreateInfo::instance()'],['../struct_vma_allocator_info.html#a2ed6a4d2d3fea039d66a13f15d0ce5fe',1,'VmaAllocatorInfo::instance()']]]
+ ['maxallocationsperpass_0',['maxAllocationsPerPass',['../struct_vma_defragmentation_info.html#ac2db29d309bebc4f7d55041416e9694b',1,'VmaDefragmentationInfo']]],
+ ['maxblockcount_1',['maxBlockCount',['../struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c',1,'VmaPoolCreateInfo']]],
+ ['maxbytesperpass_2',['maxBytesPerPass',['../struct_vma_defragmentation_info.html#a637ada77b02179a27fa92290000afac4',1,'VmaDefragmentationInfo']]],
+ ['memoryheap_3',['memoryHeap',['../struct_vma_total_statistics.html#a39beeba5b3a2e7cfe5f5e2331a2705ce',1,'VmaTotalStatistics']]],
+ ['memorytype_4',['memoryType',['../struct_vma_total_statistics.html#acb70e5b7fe543813ed8ba9282640969d',1,'VmaTotalStatistics::memoryType()'],['../struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5',1,'VmaAllocationInfo::memoryType()']]],
+ ['memorytypebits_5',['memoryTypeBits',['../struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055',1,'VmaAllocationCreateInfo']]],
+ ['memorytypeindex_6',['memoryTypeIndex',['../struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319',1,'VmaPoolCreateInfo']]],
+ ['minallocationalignment_7',['minAllocationAlignment',['../struct_vma_pool_create_info.html#ade3eca546f0c6ab4e8fbf20eb6d854cb',1,'VmaPoolCreateInfo']]],
+ ['minblockcount_8',['minBlockCount',['../struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae',1,'VmaPoolCreateInfo']]],
+ ['movecount_9',['moveCount',['../struct_vma_defragmentation_pass_move_info.html#a1b3e18c23f9691f35baf183e615c4408',1,'VmaDefragmentationPassMoveInfo']]]
];
diff --git a/docs/html/search/variables_6.js b/docs/html/search/variables_6.js
index ccb48f6..a6e0daa 100644
--- a/docs/html/search/variables_6.js
+++ b/docs/html/search/variables_6.js
@@ -1,18 +1,5 @@
var searchData=
[
- ['maxallocationstomove_0',['maxAllocationsToMove',['../struct_vma_defragmentation_info.html#aa7c7304e13c71f604c907196c4e28fbc',1,'VmaDefragmentationInfo']]],
- ['maxblockcount_1',['maxBlockCount',['../struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c',1,'VmaPoolCreateInfo']]],
- ['maxbytestomove_2',['maxBytesToMove',['../struct_vma_defragmentation_info.html#acb311c940a777270e67e1b81c5ab6a1d',1,'VmaDefragmentationInfo']]],
- ['maxcpuallocationstomove_3',['maxCpuAllocationsToMove',['../struct_vma_defragmentation_info2.html#a94c2c7223d52878445a8cccce396b671',1,'VmaDefragmentationInfo2']]],
- ['maxcpubytestomove_4',['maxCpuBytesToMove',['../struct_vma_defragmentation_info2.html#af78e1ea40c22d85137b65f6b384a4d0a',1,'VmaDefragmentationInfo2']]],
- ['maxgpuallocationstomove_5',['maxGpuAllocationsToMove',['../struct_vma_defragmentation_info2.html#a40d53d33e71ba0b66f844ed63c05a3f6',1,'VmaDefragmentationInfo2']]],
- ['maxgpubytestomove_6',['maxGpuBytesToMove',['../struct_vma_defragmentation_info2.html#a4ddbc898d0afe1518f863a3763628f08',1,'VmaDefragmentationInfo2']]],
- ['memory_7',['memory',['../struct_vma_defragmentation_pass_move_info.html#a06eb0c8690aa0d3478a036753492e769',1,'VmaDefragmentationPassMoveInfo']]],
- ['memoryheap_8',['memoryHeap',['../struct_vma_total_statistics.html#a39beeba5b3a2e7cfe5f5e2331a2705ce',1,'VmaTotalStatistics']]],
- ['memorytype_9',['memoryType',['../struct_vma_total_statistics.html#acb70e5b7fe543813ed8ba9282640969d',1,'VmaTotalStatistics::memoryType()'],['../struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5',1,'VmaAllocationInfo::memoryType()']]],
- ['memorytypebits_10',['memoryTypeBits',['../struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055',1,'VmaAllocationCreateInfo']]],
- ['memorytypeindex_11',['memoryTypeIndex',['../struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319',1,'VmaPoolCreateInfo']]],
- ['minallocationalignment_12',['minAllocationAlignment',['../struct_vma_pool_create_info.html#ade3eca546f0c6ab4e8fbf20eb6d854cb',1,'VmaPoolCreateInfo']]],
- ['minblockcount_13',['minBlockCount',['../struct_vma_pool_create_info.html#ad8006fb803185c0a699d30f3e9a865ae',1,'VmaPoolCreateInfo']]],
- ['movecount_14',['moveCount',['../struct_vma_defragmentation_pass_info.html#ac1086e657ba995f8d1f4e49b83dcfb6c',1,'VmaDefragmentationPassInfo']]]
+ ['offset_0',['offset',['../struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268',1,'VmaAllocationInfo::offset()'],['../struct_vma_virtual_allocation_info.html#accb40a8205f49ccca3de975da7d1a2b5',1,'VmaVirtualAllocationInfo::offset()']]],
+ ['operation_1',['operation',['../struct_vma_defragmentation_move.html#a20996a4686c9246dff77b375ac4a91e2',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/variables_7.js b/docs/html/search/variables_7.js
index 95a7ac4..06db0e6 100644
--- a/docs/html/search/variables_7.js
+++ b/docs/html/search/variables_7.js
@@ -1,4 +1,19 @@
var searchData=
[
- ['offset_0',['offset',['../struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268',1,'VmaAllocationInfo::offset()'],['../struct_vma_defragmentation_pass_move_info.html#a8ab4508bc03625b0653c880576be96c6',1,'VmaDefragmentationPassMoveInfo::offset()'],['../struct_vma_virtual_allocation_info.html#accb40a8205f49ccca3de975da7d1a2b5',1,'VmaVirtualAllocationInfo::offset()']]]
+ ['pallocationcallbacks_0',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo::pAllocationCallbacks()'],['../struct_vma_virtual_block_create_info.html#a290283bf915c257d24584872d793ad30',1,'VmaVirtualBlockCreateInfo::pAllocationCallbacks()']]],
+ ['pdevicememorycallbacks_1',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
+ ['pfnallocate_2',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
+ ['pfnfree_3',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
+ ['pheapsizelimit_4',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
+ ['physicaldevice_5',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo::physicalDevice()'],['../struct_vma_allocator_info.html#aba2b703f96e51d567717e1fb2935b47a',1,'VmaAllocatorInfo::physicalDevice()']]],
+ ['pmappeddata_6',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
+ ['pmemoryallocatenext_7',['pMemoryAllocateNext',['../struct_vma_pool_create_info.html#af0f8c58f51a2a7a0a389dc79565044d7',1,'VmaPoolCreateInfo']]],
+ ['pmoves_8',['pMoves',['../struct_vma_defragmentation_pass_move_info.html#adfa7a4994afd9b940e7f1dfaf436a725',1,'VmaDefragmentationPassMoveInfo']]],
+ ['pool_9',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo::pool()'],['../struct_vma_defragmentation_info.html#a18dd2097d8ab2976cdc7dd3e7b978bd4',1,'VmaDefragmentationInfo::pool()']]],
+ ['preferredflags_10',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
+ ['preferredlargeheapblocksize_11',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
+ ['priority_12',['priority',['../struct_vma_allocation_create_info.html#a983d39e1a2e63649d78a960aa2fdd0f7',1,'VmaAllocationCreateInfo::priority()'],['../struct_vma_pool_create_info.html#a16e686c688f6725f119ebf6e24ab5274',1,'VmaPoolCreateInfo::priority()']]],
+ ['ptypeexternalmemoryhandletypes_13',['pTypeExternalMemoryHandleTypes',['../struct_vma_allocator_create_info.html#ae8f0db05e5cb4c43d7713bf4a49a736b',1,'VmaAllocatorCreateInfo']]],
+ ['puserdata_14',['pUserData',['../struct_vma_device_memory_callbacks.html#a24052de0937ddd54015a2df0363903c6',1,'VmaDeviceMemoryCallbacks::pUserData()'],['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()'],['../struct_vma_virtual_allocation_create_info.html#a015f8544ca51a7350f7434d42d0587bb',1,'VmaVirtualAllocationCreateInfo::pUserData()'],['../struct_vma_virtual_allocation_info.html#a41d5cb09357656411653d82fee436f45',1,'VmaVirtualAllocationInfo::pUserData()']]],
+ ['pvulkanfunctions_15',['pVulkanFunctions',['../struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd',1,'VmaAllocatorCreateInfo']]]
];
diff --git a/docs/html/search/variables_8.js b/docs/html/search/variables_8.js
index 2e46be0..4d04dae 100644
--- a/docs/html/search/variables_8.js
+++ b/docs/html/search/variables_8.js
@@ -1,23 +1,4 @@
var searchData=
[
- ['pallocationcallbacks_0',['pAllocationCallbacks',['../struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d',1,'VmaAllocatorCreateInfo::pAllocationCallbacks()'],['../struct_vma_virtual_block_create_info.html#a290283bf915c257d24584872d793ad30',1,'VmaVirtualBlockCreateInfo::pAllocationCallbacks()']]],
- ['pallocations_1',['pAllocations',['../struct_vma_defragmentation_info2.html#ab6d288f29d028156cf73542d630a2e32',1,'VmaDefragmentationInfo2']]],
- ['pallocationschanged_2',['pAllocationsChanged',['../struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc',1,'VmaDefragmentationInfo2']]],
- ['pdevicememorycallbacks_3',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
- ['pfnallocate_4',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
- ['pfnfree_5',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
- ['pheapsizelimit_6',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
- ['physicaldevice_7',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo::physicalDevice()'],['../struct_vma_allocator_info.html#aba2b703f96e51d567717e1fb2935b47a',1,'VmaAllocatorInfo::physicalDevice()']]],
- ['pmappeddata_8',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
- ['pmemoryallocatenext_9',['pMemoryAllocateNext',['../struct_vma_pool_create_info.html#af0f8c58f51a2a7a0a389dc79565044d7',1,'VmaPoolCreateInfo']]],
- ['pmoves_10',['pMoves',['../struct_vma_defragmentation_pass_info.html#acbd42d4a3357999da130a95cd99a3792',1,'VmaDefragmentationPassInfo']]],
- ['pool_11',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
- ['poolcount_12',['poolCount',['../struct_vma_defragmentation_info2.html#a7e70aa2a1081d849dcc7829b19d3ec9d',1,'VmaDefragmentationInfo2']]],
- ['ppools_13',['pPools',['../struct_vma_defragmentation_info2.html#a3c9c6aa5c97d5670f8e362b3a6f3029b',1,'VmaDefragmentationInfo2']]],
- ['preferredflags_14',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
- ['preferredlargeheapblocksize_15',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
- ['priority_16',['priority',['../struct_vma_allocation_create_info.html#a983d39e1a2e63649d78a960aa2fdd0f7',1,'VmaAllocationCreateInfo::priority()'],['../struct_vma_pool_create_info.html#a16e686c688f6725f119ebf6e24ab5274',1,'VmaPoolCreateInfo::priority()']]],
- ['ptypeexternalmemoryhandletypes_17',['pTypeExternalMemoryHandleTypes',['../struct_vma_allocator_create_info.html#ae8f0db05e5cb4c43d7713bf4a49a736b',1,'VmaAllocatorCreateInfo']]],
- ['puserdata_18',['pUserData',['../struct_vma_device_memory_callbacks.html#a24052de0937ddd54015a2df0363903c6',1,'VmaDeviceMemoryCallbacks::pUserData()'],['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()'],['../struct_vma_virtual_allocation_create_info.html#a015f8544ca51a7350f7434d42d0587bb',1,'VmaVirtualAllocationCreateInfo::pUserData()'],['../struct_vma_virtual_allocation_info.html#a41d5cb09357656411653d82fee436f45',1,'VmaVirtualAllocationInfo::pUserData()']]],
- ['pvulkanfunctions_19',['pVulkanFunctions',['../struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd',1,'VmaAllocatorCreateInfo']]]
+ ['requiredflags_0',['requiredFlags',['../struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90',1,'VmaAllocationCreateInfo']]]
];
diff --git a/docs/html/search/variables_9.js b/docs/html/search/variables_9.js
index 4d04dae..9bc4f4e 100644
--- a/docs/html/search/variables_9.js
+++ b/docs/html/search/variables_9.js
@@ -1,4 +1,6 @@
var searchData=
[
- ['requiredflags_0',['requiredFlags',['../struct_vma_allocation_create_info.html#a9166390303ff42d783305bc31c2b6b90',1,'VmaAllocationCreateInfo']]]
+ ['size_0',['size',['../struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f',1,'VmaAllocationInfo::size()'],['../struct_vma_virtual_block_create_info.html#a670ab8c6a6e822f3c36781d79e8824e9',1,'VmaVirtualBlockCreateInfo::size()'],['../struct_vma_virtual_allocation_create_info.html#aae08752b86817abd0d944c6025dc603e',1,'VmaVirtualAllocationCreateInfo::size()'],['../struct_vma_virtual_allocation_info.html#afb6d6bd0a6813869ea0842048d40aa2b',1,'VmaVirtualAllocationInfo::size()']]],
+ ['srcallocation_1',['srcAllocation',['../struct_vma_defragmentation_move.html#a25aa1bb64efc507a49c6cbc50689f862',1,'VmaDefragmentationMove']]],
+ ['statistics_2',['statistics',['../struct_vma_detailed_statistics.html#a13efbdb35bd1291191d275f43e96d360',1,'VmaDetailedStatistics::statistics()'],['../struct_vma_budget.html#a6d15ab3a798fd62d9efa3a1e1f83bf54',1,'VmaBudget::statistics()']]]
];
diff --git a/docs/html/search/variables_a.js b/docs/html/search/variables_a.js
index e114e1e..2fe757a 100644
--- a/docs/html/search/variables_a.js
+++ b/docs/html/search/variables_a.js
@@ -1,5 +1,4 @@
var searchData=
[
- ['size_0',['size',['../struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f',1,'VmaAllocationInfo::size()'],['../struct_vma_virtual_block_create_info.html#a670ab8c6a6e822f3c36781d79e8824e9',1,'VmaVirtualBlockCreateInfo::size()'],['../struct_vma_virtual_allocation_create_info.html#aae08752b86817abd0d944c6025dc603e',1,'VmaVirtualAllocationCreateInfo::size()'],['../struct_vma_virtual_allocation_info.html#afb6d6bd0a6813869ea0842048d40aa2b',1,'VmaVirtualAllocationInfo::size()']]],
- ['statistics_1',['statistics',['../struct_vma_detailed_statistics.html#a13efbdb35bd1291191d275f43e96d360',1,'VmaDetailedStatistics::statistics()'],['../struct_vma_budget.html#a6d15ab3a798fd62d9efa3a1e1f83bf54',1,'VmaBudget::statistics()']]]
+ ['total_0',['total',['../struct_vma_total_statistics.html#a76f1935f7101883f5bb2a03b6c5649d2',1,'VmaTotalStatistics']]]
];
diff --git a/docs/html/search/variables_b.js b/docs/html/search/variables_b.js
index 2fe757a..c5f6f77 100644
--- a/docs/html/search/variables_b.js
+++ b/docs/html/search/variables_b.js
@@ -1,4 +1,7 @@
var searchData=
[
- ['total_0',['total',['../struct_vma_total_statistics.html#a76f1935f7101883f5bb2a03b6c5649d2',1,'VmaTotalStatistics']]]
+ ['unusedrangecount_0',['unusedRangeCount',['../struct_vma_detailed_statistics.html#ab721bf04892e8b67802d4ddb7734638a',1,'VmaDetailedStatistics']]],
+ ['unusedrangesizemax_1',['unusedRangeSizeMax',['../struct_vma_detailed_statistics.html#af98943b5da98cf441ffa04b67914c78c',1,'VmaDetailedStatistics']]],
+ ['unusedrangesizemin_2',['unusedRangeSizeMin',['../struct_vma_detailed_statistics.html#a830eda847ed735d0e91da25cfcf797a4',1,'VmaDetailedStatistics']]],
+ ['usage_3',['usage',['../struct_vma_budget.html#a84dd1ecca8b0110259eb206dbadb11f6',1,'VmaBudget::usage()'],['../struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910',1,'VmaAllocationCreateInfo::usage()']]]
];
diff --git a/docs/html/search/variables_c.js b/docs/html/search/variables_c.js
index c5f6f77..896216d 100644
--- a/docs/html/search/variables_c.js
+++ b/docs/html/search/variables_c.js
@@ -1,7 +1,30 @@
var searchData=
[
- ['unusedrangecount_0',['unusedRangeCount',['../struct_vma_detailed_statistics.html#ab721bf04892e8b67802d4ddb7734638a',1,'VmaDetailedStatistics']]],
- ['unusedrangesizemax_1',['unusedRangeSizeMax',['../struct_vma_detailed_statistics.html#af98943b5da98cf441ffa04b67914c78c',1,'VmaDetailedStatistics']]],
- ['unusedrangesizemin_2',['unusedRangeSizeMin',['../struct_vma_detailed_statistics.html#a830eda847ed735d0e91da25cfcf797a4',1,'VmaDetailedStatistics']]],
- ['usage_3',['usage',['../struct_vma_budget.html#a84dd1ecca8b0110259eb206dbadb11f6',1,'VmaBudget::usage()'],['../struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910',1,'VmaAllocationCreateInfo::usage()']]]
+ ['vkallocatememory_0',['vkAllocateMemory',['../struct_vma_vulkan_functions.html#a2943bf99dfd784a0e8f599d987e22e6c',1,'VmaVulkanFunctions']]],
+ ['vkbindbuffermemory_1',['vkBindBufferMemory',['../struct_vma_vulkan_functions.html#a94fc4f3a605d9880bb3c0ba2c2fc80b2',1,'VmaVulkanFunctions']]],
+ ['vkbindbuffermemory2khr_2',['vkBindBufferMemory2KHR',['../struct_vma_vulkan_functions.html#a0c4907235aab9df2767b79836afa2dc9',1,'VmaVulkanFunctions']]],
+ ['vkbindimagememory_3',['vkBindImageMemory',['../struct_vma_vulkan_functions.html#a1338d96a128a5ade648b8d934907c637',1,'VmaVulkanFunctions']]],
+ ['vkbindimagememory2khr_4',['vkBindImageMemory2KHR',['../struct_vma_vulkan_functions.html#ab95aaa73ab8a3fe9fd3daaaec4e0b2bf',1,'VmaVulkanFunctions']]],
+ ['vkcmdcopybuffer_5',['vkCmdCopyBuffer',['../struct_vma_vulkan_functions.html#ae5c0db8c89a3b82593dc16aa6a49fa3a',1,'VmaVulkanFunctions']]],
+ ['vkcreatebuffer_6',['vkCreateBuffer',['../struct_vma_vulkan_functions.html#ae8084315a25006271a2edfc3a447519f',1,'VmaVulkanFunctions']]],
+ ['vkcreateimage_7',['vkCreateImage',['../struct_vma_vulkan_functions.html#a23ebe70be515b9b5010a1d691200e325',1,'VmaVulkanFunctions']]],
+ ['vkdestroybuffer_8',['vkDestroyBuffer',['../struct_vma_vulkan_functions.html#a7e054606faddb07f0e8556f3ed317d45',1,'VmaVulkanFunctions']]],
+ ['vkdestroyimage_9',['vkDestroyImage',['../struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa',1,'VmaVulkanFunctions']]],
+ ['vkflushmappedmemoryranges_10',['vkFlushMappedMemoryRanges',['../struct_vma_vulkan_functions.html#a33c322f4c4ad2810f8a9c97a277572f9',1,'VmaVulkanFunctions']]],
+ ['vkfreememory_11',['vkFreeMemory',['../struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4',1,'VmaVulkanFunctions']]],
+ ['vkgetbuffermemoryrequirements_12',['vkGetBufferMemoryRequirements',['../struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143',1,'VmaVulkanFunctions']]],
+ ['vkgetbuffermemoryrequirements2khr_13',['vkGetBufferMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c',1,'VmaVulkanFunctions']]],
+ ['vkgetdevicebuffermemoryrequirements_14',['vkGetDeviceBufferMemoryRequirements',['../struct_vma_vulkan_functions.html#a3d6cc5633bdbfec728213d6dfae7d413',1,'VmaVulkanFunctions']]],
+ ['vkgetdeviceimagememoryrequirements_15',['vkGetDeviceImageMemoryRequirements',['../struct_vma_vulkan_functions.html#afd4780c565028cd15498528883f51fc6',1,'VmaVulkanFunctions']]],
+ ['vkgetdeviceprocaddr_16',['vkGetDeviceProcAddr',['../struct_vma_vulkan_functions.html#ac383ab9af127e5e136622fa4ebea9e57',1,'VmaVulkanFunctions']]],
+ ['vkgetimagememoryrequirements_17',['vkGetImageMemoryRequirements',['../struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4',1,'VmaVulkanFunctions']]],
+ ['vkgetimagememoryrequirements2khr_18',['vkGetImageMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875',1,'VmaVulkanFunctions']]],
+ ['vkgetinstanceprocaddr_19',['vkGetInstanceProcAddr',['../struct_vma_vulkan_functions.html#a3eafa102f5f8915f093f40675636b849',1,'VmaVulkanFunctions']]],
+ ['vkgetphysicaldevicememoryproperties_20',['vkGetPhysicalDeviceMemoryProperties',['../struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830',1,'VmaVulkanFunctions']]],
+ ['vkgetphysicaldevicememoryproperties2khr_21',['vkGetPhysicalDeviceMemoryProperties2KHR',['../struct_vma_vulkan_functions.html#a0d992896e6ffcf92b9d7ea049fa5c445',1,'VmaVulkanFunctions']]],
+ ['vkgetphysicaldeviceproperties_22',['vkGetPhysicalDeviceProperties',['../struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96',1,'VmaVulkanFunctions']]],
+ ['vkinvalidatemappedmemoryranges_23',['vkInvalidateMappedMemoryRanges',['../struct_vma_vulkan_functions.html#a5c1093bc32386a8060c37c9f282078a1',1,'VmaVulkanFunctions']]],
+ ['vkmapmemory_24',['vkMapMemory',['../struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49',1,'VmaVulkanFunctions']]],
+ ['vkunmapmemory_25',['vkUnmapMemory',['../struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9',1,'VmaVulkanFunctions']]],
+ ['vulkanapiversion_26',['vulkanApiVersion',['../struct_vma_allocator_create_info.html#ae0ffc55139b54520a6bb704b29ffc285',1,'VmaAllocatorCreateInfo']]]
];
diff --git a/docs/html/struct_vma_allocation_info.html b/docs/html/struct_vma_allocation_info.html
index 8b14bcb..bfcb98f 100644
--- a/docs/html/struct_vma_allocation_info.html
+++ b/docs/html/struct_vma_allocation_info.html
@@ -110,7 +110,7 @@ Public Attributes
Handle to Vulkan memory object.
Same memory object can be shared by multiple allocations.
-It can change after call to vmaDefragment() if this allocation is passed to the function.
+It can change after call to vmaDefragment() if this allocation is passed to the function.
@@ -145,7 +145,7 @@ Public Attributes
Offset in VkDeviceMemory
object to the beginning of this allocation, in bytes. (deviceMemory, offset)
pair is unique to this allocation.
You usually don't need to use this offset. If you create a buffer or an image together with the allocation using e.g. function vmaCreateBuffer() , vmaCreateImage() , functions that operate on these resources refer to the beginning of the buffer or image, not entire device memory block. Functions like vmaMapMemory() , vmaBindBufferMemory() also refer to the beginning of the allocation and apply this offset automatically.
-It can change after call to vmaDefragment() if this allocation is passed to the function.
+It can change after call to vmaDefragment() if this allocation is passed to the function.
@@ -163,7 +163,7 @@ Public Attributes
Pointer to the beginning of this allocation as mapped data.
If the allocation hasn't been mapped using vmaMapMemory() and hasn't been created with VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value is null.
-It can change after call to vmaMapMemory() , vmaUnmapMemory() . It can also change after call to vmaDefragment() if this allocation is passed to the function.
+It can change after call to vmaMapMemory() , vmaUnmapMemory() . It can also change after call to vmaDefragment() if this allocation is passed to the function.
diff --git a/docs/html/struct_vma_defragmentation_context.html b/docs/html/struct_vma_defragmentation_context.html
index 171639d..fee98aa 100644
--- a/docs/html/struct_vma_defragmentation_context.html
+++ b/docs/html/struct_vma_defragmentation_context.html
@@ -66,11 +66,11 @@ $(function() {
-
Represents Opaque object that represents started defragmentation process.
+
An opaque object that represents started defragmentation process.
More...
-
Represents Opaque object that represents started defragmentation process.
-
Fill structure VmaDefragmentationInfo2 and call function vmaDefragmentationBegin() to create it. Call function vmaDefragmentationEnd() to destroy it.
+
An opaque object that represents started defragmentation process.
+
Fill structure VmaDefragmentationInfo and call function vmaBeginDefragmentation() to create it. Call function vmaEndDefragmentation() to destroy it.
The documentation for this struct was generated from the following file:
diff --git a/docs/html/struct_vma_defragmentation_info-members.html b/docs/html/struct_vma_defragmentation_info-members.html
index 0e26a93..0e7b68a 100644
--- a/docs/html/struct_vma_defragmentation_info-members.html
+++ b/docs/html/struct_vma_defragmentation_info-members.html
@@ -68,8 +68,10 @@ $(function() {
This is the complete list of members for VmaDefragmentationInfo , including all inherited members.
-
Deprecated. Optional configuration parameters to be passed to function vmaDefragment() .
+
Parameters for defragmentation.
More...
-
Deprecated. Optional configuration parameters to be passed to function vmaDefragment() .
-
Deprecated: This is a part of the old interface. It is recommended to use structure VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead.
+
Parameters for defragmentation.
+
To be used with function vmaBeginDefragmentation() .
-
-
◆ maxAllocationsToMove
+
+
◆ flags
-
Maximum number of allocations that can be moved to different place.
-
Default is UINT32_MAX
, which means no limit.
+
Use combination of VmaDefragmentationFlagBits .
-
-
◆ maxBytesToMove
+
+
◆ maxAllocationsPerPass
- VkDeviceSize VmaDefragmentationInfo::maxBytesToMove
+ uint32_t VmaDefragmentationInfo::maxAllocationsPerPass
-
Maximum total numbers of bytes that can be copied while moving allocations to different places.
-
Default is VK_WHOLE_SIZE
, which means no limit.
+
Maximum number of allocations that can be moved during single pass to a different place.
+
0
means no limit.
+
+
+
+
+
◆ maxBytesPerPass
+
+
+
+
+
+ VkDeviceSize VmaDefragmentationInfo::maxBytesPerPass
+
+
+
+
+
Maximum numbers of bytes that can be copied during single pass, while moving allocations to different places.
+
0
means no limit.
+
+
+
+
+
◆ pool
+
+
+
+
+
+ VmaPool VmaDefragmentationInfo::pool
+
+
+
+
+
Custom pool to be defragmented.
+
If null then default pools will undergo defragmentation process.
diff --git a/docs/html/struct_vma_defragmentation_move-members.html b/docs/html/struct_vma_defragmentation_move-members.html
new file mode 100644
index 0000000..056f74d
--- /dev/null
+++ b/docs/html/struct_vma_defragmentation_move-members.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
Vulkan Memory Allocator: Member List
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vulkan Memory Allocator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This is the complete list of members for VmaDefragmentationMove , including all inherited members.
+
+
+
+
+
diff --git a/docs/html/struct_vma_defragmentation_move.html b/docs/html/struct_vma_defragmentation_move.html
new file mode 100644
index 0000000..f9a3f4c
--- /dev/null
+++ b/docs/html/struct_vma_defragmentation_move.html
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
Vulkan Memory Allocator: VmaDefragmentationMove Struct Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vulkan Memory Allocator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Single move of an allocation to be done for defragmentation.
+ More...
+
+
+
Single move of an allocation to be done for defragmentation.
+
+
+
◆ dstMemory
+
+
+
+
+
+ VkDeviceMemory VmaDefragmentationMove::dstMemory
+
+
+
+
+
Destination memory block where the allocation should be moved.
+
+
+
+
+
◆ dstOffset
+
+
+
+
+
+ VkDeviceSize VmaDefragmentationMove::dstOffset
+
+
+
+
+
Destination offset where the allocation should be moved.
+
+
+
+
+
◆ internalData
+
+
+
+
+
+ void* VmaDefragmentationMove::internalData
+
+
+
+
+
Internal data used by VMA. Do not use or modify!
+
+
+
+
+
◆ operation
+
+
+
+
◆ srcAllocation
+
+
+
+
+
Allocation that should be moved.
+
+
+
+
The documentation for this struct was generated from the following file:
+
+
+
+
+
diff --git a/docs/html/struct_vma_defragmentation_pass_move_info-members.html b/docs/html/struct_vma_defragmentation_pass_move_info-members.html
index 96425a6..9df2594 100644
--- a/docs/html/struct_vma_defragmentation_pass_move_info-members.html
+++ b/docs/html/struct_vma_defragmentation_pass_move_info-members.html
@@ -68,9 +68,8 @@ $(function() {
This is the complete list of members for VmaDefragmentationPassMoveInfo , including all inherited members.
+
+
Parameters for incremental defragmentation steps.
+ More...
-
-
-
◆ allocation
+
+
Parameters for incremental defragmentation steps.
+
To be used with function vmaBeginDefragmentationPass() .
+
+
+
◆ moveCount
- VmaAllocation VmaDefragmentationPassMoveInfo::allocation
+ uint32_t VmaDefragmentationPassMoveInfo::moveCount
+
Number of elements in the pMoves
array.
+
-
-
◆ memory
+
+
◆ pMoves
- VkDeviceMemory VmaDefragmentationPassMoveInfo::memory
+ VmaDefragmentationMove * VmaDefragmentationPassMoveInfo::pMoves
-
-
-
-
◆ offset
-
-
-
-
-
- VkDeviceSize VmaDefragmentationPassMoveInfo::offset
-
-
-
+
Array of moves to be performed by the user in the current defragmentation pass.
+
Pointer to an array of moveCount
elements, owned by VMA, created in vmaBeginDefragmentationPass() , destroyed in vmaEndDefragmentationPass() .
+
For each element, you should:
+
+Create a new buffer/image in the place pointed by VmaDefragmentationMove::dstMemory + VmaDefragmentationMove::dstOffset .
+Copy data from the VmaDefragmentationMove::srcAllocation e.g. using vkCmdCopyBuffer
, vkCmdCopyImage
.
+Make sure these commands finished executing on the GPU.
+Destroy the old buffer/image.
+
+
Only then you can finish defragmentation pass by calling vmaEndDefragmentationPass() . After this call, the allocation will point to the new place in memory.
+
Alternatively, if you cannot move specific allocation, you can set VmaDefragmentationMove::operation to VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE .
+
Alternatively, if you decide you want to completely remove the allocation:
+
+Destroy its buffer/image.
+Set VmaDefragmentationMove::operation to VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY .
+
+
Then, after vmaEndDefragmentationPass() the allocation will be freed.
diff --git a/docs/html/struct_vma_defragmentation_stats.html b/docs/html/struct_vma_defragmentation_stats.html
index afc49d1..86d9c11 100644
--- a/docs/html/struct_vma_defragmentation_stats.html
+++ b/docs/html/struct_vma_defragmentation_stats.html
@@ -69,7 +69,7 @@ $(function() {
-
Statistics returned by function vmaDefragment() .
+
Statistics returned for defragmentation process in function vmaEndDefragmentation() .
More...
-
Statistics returned by function vmaDefragment() .
+
Statistics returned for defragmentation process in function vmaEndDefragmentation() .
◆ allocationsMoved
diff --git a/docs/html/usage_patterns.html b/docs/html/usage_patterns.html
index cb572f0..8cf973f 100644
--- a/docs/html/usage_patterns.html
+++ b/docs/html/usage_patterns.html
@@ -96,11 +96,11 @@ GPU-only resource
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:493
-
@ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
Set this flag if the allocation should have its own memory block.
Definition: vk_mem_alloc.h:529
-
Definition: vk_mem_alloc.h:1218
-
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1226
-
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1220
+
@ VMA_MEMORY_USAGE_AUTO
Definition: vk_mem_alloc.h:488
+
@ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
Set this flag if the allocation should have its own memory block.
Definition: vk_mem_alloc.h:524
+
Definition: vk_mem_alloc.h:1211
+
VmaMemoryUsage usage
Intended usage of memory.
Definition: vk_mem_alloc.h:1219
+
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:1213
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.
@@ -125,10 +125,10 @@ Staging copy for upload
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
-
@ 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:551
-
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition: vk_mem_alloc.h:598
-
Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1333
-
void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition: vk_mem_alloc.h:1375
+
@ 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:546
+
@ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
Definition: vk_mem_alloc.h:593
+
Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
Definition: vk_mem_alloc.h:1326
+
void * pMappedData
Pointer to the beginning of this allocation as mapped data.
Definition: vk_mem_alloc.h:1368
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
@@ -151,7 +151,7 @@ Readback
...
const
float * downloadedData = (
const float *)allocInfo.
pMappedData ;
-@ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
Definition: vk_mem_alloc.h:610
+@ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
Definition: vk_mem_alloc.h:605
Advanced data uploading
For resources that you frequently write on CPU via mapped pointer and freqnently read on GPU e.g. as a uniform buffer (also called "dynamic"), multiple options are possible:
@@ -220,7 +220,7 @@ Advanced data uploading
vkCmdCopyBuffer(cmdBuf, stagingBuf, buf, 1, &bufCopy);
}
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:622
+@ VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT
Definition: vk_mem_alloc.h:617
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 d38b9c2..d29811c 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:1516
-VkDeviceSize size
Total size of the virtual block.
Definition: vk_mem_alloc.h:1522
+Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().
Definition: vk_mem_alloc.h:1472
+VkDeviceSize size
Total size of the virtual block.
Definition: vk_mem_alloc.h:1478
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:1537
-VkDeviceSize size
Size of the allocation.
Definition: vk_mem_alloc.h:1542
+Parameters of created virtual allocation to be passed to vmaVirtualAllocate().
Definition: vk_mem_alloc.h:1493
+VkDeviceSize size
Size of the allocation.
Definition: vk_mem_alloc.h:1498
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:1560
-void * pUserData
Custom pointer associated with the allocation.
Definition: vk_mem_alloc.h:1575
+Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().
Definition: vk_mem_alloc.h:1516
+void * pUserData
Custom pointer associated with the allocation.
Definition: vk_mem_alloc.h:1531
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:1547
+VkDeviceSize alignment
Required alignment of the allocation. Optional.
Definition: vk_mem_alloc.h:1503
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 vmaGetVirtualBlockStatistics(VmaVirtualBlock virtualBlock, VmaStatistics *pStats)
Calculates and returns statistics about virtual allocations and memory usage in given VmaVirtualBlock...
-Calculated statistics of memory usage e.g. in a specific memory type, heap, custom pool,...
Definition: vk_mem_alloc.h:1111
-VkDeviceSize allocationBytes
Total number of bytes occupied by all VmaAllocation objects.
Definition: vk_mem_alloc.h:1133
-uint32_t allocationCount
Number of VmaAllocation objects allocated.
Definition: vk_mem_alloc.h:1119
+Calculated statistics of memory usage e.g. in a specific memory type, heap, custom pool,...
Definition: vk_mem_alloc.h:1104
+VkDeviceSize allocationBytes
Total number of bytes occupied by all VmaAllocation objects.
Definition: vk_mem_alloc.h:1126
+uint32_t allocationCount
Number of VmaAllocation objects allocated.
Definition: vk_mem_alloc.h:1112
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/docs/html/vk__mem__alloc_8h.html b/docs/html/vk__mem__alloc_8h.html
index bf4b323..d5fa800 100644
--- a/docs/html/vk__mem__alloc_8h.html
+++ b/docs/html/vk__mem__alloc_8h.html
@@ -111,19 +111,17 @@ Classes
struct VmaAllocationInfo
Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo() . More...
-struct VmaDefragmentationInfo2
- Parameters for defragmentation. More...
+struct VmaDefragmentationInfo
+ Parameters for defragmentation. More...
+
+struct VmaDefragmentationMove
+ Single move of an allocation to be done for defragmentation. More...
struct VmaDefragmentationPassMoveInfo
-
-struct VmaDefragmentationPassInfo
- Parameters for incremental defragmentation steps. More...
-
-struct VmaDefragmentationInfo
- Deprecated. Optional configuration parameters to be passed to function vmaDefragment() . More...
+ Parameters for incremental defragmentation steps. More...
struct VmaDefragmentationStats
- Statistics returned by function vmaDefragment() . More...
+ Statistics returned for defragmentation process in function vmaEndDefragmentation() . More...
struct VmaVirtualBlockCreateInfo
Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock() . More...
@@ -170,10 +168,13 @@ Typedefs
Flags to be passed as VmaPoolCreateInfo::flags . See VmaPoolCreateFlagBits . More...
typedef enum VmaDefragmentationFlagBits VmaDefragmentationFlagBits
- Flags to be used in vmaDefragmentationBegin() . None at the moment. Reserved for future use. More...
+ Flags to be passed as VmaDefragmentationInfo::flags . More...
typedef VkFlags VmaDefragmentationFlags
+typedef enum VmaDefragmentationMoveOperation VmaDefragmentationMoveOperation
+ Operation performed on single defragmentation move. More...
+
typedef enum VmaVirtualBlockCreateFlagBits VmaVirtualBlockCreateFlagBits
Flags to be passed as VmaVirtualBlockCreateInfo::flags . More...
@@ -224,19 +225,17 @@ Typedefs
typedef struct VmaAllocationInfo VmaAllocationInfo
Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo() . More...
-typedef struct VmaDefragmentationInfo2 VmaDefragmentationInfo2
- Parameters for defragmentation. More...
-
-typedef struct VmaDefragmentationPassMoveInfo VmaDefragmentationPassMoveInfo
-
-typedef struct VmaDefragmentationPassInfo VmaDefragmentationPassInfo
- Parameters for incremental defragmentation steps. More...
-
typedef struct VmaDefragmentationInfo VmaDefragmentationInfo
- Deprecated. Optional configuration parameters to be passed to function vmaDefragment() . More...
+ Parameters for defragmentation. More...
+typedef struct VmaDefragmentationMove VmaDefragmentationMove
+ Single move of an allocation to be done for defragmentation. More...
+
+typedef struct VmaDefragmentationPassMoveInfo VmaDefragmentationPassMoveInfo
+ Parameters for incremental defragmentation steps. More...
+
typedef struct VmaDefragmentationStats VmaDefragmentationStats
- Statistics returned by function vmaDefragment() . More...
+ Statistics returned for defragmentation process in function vmaEndDefragmentation() . More...
typedef struct VmaVirtualBlockCreateInfo VmaVirtualBlockCreateInfo
Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock() . More...
@@ -301,50 +300,55 @@ Enumerations
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT = 0x00001000
, VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = 0x00010000
, VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = 0x00020000
-, VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT
+, VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = 0x00040000
,
- VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT
+ VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT
+, VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT
, VMA_ALLOCATION_CREATE_STRATEGY_MASK
, VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
}
Flags to be passed as VmaAllocationCreateInfo::flags . More...
-enum VmaPoolCreateFlagBits {
- VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002
+enum VmaPoolCreateFlagBits { VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002
, VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004
-, VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT = 0x00000008
-, VMA_POOL_CREATE_TLSF_ALGORITHM_BIT = 0x00000010
-,
- VMA_POOL_CREATE_ALGORITHM_MASK
+, VMA_POOL_CREATE_ALGORITHM_MASK
, VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
-
}
Flags to be passed as VmaPoolCreateInfo::flags . More...
-enum VmaDefragmentationFlagBits { VMA_DEFRAGMENTATION_FLAG_INCREMENTAL = 0x1
-, VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
- }
- Flags to be used in vmaDefragmentationBegin() . None at the moment. Reserved for future use. More...
-
-enum VmaVirtualBlockCreateFlagBits {
- VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = 0x00000001
-, VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT = 0x00000002
-, VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT = 0x00000004
-, VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK
+enum VmaDefragmentationFlagBits {
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT = 0x1
+, VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT = 0x2
+, VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT = 0x4
+, VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = 0x8
,
- VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK
+, VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
}
+ Flags to be passed as VmaDefragmentationInfo::flags . More...
+
+enum VmaDefragmentationMoveOperation { VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY = 0
+, VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE = 1
+, VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY = 2
+ }
+ Operation performed on single defragmentation move. More...
+
+enum VmaVirtualBlockCreateFlagBits { VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = 0x00000001
+, VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK
+, VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+ }
Flags to be passed as VmaVirtualBlockCreateInfo::flags . More...
enum VmaVirtualAllocationCreateFlagBits {
VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT
, VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT
, VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT
-, VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK = VMA_ALLOCATION_CREATE_STRATEGY_MASK
+, VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_PACKED_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT
,
- VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+ VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK = VMA_ALLOCATION_CREATE_STRATEGY_MASK
+, VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
}
Flags to be passed as VmaVirtualAllocationCreateInfo::flags . More...
@@ -456,19 +460,18 @@ Functions
VkResult vmaCheckCorruption (VmaAllocator allocator, uint32_t memoryTypeBits)
Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions. More...
-VkResult vmaDefragmentationBegin (VmaAllocator allocator, const VmaDefragmentationInfo2 *pInfo, VmaDefragmentationStats *pStats, VmaDefragmentationContext *pContext)
- Begins defragmentation process. More...
-
-VkResult vmaDefragmentationEnd (VmaAllocator allocator, VmaDefragmentationContext context)
- Ends defragmentation process. More...
-
-VkResult vmaBeginDefragmentationPass (VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassInfo *pInfo)
-
-VkResult vmaEndDefragmentationPass (VmaAllocator allocator, VmaDefragmentationContext context)
-
-VkResult vmaDefragment (VmaAllocator allocator, const VmaAllocation *pAllocations, size_t allocationCount, VkBool32 *pAllocationsChanged, const VmaDefragmentationInfo *pDefragmentationInfo, VmaDefragmentationStats *pDefragmentationStats)
- Deprecated. Compacts memory by moving allocations. More...
-
+VkResult vmaBeginDefragmentation (VmaAllocator allocator, const VmaDefragmentationInfo *pInfo, VmaDefragmentationContext *pContext)
+ Begins defragmentation process. More...
+
+VkResult vmaEndDefragmentation (VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationStats *pStats)
+ Ends defragmentation process. More...
+
+VkResult vmaBeginDefragmentationPass (VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)
+ Starts single defragmentation pass. More...
+
+VkResult vmaEndDefragmentationPass (VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)
+ Ends single defragmentation pass. More...
+
VkResult vmaBindBufferMemory (VmaAllocator allocator, VmaAllocation allocation, VkBuffer buffer)
Binds buffer to allocation. More...
diff --git a/docs/html/vk_khr_dedicated_allocation.html b/docs/html/vk_khr_dedicated_allocation.html
index 9ae1d91..a9e58fb 100644
--- a/docs/html/vk_khr_dedicated_allocation.html
+++ b/docs/html/vk_khr_dedicated_allocation.html
@@ -83,7 +83,7 @@ $(function() {
VkResult vmaCreateAllocator(const VmaAllocatorCreateInfo *pCreateInfo, VmaAllocator *pAllocator)
Creates VmaAllocator object.
-@ VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT
Enables usage of VK_KHR_dedicated_allocation extension.
Definition: vk_mem_alloc.h:347
+@ VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT
Enables usage of VK_KHR_dedicated_allocation extension.
Definition: vk_mem_alloc.h:342
That is all. The extension will be automatically used whenever you create a buffer using vmaCreateBuffer() or image using vmaCreateImage() .
When using the extension together with Vulkan Validation Layer, you will receive warnings like this:
vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer.
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index c3daf3c..05415cc 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -60,12 +60,7 @@ License: MIT
- [Stack](@ref linear_algorithm_stack)
- [Double stack](@ref linear_algorithm_double_stack)
- [Ring buffer](@ref linear_algorithm_ring_buffer)
- - [Buddy allocation algorithm](@ref buddy_algorithm)
- \subpage defragmentation
- - [Defragmenting CPU memory](@ref defragmentation_cpu)
- - [Defragmenting GPU memory](@ref defragmentation_gpu)
- - [Additional notes](@ref defragmentation_additional_notes)
- - [Writing custom allocation algorithm](@ref defragmentation_custom_algorithm)
- \subpage statistics
- [Numeric statistics](@ref statistics_numeric_statistics)
- [JSON dump](@ref statistics_json_dump)
@@ -629,6 +624,11 @@ typedef enum VmaAllocationCreateFlagBits
to minimize allocation time, possibly at the expense of allocation quality.
*/
VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = 0x00020000,
+ /** Allocation strategy that chooses always the lowest offset in available space.
+ This is not the most efficient strategy but achieves highly packed data.
+ Used internally by defragmentation, not recomended in typical usage.
+ */
+ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = 0x00040000,
/** Alias to #VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT.
*/
VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
@@ -639,7 +639,8 @@ typedef enum VmaAllocationCreateFlagBits
*/
VMA_ALLOCATION_CREATE_STRATEGY_MASK =
VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT |
- VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
+ VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT |
+ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaAllocationCreateFlagBits;
@@ -680,48 +681,60 @@ typedef enum VmaPoolCreateFlagBits
*/
VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004,
- /** \brief 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 \ref buddy_algorithm.
- */
- VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT = 0x00000008,
-
- /** \brief Enables alternative, Two-Level Segregated Fit (TLSF) allocation algorithm in this pool.
-
- This algorithm is based on 2-level lists dividing address space into smaller
- chunks. The first level is aligned to power of two which serves as buckets for requested
- memory to fall into, and the second level is lineary subdivided into lists of free memory.
- This algorithm aims to achieve bounded response time even in the worst case scenario.
- Allocation time can be sometimes slightly longer than compared to other algorithms
- but in return the application can avoid stalls in case of fragmentation, giving
- predictable results, suitable for real-time use cases.
- */
- VMA_POOL_CREATE_TLSF_ALGORITHM_BIT = 0x00000010,
-
/** Bit mask to extract only `ALGORITHM` bits from entire set of flags.
*/
VMA_POOL_CREATE_ALGORITHM_MASK =
- VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT |
- VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT |
- VMA_POOL_CREATE_TLSF_ALGORITHM_BIT,
+ VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT,
VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaPoolCreateFlagBits;
/// Flags to be passed as VmaPoolCreateInfo::flags. See #VmaPoolCreateFlagBits.
typedef VkFlags VmaPoolCreateFlags;
-/// Flags to be used in vmaDefragmentationBegin(). None at the moment. Reserved for future use.
+/// Flags to be passed as VmaDefragmentationInfo::flags.
typedef enum VmaDefragmentationFlagBits
{
- VMA_DEFRAGMENTATION_FLAG_INCREMENTAL = 0x1,
+ /* \brief Use simple but fast algorithm for defragmentation.
+ May not achieve best results but will require least time to compute and least allocations to copy.
+ */
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT = 0x1,
+ /* \brief Default defragmentation algorithm, applied also when no `ALGORITHM` flag is specified.
+ Offers a balance between defragmentation quality and the amount of allocations and bytes that need to be moved.
+ */
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT = 0x2,
+ /* \brief Perform full defragmentation of memory.
+ Can result in notably more time to compute and allocations to copy, but will achieve best memory packing.
+ */
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT = 0x4,
+ /** \brief Use the most roboust algorithm at the cost of time to compute and number of copies to make.
+ Only available when bufferImageGranularity is greater than 1, since it aims to reduce
+ alignment issues between different types of resources.
+ Otherwise falls back to same behavior as #VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT.
+ */
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = 0x8,
+
+ /// A bit mask to extract only `ALGORITHM` bits from entire set of flags.
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK =
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT |
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT |
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT |
+ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT,
+
VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaDefragmentationFlagBits;
typedef VkFlags VmaDefragmentationFlags;
+/// Operation performed on single defragmentation move.
+typedef enum VmaDefragmentationMoveOperation
+{
+ /// Buffer/image has been recreated at `dstMemory` + `dstOffset`, data has been copied, old buffer/image has been destroyed. `srcAllocation` should be changed to point to the new place. This is the default value set by vmaBeginDefragmentationPass().
+ VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY = 0,
+ /// Set this value if you cannot move the allocation. New place reserved `dstMemory` + `dstOffset` will be freed. `srcAllocation` will remain unchanged.
+ VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE = 1,
+ /// Set this value if you decide to abandon the allocation and you destroyed the buffer/image. New place reserved `dstMemory` + `dstOffset` will be freed, along with `srcAllocation`.
+ VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY = 2,
+} VmaDefragmentationMoveOperation;
+
/** @} */
/**
@@ -745,34 +758,10 @@ typedef enum VmaVirtualBlockCreateFlagBits
*/
VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = 0x00000001,
- /** \brief Enables alternative, buddy allocation algorithm in this virtual block.
-
- 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 \ref buddy_algorithm.
- */
- VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT = 0x00000002,
-
- /** \brief Enables alternative, TLSF allocation algorithm in virtual block.
-
- This algorithm is based on 2-level lists dividing address space into smaller
- chunks. The first level is aligned to power of two which serves as buckets for requested
- memory to fall into, and the second level is lineary subdivided into lists of free memory.
- This algorithm aims to achieve bounded response time even in the worst case scenario.
- Allocation time can be sometimes slightly longer than compared to other algorithms
- but in return the application can avoid stalls in case of fragmentation, giving
- predictable results, suitable for real-time use cases.
- */
- VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT = 0x00000004,
-
/** \brief Bit mask to extract only `ALGORITHM` bits from entire set of flags.
*/
VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK =
- VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT |
- VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT |
- VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT,
+ VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT,
VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaVirtualBlockCreateFlagBits;
@@ -793,6 +782,10 @@ typedef enum VmaVirtualAllocationCreateFlagBits
/** \brief Allocation strategy that tries to minimize allocation time.
*/
VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
+ /** Allocation strategy that chooses always the lowest offset in available space.
+ This is not the most efficient strategy but achieves highly packed data.
+ */
+ VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_PACKED_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT ,
/** \brief A bit mask to extract only `STRATEGY` bits from entire set of flags.
These strategy flags are binary compatible with equivalent flags in #VmaAllocationCreateFlagBits.
@@ -866,10 +859,10 @@ returned structure VmaAllocationInfo.
VK_DEFINE_HANDLE(VmaAllocation)
/** \struct VmaDefragmentationContext
-\brief Represents Opaque object that represents started defragmentation process.
+\brief An opaque object that represents started defragmentation process.
-Fill structure #VmaDefragmentationInfo2 and call function vmaDefragmentationBegin() to create it.
-Call function vmaDefragmentationEnd() to destroy it.
+Fill structure #VmaDefragmentationInfo and call function vmaBeginDefragmentation() to create it.
+Call function vmaEndDefragmentation() to destroy it.
*/
VK_DEFINE_HANDLE(VmaDefragmentationContext)
@@ -1382,116 +1375,79 @@ typedef struct VmaAllocationInfo
/** \brief Parameters for defragmentation.
-To be used with function vmaDefragmentationBegin().
+To be used with function vmaBeginDefragmentation().
*/
-typedef struct VmaDefragmentationInfo2
+typedef struct VmaDefragmentationInfo
{
- /** \brief Reserved for future use. Should be 0.
- */
+ /// \brief Use combination of #VmaDefragmentationFlagBits.
VmaDefragmentationFlags flags;
- /** \brief Number of allocations in `pAllocations` array.
+ /** \brief Custom pool to be defragmented.
+
+ If null then default pools will undergo defragmentation process.
*/
- uint32_t allocationCount;
- /** \brief Pointer to array of allocations that can be defragmented.
+ VmaPool VMA_NULLABLE pool;
+ /** \brief Maximum numbers of bytes that can be copied during single pass, while moving allocations to different places.
- The array should have `allocationCount` elements.
- The array should not contain nulls.
- Elements in the array should be unique - same allocation cannot occur twice.
- All allocations not present in this array are considered non-moveable during this defragmentation.
+ `0` means no limit.
*/
- const VmaAllocation VMA_NOT_NULL* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations;
- /** \brief Optional, output. Pointer to array that will be filled with information whether the allocation at certain index has been changed during defragmentation.
+ VkDeviceSize maxBytesPerPass;
+ /** \brief Maximum number of allocations that can be moved during single pass to a different place.
- The array should have `allocationCount` elements.
- You can pass null if you are not interested in this information.
+ `0` means no limit.
*/
- VkBool32* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationsChanged;
- /** \brief Numer of pools in `pPools` array.
- */
- uint32_t poolCount;
- /** \brief Either null or pointer to array of pools to be defragmented.
+ uint32_t maxAllocationsPerPass;
+} VmaDefragmentationInfo;
- All the allocations in the specified pools can be moved during defragmentation
- and there is no way to check if they were really moved as in `pAllocationsChanged`,
- so you must query all the allocations in all these pools for new `VkDeviceMemory`
- and offset using vmaGetAllocationInfo() if you might need to recreate buffers
- and images bound to them.
-
- The array should have `poolCount` elements.
- The array should not contain nulls.
- Elements in the array should be unique - same pool cannot occur twice.
-
- Using this array is equivalent to specifying all allocations from the pools in `pAllocations`.
- It might be more efficient.
- */
- const VmaPool VMA_NOT_NULL* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(poolCount) pPools;
- /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places using transfers on CPU side, like `memcpy()`, `memmove()`.
-
- `VK_WHOLE_SIZE` means no limit.
- */
- VkDeviceSize maxCpuBytesToMove;
- /** \brief Maximum number of allocations that can be moved to a different place using transfers on CPU side, like `memcpy()`, `memmove()`.
-
- `UINT32_MAX` means no limit.
- */
- uint32_t maxCpuAllocationsToMove;
- /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places using transfers on GPU side, posted to `commandBuffer`.
-
- `VK_WHOLE_SIZE` means no limit.
- */
- VkDeviceSize maxGpuBytesToMove;
- /** \brief Maximum number of allocations that can be moved to a different place using transfers on GPU side, posted to `commandBuffer`.
-
- `UINT32_MAX` means no limit.
- */
- uint32_t maxGpuAllocationsToMove;
- /** \brief Optional. Command buffer where GPU copy commands will be posted.
-
- If not null, it must be a valid command buffer handle that supports Transfer queue type.
- It must be in the recording state and outside of a render pass instance.
- You need to submit it and make sure it finished execution before calling vmaDefragmentationEnd().
-
- Passing null means that only CPU defragmentation will be performed.
- */
- VkCommandBuffer VMA_NULLABLE commandBuffer;
-} VmaDefragmentationInfo2;
-
-typedef struct VmaDefragmentationPassMoveInfo
+/// Single move of an allocation to be done for defragmentation.
+typedef struct VmaDefragmentationMove
{
- VmaAllocation VMA_NOT_NULL allocation;
- VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory;
- VkDeviceSize offset;
-} VmaDefragmentationPassMoveInfo;
+ /// Operation to be performed on the allocation by vmaEndDefragmentationPass(). Default value is #VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY. You can modify it.
+ VmaDefragmentationMoveOperation operation;
+ /// Allocation that should be moved.
+ VmaAllocation VMA_NOT_NULL srcAllocation;
+ /// Destination memory block where the allocation should be moved.
+ VkDeviceMemory dstMemory;
+ /// Destination offset where the allocation should be moved.
+ VkDeviceSize dstOffset;
+ /// Internal data used by VMA. Do not use or modify!
+ void* VMA_NOT_NULL internalData;
+} VmaDefragmentationMove;
/** \brief Parameters for incremental defragmentation steps.
To be used with function vmaBeginDefragmentationPass().
*/
-typedef struct VmaDefragmentationPassInfo
+typedef struct VmaDefragmentationPassMoveInfo
{
+ /// Number of elements in the `pMoves` array.
uint32_t moveCount;
- VmaDefragmentationPassMoveInfo* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(moveCount) pMoves;
-} VmaDefragmentationPassInfo;
+ /** \brief Array of moves to be performed by the user in the current defragmentation pass.
+
+ Pointer to an array of `moveCount` elements, owned by VMA, created in vmaBeginDefragmentationPass(), destroyed in vmaEndDefragmentationPass().
-/** \brief Deprecated. Optional configuration parameters to be passed to function vmaDefragment().
+ For each element, you should:
+
+ 1. Create a new buffer/image in the place pointed by VmaDefragmentationMove::dstMemory + VmaDefragmentationMove::dstOffset.
+ 2. Copy data from the VmaDefragmentationMove::srcAllocation e.g. using `vkCmdCopyBuffer`, `vkCmdCopyImage`.
+ 3. Make sure these commands finished executing on the GPU.
+ 4. Destroy the old buffer/image.
+
+ Only then you can finish defragmentation pass by calling vmaEndDefragmentationPass().
+ After this call, the allocation will point to the new place in memory.
-\deprecated This is a part of the old interface. It is recommended to use structure #VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead.
-*/
-typedef struct VmaDefragmentationInfo
-{
- /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places.
+ Alternatively, if you cannot move specific allocation, you can set VmaDefragmentationMove::operation to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE.
- Default is `VK_WHOLE_SIZE`, which means no limit.
+ Alternatively, if you decide you want to completely remove the allocation:
+
+ 1. Destroy its buffer/image.
+ 2. Set VmaDefragmentationMove::operation to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY.
+
+ Then, after vmaEndDefragmentationPass() the allocation will be freed.
*/
- VkDeviceSize maxBytesToMove;
- /** \brief Maximum number of allocations that can be moved to different place.
+ VmaDefragmentationMove* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(moveCount) pMoves;
+} VmaDefragmentationPassMoveInfo;
- Default is `UINT32_MAX`, which means no limit.
- */
- uint32_t maxAllocationsToMove;
-} VmaDefragmentationInfo;
-
-/// Statistics returned by function vmaDefragment().
+/// Statistics returned for defragmentation process in function vmaEndDefragmentation().
typedef struct VmaDefragmentationStats
{
/// Total number of bytes that have been copied while moving allocations to different places.
@@ -2131,103 +2087,66 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(
\param allocator Allocator object.
\param pInfo Structure filled with parameters of defragmentation.
-\param[out] pStats Optional. Statistics of defragmentation. You can pass null if you are not interested in this information.
-\param[out] pContext Context object that must be passed to vmaDefragmentationEnd() to finish defragmentation.
-\return `VK_SUCCESS` and `*pContext == null` if defragmentation finished within this function call. `VK_NOT_READY` and `*pContext != null` if defragmentation has been started and you need to call vmaDefragmentationEnd() to finish it. Negative value in case of error.
+\param[out] pContext Context object that must be passed to vmaEndDefragmentation() to finish defragmentation.
-Use this function instead of old, deprecated vmaDefragment().
-
-Warning! Between the call to vmaDefragmentationBegin() and vmaDefragmentationEnd():
-
-- You should not use any of allocations passed as `pInfo->pAllocations` or
- any allocations that belong to pools passed as `pInfo->pPools`,
- including calling vmaGetAllocationInfo(), or access
- their data.
-- Some mutexes protecting internal data structures may be locked, so trying to
- make or free any allocations, bind buffers or images, map memory, or launch
- another simultaneous defragmentation in between may cause stall (when done on
- another thread) or deadlock (when done on the same thread), unless you are
- 100% sure that defragmented allocations are in different pools.
-- Information returned via `pStats` and `pInfo->pAllocationsChanged` are undefined.
- They become valid after call to vmaDefragmentationEnd().
-- If `pInfo->commandBuffer` is not null, you must submit that command buffer
- and make sure it finished execution before calling vmaDefragmentationEnd().
-
-For more information and important limitations regarding defragmentation, see documentation chapter:
+For more information about defragmentation, see documentation chapter:
[Defragmentation](@ref defragmentation).
*/
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationBegin(
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentation(
VmaAllocator VMA_NOT_NULL allocator,
- const VmaDefragmentationInfo2* VMA_NOT_NULL pInfo,
- VmaDefragmentationStats* VMA_NULLABLE pStats,
+ const VmaDefragmentationInfo* VMA_NOT_NULL pInfo,
VmaDefragmentationContext VMA_NULLABLE* VMA_NOT_NULL pContext);
/** \brief Ends defragmentation process.
-Use this function to finish defragmentation started by vmaDefragmentationBegin().
-It is safe to pass `context == null`. The function then does nothing.
-*/
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationEnd(
- VmaAllocator VMA_NOT_NULL allocator,
- VmaDefragmentationContext VMA_NULLABLE context);
+\param allocator Allocator object.
+\param context Context object that has been created by vmaBeginDefragmentation().
+\param[out] pStats Optional stats for the defragmentation. Can be null.
+Use this function to finish defragmentation started by vmaBeginDefragmentation().
+*/
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentation(
+ VmaAllocator VMA_NOT_NULL allocator,
+ VmaDefragmentationContext VMA_NOT_NULL context,
+ VmaDefragmentationStats* VMA_NULLABLE pStats);
+
+/** \brief Starts single defragmentation pass.
+
+\param allocator Allocator object.
+\param context Context object that has been created by vmaBeginDefragmentation().
+\param[out] pPassInfo Computed informations for current pass.
+\returns
+- `VK_SUCCESS` if no more moves are possible. Then you can omit call to vmaEndDefragmentationPass() and simply end whole defragmentation.
+- `VK_INCOMPLETE` if there are pending moves returned in `pPassInfo`. You need to perform them, call vmaEndDefragmentationPass(),
+ and then preferably try another pass with vmaBeginDefragmentationPass().
+*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass(
VmaAllocator VMA_NOT_NULL allocator,
- VmaDefragmentationContext VMA_NULLABLE context,
- VmaDefragmentationPassInfo* VMA_NOT_NULL pInfo);
+ VmaDefragmentationContext VMA_NOT_NULL context,
+ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo);
+/** \brief Ends single defragmentation pass.
+
+\param allocator Allocator object.
+\param context Context object that has been created by vmaBeginDefragmentation().
+\param pPassInfo Computed informations for current pass filled by vmaBeginDefragmentationPass() and possibly modified by you.
+
+Returns `VK_SUCCESS` if no more moves are possible or `VK_INCOMPLETE` if more defragmentations are possible.
+
+Ends incremental defragmentation pass and commits all defragmentation moves from `pPassInfo`.
+After this call:
+
+- Allocations at `pPassInfo[i].srcAllocation` that had `pPassInfo[i].operation ==` #VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY
+ (which is the default) will be pointing to the new destination place.
+- Allocation at `pPassInfo[i].srcAllocation` that had `pPassInfo[i].operation ==` #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY
+ will be freed.
+
+If no more moves are possible you can end whole defragmentation.
+*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass(
VmaAllocator VMA_NOT_NULL allocator,
- VmaDefragmentationContext VMA_NULLABLE context);
-
-/** \brief Deprecated. Compacts memory by moving allocations.
-
-\param allocator
-\param pAllocations Array of allocations that can be moved during this compation.
-\param allocationCount Number of elements in pAllocations and pAllocationsChanged arrays.
-\param[out] pAllocationsChanged Array of boolean values that will indicate whether matching allocation in pAllocations array has been moved. This parameter is optional. Pass null if you don't need this information.
-\param pDefragmentationInfo Configuration parameters. Optional - pass null to use default values.
-\param[out] pDefragmentationStats Statistics returned by the function. Optional - pass null if you don't need this information.
-\return `VK_SUCCESS` if completed, negative error code in case of error.
-
-\deprecated This is a part of the old interface. It is recommended to use structure #VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead.
-
-This function works by moving allocations to different places (different
-`VkDeviceMemory` objects and/or different offsets) in order to optimize memory
-usage. Only allocations that are in `pAllocations` array can be moved. All other
-allocations are considered nonmovable in this call. Basic rules:
-
-- Only allocations made in memory types that have
- `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` and `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT`
- flags can be compacted. You may pass other allocations but it makes no sense -
- these will never be moved.
-- Custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT or
- #VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT flag are not defragmented. Allocations
- passed to this function that come from such pools are ignored.
-- Allocations created with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT or
- created as dedicated allocations for any other reason are also ignored.
-- Both allocations made with or without #VMA_ALLOCATION_CREATE_MAPPED_BIT
- flag can be compacted. If not persistently mapped, memory will be mapped
- temporarily inside this function if needed.
-- You must not pass same #VmaAllocation object multiple times in `pAllocations` array.
-
-The function also frees empty `VkDeviceMemory` blocks.
-
-Warning: This function may be time-consuming, so you shouldn't call it too often
-(like after every resource creation/destruction).
-You can call it on special occasions (like when reloading a game level or
-when you just destroyed a lot of objects). Calling it every frame may be OK, but
-you should measure that on your platform.
-
-For more information, see [Defragmentation](@ref defragmentation) chapter.
-*/
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragment(
- VmaAllocator VMA_NOT_NULL allocator,
- const VmaAllocation VMA_NOT_NULL* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations,
- size_t allocationCount,
- VkBool32* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationsChanged,
- const VmaDefragmentationInfo* VMA_NULLABLE pDefragmentationInfo,
- VmaDefragmentationStats* VMA_NULLABLE pDefragmentationStats);
+ VmaDefragmentationContext VMA_NOT_NULL context,
+ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo);
/** \brief Binds buffer to allocation.
@@ -3140,23 +3059,13 @@ typedef VmaList> VmaSuballoc
struct VmaAllocationRequest;
class VmaBlockMetadata;
-class VmaBlockMetadata_Generic;
class VmaBlockMetadata_Linear;
-class VmaBlockMetadata_Buddy;
class VmaBlockMetadata_TLSF;
class VmaBlockVector;
-struct VmaDefragmentationMove;
-class VmaDefragmentationAlgorithm;
-class VmaDefragmentationAlgorithm_Generic;
-class VmaDefragmentationAlgorithm_Fast;
-
struct VmaPoolListItemTraits;
-struct VmaBlockDefragmentationContext;
-class VmaBlockVectorDefragmentationContext;
-
struct VmaCurrentBudgetData;
class VmaAllocationObjectAllocator;
@@ -3164,7 +3073,7 @@ class VmaAllocationObjectAllocator;
#endif // _VMA_FORWARD_DECLARATIONS
-#ifndef _VMA_FUNCTIONS
+#ifndef _VMA_FUNCTIONS
// Returns number of bits set to 1 in (v).
static inline uint32_t VmaCountBitsSet(uint32_t v)
{
@@ -3375,12 +3284,8 @@ static const char* VmaAlgorithmToStr(uint32_t algorithm)
{
case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT:
return "Linear";
- case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT:
- return "Buddy";
- case VMA_POOL_CREATE_TLSF_ALGORITHM_BIT:
- return "TLSF";
case 0:
- return "Default";
+ return "TLSF";
default:
VMA_ASSERT(0);
return "";
@@ -4837,6 +4742,7 @@ public:
class iterator
{
+ friend class const_iterator;
friend class VmaList;
public:
iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {}
@@ -4862,6 +4768,7 @@ public:
};
class reverse_iterator
{
+ friend class const_reverse_iterator;
friend class VmaList;
public:
reverse_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {}
@@ -4893,6 +4800,8 @@ public:
const_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
const_iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
+ iterator drop_const() { return { const_cast*>(m_pList), const_cast*>(m_pItem) }; }
+
const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; }
const T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; }
@@ -4919,6 +4828,8 @@ public:
const_reverse_iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
const_reverse_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
+ reverse_iterator drop_const() { return { const_cast*>(m_pList), const_cast*>(m_pItem) }; }
+
const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; }
const T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; }
@@ -4955,8 +4866,8 @@ public:
reverse_iterator rbegin() { return reverse_iterator(&m_RawList, m_RawList.Back()); }
reverse_iterator rend() { return reverse_iterator(&m_RawList, VMA_NULL); }
- const_reverse_iterator crbegin() { return const_reverse_iterator(&m_RawList, m_RawList.Back()); }
- const_reverse_iterator crend() { return const_reverse_iterator(&m_RawList, VMA_NULL); }
+ const_reverse_iterator crbegin() const { return const_reverse_iterator(&m_RawList, m_RawList.Back()); }
+ const_reverse_iterator crend() const { return const_reverse_iterator(&m_RawList, VMA_NULL); }
const_reverse_iterator rbegin() const { return crbegin(); }
const_reverse_iterator rend() const { return crend(); }
@@ -5325,13 +5236,14 @@ public:
iterator begin() { return m_Vector.begin(); }
iterator end() { return m_Vector.end(); }
+ size_t size() { return m_Vector.size(); }
void insert(const PairType& pair);
iterator find(const KeyT& key);
void erase(iterator it);
private:
- VmaVector< PairType, VmaStlAllocator > m_Vector;
+ VmaVector< PairType, VmaStlAllocator> m_Vector;
};
#ifndef _VMA_MAP_FUNCTIONS
@@ -6030,8 +5942,7 @@ public:
bool IsMappingAllowed() const { return (m_Flags & FLAG_MAPPING_ALLOWED) != 0; }
void SetUserData(VmaAllocator hAllocator, void* pUserData);
- void ChangeBlockAllocation(VmaAllocator hAllocator, VmaDeviceMemoryBlock* block, VmaAllocHandle allocHandle);
- void ChangeAllocHandle(VmaAllocHandle newAllocHandle);
+ void SwapBlockAllocation(VmaAllocation allocation);
VmaAllocHandle GetAllocHandle() const;
VkDeviceSize GetOffset() const;
VmaPool GetParentPool() const;
@@ -6329,6 +6240,10 @@ public:
virtual bool IsEmpty() const = 0;
virtual void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) = 0;
virtual VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const = 0;
+ virtual void* GetAllocationUserData(VmaAllocHandle allocHandle) const = 0;
+
+ virtual VmaAllocHandle GetAllocationListBegin() const = 0;
+ virtual VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const = 0;
// Shouldn't modify blockCount.
virtual void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const = 0;
@@ -6772,6 +6687,7 @@ void VmaBlockBufferImageGranularity::AllocPage(RegionInfo& page, uint8_t allocTy
#endif // _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY_FUNCTIONS
#endif // _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY
+#if 0
#ifndef _VMA_BLOCK_METADATA_GENERIC
class VmaBlockMetadata_Generic : public VmaBlockMetadata
{
@@ -6815,15 +6731,13 @@ public:
void* userData) override;
void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
+ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
+ VmaAllocHandle GetAllocationListBegin() const override;
+ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
void Clear() override;
void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
void DebugLogAllAllocations() const override;
- // For defragmentation
- bool IsBufferImageGranularityConflictPossible(
- VkDeviceSize bufferImageGranularity,
- VmaSuballocationType& inOutPrevSuballocType) const;
-
private:
uint32_t m_FreeCount;
VkDeviceSize m_SumFreeSize;
@@ -6833,7 +6747,7 @@ private:
VkDeviceSize AlignAllocationSize(VkDeviceSize size) const { return IsVirtual() ? size : VmaAlignUp(size, (VkDeviceSize)16); }
- VmaSuballocationList::iterator FindAtOffset(VkDeviceSize offset);
+ VmaSuballocationList::iterator FindAtOffset(VkDeviceSize offset) const;
bool ValidateFreeSuballocationList() const;
// Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem.
@@ -7091,7 +7005,7 @@ bool VmaBlockMetadata_Generic::CreateAllocationRequest(
}
else
{
- VMA_ASSERT(strategy == VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT);
+ VMA_ASSERT(strategy & (VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT | VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT ));
// Search staring from biggest suballocations.
for (size_t index = freeSuballocCount; index--; )
{
@@ -7202,6 +7116,37 @@ void VmaBlockMetadata_Generic::GetAllocationInfo(VmaAllocHandle allocHandle, Vma
outInfo.pUserData = suballoc.userData;
}
+void* VmaBlockMetadata_Generic::GetAllocationUserData(VmaAllocHandle allocHandle) const
+{
+ return FindAtOffset((VkDeviceSize)allocHandle - 1)->userData;
+}
+
+VmaAllocHandle VmaBlockMetadata_Generic::GetAllocationListBegin() const
+{
+ if (IsEmpty())
+ return VK_NULL_HANDLE;
+
+ for (const auto& suballoc : m_Suballocations)
+ {
+ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
+ return (VmaAllocHandle)(suballoc.offset + 1);
+ }
+ VMA_ASSERT(false && "Should contain at least 1 allocation!");
+ return VK_NULL_HANDLE;
+}
+
+VmaAllocHandle VmaBlockMetadata_Generic::GetNextAllocation(VmaAllocHandle prevAlloc) const
+{
+ VmaSuballocationList::const_iterator prev = FindAtOffset((VkDeviceSize)prevAlloc - 1);
+
+ for (VmaSuballocationList::const_iterator it = ++prev; it != m_Suballocations.end(); ++it)
+ {
+ if (it->type != VMA_SUBALLOCATION_TYPE_FREE)
+ return (VmaAllocHandle)(it->offset + 1);
+ }
+ return VK_NULL_HANDLE;
+}
+
void VmaBlockMetadata_Generic::Clear()
{
const VkDeviceSize size = GetSize();
@@ -7236,15 +7181,15 @@ void VmaBlockMetadata_Generic::DebugLogAllAllocations() const
}
}
-VmaSuballocationList::iterator VmaBlockMetadata_Generic::FindAtOffset(VkDeviceSize offset)
+VmaSuballocationList::iterator VmaBlockMetadata_Generic::FindAtOffset(VkDeviceSize offset) const
{
VMA_HEAVY_ASSERT(!m_Suballocations.empty());
const VkDeviceSize last = m_Suballocations.rbegin()->offset;
if (last == offset)
- return m_Suballocations.rbegin();
+ return m_Suballocations.rbegin().drop_const();
const VkDeviceSize first = m_Suballocations.begin()->offset;
if (first == offset)
- return m_Suballocations.begin();
+ return m_Suballocations.begin().drop_const();
const size_t suballocCount = m_Suballocations.size();
const VkDeviceSize step = (last - first + m_Suballocations.begin()->size) / suballocCount;
@@ -7254,12 +7199,11 @@ VmaSuballocationList::iterator VmaBlockMetadata_Generic::FindAtOffset(VkDeviceSi
suballocItem != end;
++suballocItem)
{
- VmaSuballocation& suballoc = *suballocItem;
- if (suballoc.offset == offset)
- return suballocItem;
+ if (suballocItem->offset == offset)
+ return suballocItem.drop_const();
}
VMA_ASSERT(false && "Not found!");
- return m_Suballocations.end();
+ return m_Suballocations.end().drop_const();
};
// If requested offset is closer to the end of range, search from the end
if (offset - first > suballocCount * step / 2)
@@ -7503,37 +7447,9 @@ void VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList:
//VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());
}
-
-bool VmaBlockMetadata_Generic::IsBufferImageGranularityConflictPossible(
- VkDeviceSize bufferImageGranularity,
- VmaSuballocationType& inOutPrevSuballocType) const
-{
- if (bufferImageGranularity == 1 || IsEmpty() || IsVirtual())
- {
- return false;
- }
-
- VkDeviceSize minAlignment = VK_WHOLE_SIZE;
- bool typeConflictFound = false;
- for (const auto& suballoc : m_Suballocations)
- {
- const VmaSuballocationType suballocType = suballoc.type;
- if (suballocType != VMA_SUBALLOCATION_TYPE_FREE)
- {
- VmaAllocation const alloc = (VmaAllocation)suballoc.userData;
- minAlignment = VMA_MIN(minAlignment, alloc->GetAlignment());
- if (VmaIsBufferImageGranularityConflict(inOutPrevSuballocType, suballocType))
- {
- typeConflictFound = true;
- }
- inOutPrevSuballocType = suballocType;
- }
- }
-
- return typeConflictFound || minAlignment >= bufferImageGranularity;
-}
#endif // _VMA_BLOCK_METADATA_GENERIC_FUNCTIONS
#endif // _VMA_BLOCK_METADATA_GENERIC
+#endif // #if 0
#ifndef _VMA_BLOCK_METADATA_LINEAR
/*
@@ -7654,6 +7570,9 @@ public:
void Free(VmaAllocHandle allocHandle) override;
void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
+ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
+ VmaAllocHandle GetAllocationListBegin() const override;
+ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
void Clear() override;
void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
void DebugLogAllAllocations() const override;
@@ -7700,7 +7619,7 @@ private:
const SuballocationVectorType& AccessSuballocations1st() const { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }
const SuballocationVectorType& AccessSuballocations2nd() const { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }
- VmaSuballocation& FindSuballocation(VkDeviceSize offset);
+ VmaSuballocation& FindSuballocation(VkDeviceSize offset) const;
bool ShouldCompact1st() const;
void CleanupAfterFree();
@@ -8744,6 +8663,25 @@ void VmaBlockMetadata_Linear::GetAllocationInfo(VmaAllocHandle allocHandle, VmaV
outInfo.pUserData = suballoc.userData;
}
+void* VmaBlockMetadata_Linear::GetAllocationUserData(VmaAllocHandle allocHandle) const
+{
+ return FindSuballocation((VkDeviceSize)allocHandle - 1).userData;
+}
+
+VmaAllocHandle VmaBlockMetadata_Linear::GetAllocationListBegin() const
+{
+ // Function only used for defragmentation, which is disabled for this algorithm
+ VMA_ASSERT(0);
+ return VK_NULL_HANDLE;
+}
+
+VmaAllocHandle VmaBlockMetadata_Linear::GetNextAllocation(VmaAllocHandle prevAlloc) const
+{
+ // Function only used for defragmentation, which is disabled for this algorithm
+ VMA_ASSERT(0);
+ return VK_NULL_HANDLE;
+}
+
void VmaBlockMetadata_Linear::Clear()
{
m_SumFreeSize = GetSize();
@@ -8775,10 +8713,10 @@ void VmaBlockMetadata_Linear::DebugLogAllAllocations() const
DebugLogAllocation(it->offset, it->size, it->userData);
}
-VmaSuballocation& VmaBlockMetadata_Linear::FindSuballocation(VkDeviceSize offset)
+VmaSuballocation& VmaBlockMetadata_Linear::FindSuballocation(VkDeviceSize offset) const
{
- SuballocationVectorType& suballocations1st = AccessSuballocations1st();
- SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
+ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
+ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
VmaSuballocation refSuballoc;
refSuballoc.offset = offset;
@@ -8786,31 +8724,31 @@ VmaSuballocation& VmaBlockMetadata_Linear::FindSuballocation(VkDeviceSize offset
// Item from the 1st vector.
{
- const SuballocationVectorType::iterator it = VmaBinaryFindSorted(
+ SuballocationVectorType::const_iterator it = VmaBinaryFindSorted(
suballocations1st.begin() + m_1stNullItemsBeginCount,
suballocations1st.end(),
refSuballoc,
VmaSuballocationOffsetLess());
if (it != suballocations1st.end())
{
- return *it;
+ return const_cast(*it);
}
}
if (m_2ndVectorMode != SECOND_VECTOR_EMPTY)
{
// Rest of members stays uninitialized intentionally for better performance.
- const SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?
+ SuballocationVectorType::const_iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?
VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) :
VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater());
if (it != suballocations2nd.end())
{
- return *it;
+ return const_cast(*it);
}
}
VMA_ASSERT(0 && "Allocation not found in linear allocator!");
- return suballocations1st.back(); // Should never occur.
+ return const_cast(suballocations1st.back()); // Should never occur.
}
bool VmaBlockMetadata_Linear::ShouldCompact1st() const
@@ -9221,6 +9159,7 @@ bool VmaBlockMetadata_Linear::CreateAllocationRequest_UpperAddress(
#endif // _VMA_BLOCK_METADATA_LINEAR_FUNCTIONS
#endif // _VMA_BLOCK_METADATA_LINEAR
+#if 0
#ifndef _VMA_BLOCK_METADATA_BUDDY
/*
- GetSize() is the original size of allocated memory block.
@@ -9273,6 +9212,9 @@ public:
void Free(VmaAllocHandle allocHandle) override;
void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
+ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
+ VmaAllocHandle GetAllocationListBegin() const override;
+ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
void Clear() override;
void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
@@ -9346,7 +9288,7 @@ private:
}
return VmaNextPow2(size);
}
- Node* FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel);
+ Node* FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel) const;
void DeleteNodeChildren(Node* node);
bool ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const;
uint32_t AllocSizeToLevel(VkDeviceSize allocSize) const;
@@ -9634,6 +9576,25 @@ void VmaBlockMetadata_Buddy::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVi
outInfo.pUserData = node->allocation.userData;
}
+void* VmaBlockMetadata_Buddy::GetAllocationUserData(VmaAllocHandle allocHandle) const
+{
+ uint32_t level = 0;
+ const Node* const node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level);
+ return node->allocation.userData;
+}
+
+VmaAllocHandle VmaBlockMetadata_Buddy::GetAllocationListBegin() const
+{
+ // Function only used for defragmentation, which is disabled for this algorithm
+ return VK_NULL_HANDLE;
+}
+
+VmaAllocHandle VmaBlockMetadata_Buddy::GetNextAllocation(VmaAllocHandle prevAlloc) const
+{
+ // Function only used for defragmentation, which is disabled for this algorithm
+ return VK_NULL_HANDLE;
+}
+
void VmaBlockMetadata_Buddy::DeleteNodeChildren(Node* node)
{
if (node->type == Node::TYPE_SPLIT)
@@ -9662,7 +9623,7 @@ void VmaBlockMetadata_Buddy::SetAllocationUserData(VmaAllocHandle allocHandle, v
node->allocation.userData = userData;
}
-VmaBlockMetadata_Buddy::Node* VmaBlockMetadata_Buddy::FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel)
+VmaBlockMetadata_Buddy::Node* VmaBlockMetadata_Buddy::FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel) const
{
Node* node = m_Root;
VkDeviceSize nodeOffset = 0;
@@ -9859,6 +9820,8 @@ void VmaBlockMetadata_Buddy::DebugLogAllAllocationNode(Node* node, uint32_t leve
{
switch (node->type)
{
+ case Node::TYPE_FREE:
+ break;
case Node::TYPE_ALLOCATION:
DebugLogAllocation(node->offset, LevelToNodeSize(level), node->allocation.userData);
break;
@@ -9901,6 +9864,7 @@ void VmaBlockMetadata_Buddy::PrintDetailedMapNode(class VmaJsonWriter& json, con
#endif // VMA_STATS_STRING_ENABLED
#endif // _VMA_BLOCK_METADATA_BUDDY_FUNCTIONS
#endif // _VMA_BLOCK_METADATA_BUDDY
+#endif // #if 0
#ifndef _VMA_BLOCK_METADATA_TLSF
// To not search current larger region if first allocation won't succeed and skip to smaller range
@@ -9946,6 +9910,9 @@ public:
void Free(VmaAllocHandle allocHandle) override;
void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
+ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
+ VmaAllocHandle GetAllocationListBegin() const override;
+ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
void Clear() override;
void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
void DebugLogAllAllocations() const override;
@@ -10329,6 +10296,33 @@ bool VmaBlockMetadata_TLSF::CreateAllocationRequest(
nextListBlock = nextListBlock->NextFree();
}
}
+ else if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT )
+ {
+ // Perform search from the start
+ VmaStlAllocator allocator(GetAllocationCallbacks());
+ VmaVector> blockList(m_BlocksFreeCount, allocator);
+
+ size_t i = m_BlocksFreeCount;
+ for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical)
+ {
+ if (block->IsFree() && block->size >= allocSize)
+ blockList[--i] = block;
+ }
+
+ for (; i < m_BlocksFreeCount; ++i)
+ {
+ Block& block = *blockList[i];
+ if (CheckBlock(block, GetListIndex(block.size), allocSize, allocAlignment, allocType, pAllocationRequest))
+ return true;
+ }
+
+ // If failed check null block
+ if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest))
+ return true;
+
+ // Whole range searched, no more memory
+ return false;
+ }
else
{
// Check larger bucket
@@ -10561,6 +10555,40 @@ void VmaBlockMetadata_TLSF::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVir
outInfo.pUserData = block->UserData();
}
+void* VmaBlockMetadata_TLSF::GetAllocationUserData(VmaAllocHandle allocHandle) const
+{
+ Block* block = (Block*)allocHandle;
+ VMA_ASSERT(!block->IsFree() && "Cannot get user data for free block!");
+ return block->UserData();
+}
+
+VmaAllocHandle VmaBlockMetadata_TLSF::GetAllocationListBegin() const
+{
+ if (m_AllocCount == 0)
+ return VK_NULL_HANDLE;
+
+ for (Block* block = m_NullBlock->prevPhysical; block; block = block->prevPhysical)
+ {
+ if (!block->IsFree())
+ return (VmaAllocHandle)block;
+ }
+ VMA_ASSERT(false && "If m_AllocCount > 0 then should find any allocation!");
+ return VK_NULL_HANDLE;
+}
+
+VmaAllocHandle VmaBlockMetadata_TLSF::GetNextAllocation(VmaAllocHandle prevAlloc) const
+{
+ Block* startBlock = (Block*)prevAlloc;
+ VMA_ASSERT(!startBlock->IsFree() && "Incorrect block!");
+
+ for (Block* block = startBlock->prevPhysical; block; block = block->prevPhysical)
+ {
+ if (!block->IsFree())
+ return (VmaAllocHandle)block;
+ }
+ return VK_NULL_HANDLE;
+}
+
void VmaBlockMetadata_TLSF::Clear()
{
m_AllocCount = 0;
@@ -10773,7 +10801,7 @@ Synchronized internally with a mutex.
*/
class VmaBlockVector
{
- friend class VmaDefragmentationAlgorithm_Generic;
+ friend struct VmaDefragmentationContext_T;
VMA_CLASS_NO_COPY(VmaBlockVector)
public:
VmaBlockVector(
@@ -10800,7 +10828,11 @@ public:
uint32_t GetAlgorithm() const { return m_Algorithm; }
bool HasExplicitBlockSize() const { return m_ExplicitBlockSize; }
float GetPriority() const { return m_Priority; }
- void* GetAllocationNextPtr() const { return m_pMemoryAllocateNext; }
+ void* const GetAllocationNextPtr() const { return m_pMemoryAllocateNext; }
+ // To be used only while the m_Mutex is locked. Used during defragmentation.
+ size_t GetBlockCount() const { return m_Blocks.size(); }
+ // To be used only while the m_Mutex is locked. Used during defragmentation.
+ VmaDeviceMemoryBlock* GetBlock(size_t index) const { return m_Blocks[index]; }
VkResult CreateMinBlocks();
void AddStatistics(VmaStatistics& inoutStats);
@@ -10816,7 +10848,7 @@ public:
size_t allocationCount,
VmaAllocation* pAllocations);
- void Free(const VmaAllocation hAllocation);
+ void Free(const VmaAllocation hAllocation, bool incrementalSort = true);
#if VMA_STATS_STRING_ENABLED
void PrintDetailedMap(class VmaJsonWriter& json);
@@ -10824,34 +10856,6 @@ public:
VkResult CheckCorruption();
- // Saves results in pCtx->res.
- void Defragment(
- class VmaBlockVectorDefragmentationContext* pCtx,
- VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags,
- VkDeviceSize& maxCpuBytesToMove, uint32_t& maxCpuAllocationsToMove,
- VkDeviceSize& maxGpuBytesToMove, uint32_t& maxGpuAllocationsToMove,
- VkCommandBuffer commandBuffer);
- void DefragmentationEnd(
- class VmaBlockVectorDefragmentationContext* pCtx,
- uint32_t flags,
- VmaDefragmentationStats* pStats);
-
- uint32_t ProcessDefragmentations(
- class VmaBlockVectorDefragmentationContext* pCtx,
- VmaDefragmentationPassMoveInfo* pMove, uint32_t maxMoves);
-
- void CommitDefragmentations(
- class VmaBlockVectorDefragmentationContext* pCtx,
- VmaDefragmentationStats* pStats);
-
- ////////////////////////////////////////////////////////////////////////////////
- // To be used only while the m_Mutex is locked. Used during defragmentation.
-
- size_t GetBlockCount() const { return m_Blocks.size(); }
- VmaDeviceMemoryBlock* GetBlock(size_t index) const { return m_Blocks[index]; }
- size_t CalcAllocationCount() const;
- bool IsBufferImageGranularityConflictPossible() const;
-
private:
const VmaAllocator m_hAllocator;
const VmaPool m_hParentPool;
@@ -10877,6 +10881,7 @@ private:
// Performs single step in sorting m_Blocks. They may not be fully sorted
// after this call.
void IncrementallySortBlocks();
+ void SortByFreeSize();
VkResult AllocatePage(
VkDeviceSize size,
@@ -10895,327 +10900,90 @@ private:
uint32_t strategy,
VmaAllocation* pAllocation);
- VkResult CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex);
- // Saves result to pCtx->res.
- void ApplyDefragmentationMovesCpu(
- VmaBlockVectorDefragmentationContext* pDefragCtx,
- const VmaVector>& moves);
- // Saves result to pCtx->res.
- void ApplyDefragmentationMovesGpu(
- VmaBlockVectorDefragmentationContext* pDefragCtx,
- VmaVector>& moves,
- VkCommandBuffer commandBuffer);
+ VkResult CommitAllocationRequest(
+ VmaAllocationRequest& allocRequest,
+ VmaDeviceMemoryBlock* pBlock,
+ VkDeviceSize alignment,
+ VmaAllocationCreateFlags allocFlags,
+ void* pUserData,
+ VmaSuballocationType suballocType,
+ VmaAllocation* pAllocation);
- /*
- Used during defragmentation. pDefragmentationStats is optional. It is in/out
- - updated with new data.
- */
- void FreeEmptyBlocks(VmaDefragmentationStats* pDefragmentationStats);
- bool HasEmptyBlock() const;
+ VkResult CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex);
+ bool HasEmptyBlock();
};
#endif // _VMA_BLOCK_VECTOR
-#ifndef _VMA_DEFRAGMENTATION_ALGORITHM
-struct VmaDefragmentationMove
-{
- size_t srcBlockIndex;
- size_t dstBlockIndex;
- VkDeviceSize srcOffset;
- VkDeviceSize dstOffset;
- VmaAllocHandle dstHandle;
- VkDeviceSize size;
- VmaAllocation hAllocation;
- VmaDeviceMemoryBlock* pSrcBlock;
- VmaDeviceMemoryBlock* pDstBlock;
-};
-
-/*
-Performs defragmentation:
-
-- Updates `pBlockVector->m_pMetadata`.
-- Updates allocations by calling ChangeBlockAllocation() or ChangeOffset().
-- Does not move actual data, only returns requested moves as `moves`.
-*/
-class VmaDefragmentationAlgorithm
-{
- VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm)
-public:
- VmaDefragmentationAlgorithm(
- VmaAllocator hAllocator,
- VmaBlockVector* pBlockVector)
- : m_hAllocator(hAllocator),
- m_pBlockVector(pBlockVector) {}
- virtual ~VmaDefragmentationAlgorithm() = default;
-
- virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) = 0;
- virtual void AddAll() = 0;
-
- virtual VkResult Defragment(
- VmaVector>& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- VmaDefragmentationFlags flags) = 0;
-
- virtual VkDeviceSize GetBytesMoved() const = 0;
- virtual uint32_t GetAllocationsMoved() const = 0;
-
-protected:
- struct AllocationInfo
- {
- VmaAllocation m_hAllocation;
- VkBool32* m_pChanged;
-
- AllocationInfo() : m_hAllocation(VK_NULL_HANDLE), m_pChanged(VMA_NULL) {}
- AllocationInfo(VmaAllocation hAlloc, VkBool32* pChanged) : m_hAllocation(hAlloc), m_pChanged(pChanged) {}
- };
-
- VmaAllocator const m_hAllocator;
- VmaBlockVector* const m_pBlockVector;
-};
-
-#endif // _VMA_DEFRAGMENTATION_ALGORITHM
-
-#ifndef _VMA_DEFRAGMENTATION_ALGORITHM_GENERIC
-class VmaDefragmentationAlgorithm_Generic : public VmaDefragmentationAlgorithm
-{
- VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm_Generic)
-public:
- VmaDefragmentationAlgorithm_Generic(
- VmaAllocator hAllocator,
- VmaBlockVector* pBlockVector,
- bool overlappingMoveSupported);
- virtual ~VmaDefragmentationAlgorithm_Generic();
-
- virtual void AddAll() { m_AllAllocations = true; }
- virtual VkDeviceSize GetBytesMoved() const { return m_BytesMoved; }
- virtual uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; }
-
- virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged);
- virtual VkResult Defragment(
- VmaVector>& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- VmaDefragmentationFlags flags);
-
-private:
- struct AllocationInfoSizeGreater
- {
- bool operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const;
- };
- struct AllocationInfoOffsetGreater
- {
- bool operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const;
- };
- struct BlockInfo
- {
- size_t m_OriginalBlockIndex;
- VmaDeviceMemoryBlock* m_pBlock;
- bool m_HasNonMovableAllocations;
- VmaVector> m_Allocations;
-
- BlockInfo(const VkAllocationCallbacks* pAllocationCallbacks);
-
- void CalcHasNonMovableAllocations();
- void SortAllocationsBySizeDescending();
- void SortAllocationsByOffsetDescending();
- };
- struct BlockPointerLess
- {
- bool operator()(const BlockInfo* pLhsBlockInfo, const VmaDeviceMemoryBlock* pRhsBlock) const;
- bool operator()(const BlockInfo* pLhsBlockInfo, const BlockInfo* pRhsBlockInfo) const;
- };
- // 1. Blocks with some non-movable allocations go first.
- // 2. Blocks with smaller sumFreeSize go first.
- struct BlockInfoCompareMoveDestination
- {
- bool operator()(const BlockInfo* pLhsBlockInfo, const BlockInfo* pRhsBlockInfo) const;
- };
- typedef VmaVector> BlockInfoVector;
-
- BlockInfoVector m_Blocks;
- uint32_t m_AllocationCount;
- bool m_AllAllocations;
- VkDeviceSize m_BytesMoved;
- uint32_t m_AllocationsMoved;
-
- static bool MoveMakesSense(
- size_t dstBlockIndex, VkDeviceSize dstOffset,
- size_t srcBlockIndex, VkDeviceSize srcOffset);
-
- size_t CalcBlocksWithNonMovableCount() const;
- VkResult DefragmentRound(
- VmaVector>& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- bool freeOldAllocations);
-};
-#endif // _VMA_DEFRAGMENTATION_ALGORITHM_GENERIC
-
-#ifndef _VMA_DEFRAGMENTATION_ALGORITHM_FAST
-class VmaDefragmentationAlgorithm_Fast : public VmaDefragmentationAlgorithm
-{
- VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm_Fast)
-public:
- VmaDefragmentationAlgorithm_Fast(
- VmaAllocator hAllocator,
- VmaBlockVector* pBlockVector,
- bool overlappingMoveSupported);
- virtual ~VmaDefragmentationAlgorithm_Fast() = default;
-
- virtual void AddAll() { m_AllAllocations = true; }
- virtual VkDeviceSize GetBytesMoved() const { return m_BytesMoved; }
- virtual uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; }
- virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) { ++m_AllocationCount; }
-
- virtual VkResult Defragment(
- VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- VmaDefragmentationFlags flags);
-
-private:
- struct BlockInfo
- {
- size_t origBlockIndex;
- };
- class FreeSpaceDatabase
- {
- public:
- FreeSpaceDatabase();
-
- void Register(size_t blockInfoIndex, VkDeviceSize offset, VkDeviceSize size);
- bool Fetch(VkDeviceSize alignment, VkDeviceSize size,
- size_t& outBlockInfoIndex, VkDeviceSize& outDstOffset);
-
- private:
- static const size_t MAX_COUNT = 4;
-
- struct FreeSpace
- {
- size_t blockInfoIndex; // SIZE_MAX means this structure is invalid.
- VkDeviceSize offset;
- VkDeviceSize size;
- } m_FreeSpaces[MAX_COUNT];
- };
-
- const bool m_OverlappingMoveSupported;
-
- uint32_t m_AllocationCount;
- bool m_AllAllocations;
- VkDeviceSize m_BytesMoved;
- uint32_t m_AllocationsMoved;
-
- VmaVector> m_BlockInfos;
-
- void PreprocessMetadata();
- void PostprocessMetadata();
- void InsertSuballoc(VmaBlockMetadata_Generic* pMetadata, const VmaSuballocation& suballoc);
-};
-#endif // _VMA_DEFRAGMENTATION_ALGORITHM_FAST
-
-#ifndef _VMA_BLOCK_VECTOR_DEFRAGMENTATION_CONTEXT
-struct VmaBlockDefragmentationContext
-{
- enum BLOCK_FLAG
- {
- BLOCK_FLAG_USED = 0x00000001,
- };
- uint32_t flags;
- VkBuffer hBuffer;
-};
-
-class VmaBlockVectorDefragmentationContext
-{
- VMA_CLASS_NO_COPY(VmaBlockVectorDefragmentationContext)
-public:
- VkResult res;
- bool mutexLocked;
- VmaVector> blockContexts;
- VmaVector> defragmentationMoves;
- uint32_t defragmentationMovesProcessed;
- uint32_t defragmentationMovesCommitted;
- bool hasDefragmentationPlan;
-
- VmaBlockVectorDefragmentationContext(
- VmaAllocator hAllocator,
- VmaPool hCustomPool, // Optional.
- VmaBlockVector* pBlockVector);
- ~VmaBlockVectorDefragmentationContext();
-
- VmaPool GetCustomPool() const { return m_hCustomPool; }
- VmaBlockVector* GetBlockVector() const { return m_pBlockVector; }
- VmaDefragmentationAlgorithm* GetAlgorithm() const { return m_pAlgorithm; }
- void AddAll() { m_AllAllocations = true; }
-
- void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged);
- void Begin(bool overlappingMoveSupported, VmaDefragmentationFlags flags);
-
-private:
- struct AllocInfo
- {
- VmaAllocation hAlloc;
- VkBool32* pChanged;
- };
-
- const VmaAllocator m_hAllocator;
- // Null if not from custom pool.
- const VmaPool m_hCustomPool;
- // Redundant, for convenience not to fetch from m_hCustomPool->m_BlockVector or m_hAllocator->m_pBlockVectors.
- VmaBlockVector* const m_pBlockVector;
- // Owner of this object.
- VmaDefragmentationAlgorithm* m_pAlgorithm;
- // Used between constructor and Begin.
- VmaVector> m_Allocations;
- bool m_AllAllocations;
-};
-#endif // _VMA_BLOCK_VECTOR_DEFRAGMENTATION_CONTEXT
-
#ifndef _VMA_DEFRAGMENTATION_CONTEXT
struct VmaDefragmentationContext_T
{
-private:
VMA_CLASS_NO_COPY(VmaDefragmentationContext_T)
public:
VmaDefragmentationContext_T(
VmaAllocator hAllocator,
- uint32_t flags,
- VmaDefragmentationStats* pStats);
+ const VmaDefragmentationInfo& info);
~VmaDefragmentationContext_T();
- void AddPools(uint32_t poolCount, const VmaPool* pPools);
- void AddAllocations(
- uint32_t allocationCount,
- const VmaAllocation* pAllocations,
- VkBool32* pAllocationsChanged);
+ void GetStats(VmaDefragmentationStats& outStats) { outStats = m_Stats; }
- /*
- Returns:
- - `VK_SUCCESS` if succeeded and object can be destroyed immediately.
- - `VK_NOT_READY` if succeeded but the object must remain alive until vmaDefragmentationEnd().
- - Negative value if error occurred and object can be destroyed immediately.
- */
- VkResult Defragment(
- VkDeviceSize maxCpuBytesToMove, uint32_t maxCpuAllocationsToMove,
- VkDeviceSize maxGpuBytesToMove, uint32_t maxGpuAllocationsToMove,
- VkCommandBuffer commandBuffer, VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags);
-
- VkResult DefragmentPassBegin(VmaDefragmentationPassInfo* pInfo);
- VkResult DefragmentPassEnd();
+ VkResult DefragmentPassBegin(VmaDefragmentationPassMoveInfo& moveInfo);
+ VkResult DefragmentPassEnd(VmaDefragmentationPassMoveInfo& moveInfo);
private:
- const VmaAllocator m_hAllocator;
- const uint32_t m_Flags;
- VmaDefragmentationStats* const m_pStats;
+ struct ImmovableBlock
+ {
+ uint32_t vectorIndex;
+ VmaDeviceMemoryBlock* block;
+ };
+ struct StateExtensive
+ {
+ enum class Operation : uint8_t
+ {
+ FindFreeBlockBuffer, FindFreeBlockTexture, FindFreeBlockAll,
+ MoveBuffers, MoveTextures, MoveAll,
+ Cleanup, Done
+ };
- VkDeviceSize m_MaxCpuBytesToMove;
- uint32_t m_MaxCpuAllocationsToMove;
- VkDeviceSize m_MaxGpuBytesToMove;
- uint32_t m_MaxGpuAllocationsToMove;
+ Operation operation = Operation::FindFreeBlockTexture;
+ size_t firstFreeBlock = SIZE_MAX;
+ };
+ struct MoveAllocationData
+ {
+ VkDeviceSize size;
+ VkDeviceSize alignment;
+ VmaSuballocationType type;
+ VmaAllocationCreateFlags flags;
+ VmaDefragmentationMove move = {};
+ };
- // Owner of these objects.
- VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES];
- // Owner of these objects.
- VmaVector> m_CustomPoolContexts;
+ const VkDeviceSize m_MaxPassBytes;
+ const uint32_t m_MaxPassAllocations;
+
+ VmaStlAllocator m_MoveAllocator;
+ VmaVector> m_Moves;
+
+ uint32_t m_Algorithm;
+ uint32_t m_BlockVectorCount;
+ VmaBlockVector* m_PoolBlockVector;
+ VmaBlockVector** m_pBlockVectors;
+ size_t m_ImmovableBlockCount = 0;
+ VmaDefragmentationStats m_Stats = { 0 };
+ void* m_AlgorithmState = VMA_NULL;
+
+ static MoveAllocationData GetMoveData(VmaAllocHandle handle, VmaBlockMetadata* metadata);
+ bool IncrementCounters(uint32_t& allocations, VkDeviceSize bytes);
+ bool ReallocWithinBlock(VmaBlockVector& vector, VmaDeviceMemoryBlock* block);
+ bool AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector);
+
+ bool ComputeDefragmentation(VmaBlockVector& vector, size_t index);
+ bool ComputeDefragmentation_Fast(VmaBlockVector& vector);
+ bool ComputeDefragmentation_Balanced(VmaBlockVector& vector);
+ bool ComputeDefragmentation_Full(VmaBlockVector& vector);
+ bool ComputeDefragmentation_Extensive(VmaBlockVector& vector, size_t index);
+
+ bool MoveDataToFreeBlocks(VmaSuballocationType currentType,
+ VmaBlockVector& vector, size_t firstFreeBlock,
+ bool& texturePresent, bool& bufferPresent, bool& otherPresent);
};
#endif // _VMA_DEFRAGMENTATION_CONTEXT
@@ -11399,20 +11167,14 @@ VmaVirtualBlock_T::VmaVirtualBlock_T(const VmaVirtualBlockCreateInfo& createInfo
const uint32_t algorithm = createInfo.flags & VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK;
switch (algorithm)
{
+ default:
+ VMA_ASSERT(0);
case 0:
- m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_Generic)(VK_NULL_HANDLE, 1, true);
- break;
- case VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT:
- m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_Buddy)(VK_NULL_HANDLE, 1, true);
+ m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_TLSF)(VK_NULL_HANDLE, 1, true);
break;
case VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT:
m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_Linear)(VK_NULL_HANDLE, 1, true);
break;
- case VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT:
- m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_TLSF)(VK_NULL_HANDLE, 1, true);
- break;
- default:
- VMA_ASSERT(0);
}
m_Metadata->Init(createInfo.size);
@@ -11503,6 +11265,7 @@ void VmaVirtualBlock_T::BuildStatsString(bool detailedMap, VmaStringBuilder& sb)
#endif // _VMA_VIRTUAL_BLOCK_T_FUNCTIONS
#endif // _VMA_VIRTUAL_BLOCK_T
+
// Main allocator object.
struct VmaAllocator_T
{
@@ -11630,19 +11393,6 @@ public:
void PrintDetailedMap(class VmaJsonWriter& json);
#endif
- VkResult DefragmentationBegin(
- const VmaDefragmentationInfo2& info,
- VmaDefragmentationStats* pStats,
- VmaDefragmentationContext* pContext);
- VkResult DefragmentationEnd(
- VmaDefragmentationContext context);
-
- VkResult DefragmentationPassBegin(
- VmaDefragmentationPassInfo* pInfo,
- VmaDefragmentationContext context);
- VkResult DefragmentationPassEnd(
- VmaDefragmentationContext context);
-
void GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo);
VkResult CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool);
@@ -11911,19 +11661,11 @@ void VmaDeviceMemoryBlock::Init(
m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator->GetAllocationCallbacks(),
bufferImageGranularity, false); // isVirtual
break;
- case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT:
- m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Buddy)(hAllocator->GetAllocationCallbacks(),
- bufferImageGranularity, false); // isVirtual
- break;
- case VMA_POOL_CREATE_TLSF_ALGORITHM_BIT:
- m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_TLSF)(hAllocator->GetAllocationCallbacks(),
- bufferImageGranularity, false); // isVirtual
- break;
default:
VMA_ASSERT(0);
// Fall-through.
case 0:
- m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Generic)(hAllocator->GetAllocationCallbacks(),
+ m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_TLSF)(hAllocator->GetAllocationCallbacks(),
bufferImageGranularity, false); // isVirtual
}
m_pMetadata->Init(newSize);
@@ -12221,32 +11963,19 @@ void VmaAllocation_T::SetUserData(VmaAllocator hAllocator, void* pUserData)
}
}
-void VmaAllocation_T::ChangeBlockAllocation(
- VmaAllocator hAllocator,
- VmaDeviceMemoryBlock* block,
- VmaAllocHandle allocHandle)
+void VmaAllocation_T::SwapBlockAllocation(VmaAllocation allocation)
{
- VMA_ASSERT(block != VMA_NULL);
+ VMA_ASSERT(allocation != VMA_NULL);
VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);
+ VMA_ASSERT(allocation->m_Type == ALLOCATION_TYPE_BLOCK);
- // Move mapping reference counter from old block to new block.
- if (block != m_BlockAllocation.m_Block)
- {
- uint32_t mapRefCount = m_MapCount;
- if (IsPersistentMap())
- ++mapRefCount;
- m_BlockAllocation.m_Block->Unmap(hAllocator, mapRefCount);
- block->Map(hAllocator, mapRefCount, VMA_NULL);
- }
+ m_BlockAllocation.m_Block->m_pMetadata->SetAllocationUserData(m_BlockAllocation.m_AllocHandle, allocation);
+ VMA_SWAP(m_BlockAllocation, allocation->m_BlockAllocation);
+ m_BlockAllocation.m_Block->m_pMetadata->SetAllocationUserData(m_BlockAllocation.m_AllocHandle, this);
- m_BlockAllocation.m_Block = block;
- m_BlockAllocation.m_AllocHandle = allocHandle;
-}
-
-void VmaAllocation_T::ChangeAllocHandle(VmaAllocHandle newAllocHandle)
-{
- VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);
- m_BlockAllocation.m_AllocHandle = newAllocHandle;
+#if VMA_STATS_STRING_ENABLED
+ VMA_SWAP(m_BufferImageUsage, allocation->m_BufferImageUsage);
+#endif
}
VmaAllocHandle VmaAllocation_T::GetAllocHandle() const
@@ -12816,7 +12545,8 @@ VkResult VmaBlockVector::AllocatePage(
}
void VmaBlockVector::Free(
- const VmaAllocation hAllocation)
+ const VmaAllocation hAllocation,
+ bool incrementalSort)
{
VmaDeviceMemoryBlock* pBlockToDelete = VMA_NULL;
@@ -12876,7 +12606,8 @@ void VmaBlockVector::Free(
}
}
- IncrementallySortBlocks();
+ if (incrementalSort)
+ IncrementallySortBlocks();
}
// Destruction of a free block. Deferred until this point, outside of mutex
@@ -12932,6 +12663,15 @@ void VmaBlockVector::IncrementallySortBlocks()
}
}
+void VmaBlockVector::SortByFreeSize()
+{
+ VMA_SORT(m_Blocks.begin(), m_Blocks.end(),
+ [](auto* b1, auto* b2)
+ {
+ return b1->m_pMetadata->GetSumFreeSize() < b2->m_pMetadata->GetSumFreeSize();
+ });
+}
+
VkResult VmaBlockVector::AllocateFromBlock(
VmaDeviceMemoryBlock* pBlock,
VkDeviceSize size,
@@ -12943,10 +12683,6 @@ VkResult VmaBlockVector::AllocateFromBlock(
VmaAllocation* pAllocation)
{
const bool isUpperAddress = (allocFlags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0;
- const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0;
- const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0;
- const bool isMappingAllowed = (allocFlags &
- (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0;
VmaAllocationRequest currRequest = {};
if (pBlock->m_pMetadata->CreateAllocationRequest(
@@ -12957,45 +12693,61 @@ VkResult VmaBlockVector::AllocateFromBlock(
strategy,
&currRequest))
{
- pBlock->PostAlloc();
-
- // Allocate from pCurrBlock.
- if (mapped)
- {
- VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL);
- if (res != VK_SUCCESS)
- {
- return res;
- }
- }
-
- *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(isUserDataString, isMappingAllowed);
- pBlock->m_pMetadata->Alloc(currRequest, suballocType, *pAllocation);
- (*pAllocation)->InitBlockAllocation(
- pBlock,
- currRequest.allocHandle,
- alignment,
- currRequest.size, // Not size, as actual allocation size may be larger than requested!
- m_MemoryTypeIndex,
- suballocType,
- mapped);
- VMA_HEAVY_ASSERT(pBlock->Validate());
- (*pAllocation)->SetUserData(m_hAllocator, pUserData);
- m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), currRequest.size);
- if (VMA_DEBUG_INITIALIZE_ALLOCATIONS)
- {
- m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
- }
- if (IsCorruptionDetectionEnabled())
- {
- VkResult res = pBlock->WriteMagicValueAfterAllocation(m_hAllocator, (*pAllocation)->GetOffset(), currRequest.size);
- VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value.");
- }
- return VK_SUCCESS;
+ return CommitAllocationRequest(currRequest, pBlock, alignment, allocFlags, pUserData, suballocType, pAllocation);
}
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
+VkResult VmaBlockVector::CommitAllocationRequest(
+ VmaAllocationRequest& allocRequest,
+ VmaDeviceMemoryBlock* pBlock,
+ VkDeviceSize alignment,
+ VmaAllocationCreateFlags allocFlags,
+ void* pUserData,
+ VmaSuballocationType suballocType,
+ VmaAllocation* pAllocation)
+{
+ const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0;
+ const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0;
+ const bool isMappingAllowed = (allocFlags &
+ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0;
+
+ pBlock->PostAlloc();
+ // Allocate from pCurrBlock.
+ if (mapped)
+ {
+ VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL);
+ if (res != VK_SUCCESS)
+ {
+ return res;
+ }
+ }
+
+ *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(isUserDataString, isMappingAllowed);
+ pBlock->m_pMetadata->Alloc(allocRequest, suballocType, *pAllocation);
+ (*pAllocation)->InitBlockAllocation(
+ pBlock,
+ allocRequest.allocHandle,
+ alignment,
+ allocRequest.size, // Not size, as actual allocation size may be larger than requested!
+ m_MemoryTypeIndex,
+ suballocType,
+ mapped);
+ VMA_HEAVY_ASSERT(pBlock->Validate());
+ (*pAllocation)->SetUserData(m_hAllocator, pUserData);
+ m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), allocRequest.size);
+ if (VMA_DEBUG_INITIALIZE_ALLOCATIONS)
+ {
+ m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
+ }
+ if (IsCorruptionDetectionEnabled())
+ {
+ VkResult res = pBlock->WriteMagicValueAfterAllocation(m_hAllocator, (*pAllocation)->GetOffset(), allocRequest.size);
+ VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value.");
+ }
+ return VK_SUCCESS;
+}
+
VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex)
{
VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
@@ -13062,229 +12814,7 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn
return VK_SUCCESS;
}
-void VmaBlockVector::ApplyDefragmentationMovesCpu(
- VmaBlockVectorDefragmentationContext* pDefragCtx,
- const VmaVector>& moves)
-{
- const size_t blockCount = m_Blocks.size();
- const bool isNonCoherent = m_hAllocator->IsMemoryTypeNonCoherent(m_MemoryTypeIndex);
-
- enum BLOCK_FLAG
- {
- BLOCK_FLAG_USED = 0x00000001,
- BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION = 0x00000002,
- };
-
- struct BlockInfo
- {
- uint32_t flags;
- void* pMappedData;
- };
- VmaVector< BlockInfo, VmaStlAllocator >
- blockInfo(blockCount, BlockInfo(), VmaStlAllocator(m_hAllocator->GetAllocationCallbacks()));
- memset(blockInfo.data(), 0, blockCount * sizeof(BlockInfo));
-
- // Go over all moves. Mark blocks that are used with BLOCK_FLAG_USED.
- const size_t moveCount = moves.size();
- for (size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex)
- {
- const VmaDefragmentationMove& move = moves[moveIndex];
- blockInfo[move.srcBlockIndex].flags |= BLOCK_FLAG_USED;
- blockInfo[move.dstBlockIndex].flags |= BLOCK_FLAG_USED;
- }
-
- VMA_ASSERT(pDefragCtx->res == VK_SUCCESS);
-
- // Go over all blocks. Get mapped pointer or map if necessary.
- for (size_t blockIndex = 0; pDefragCtx->res == VK_SUCCESS && blockIndex < blockCount; ++blockIndex)
- {
- BlockInfo& currBlockInfo = blockInfo[blockIndex];
- VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];
- if ((currBlockInfo.flags & BLOCK_FLAG_USED) != 0)
- {
- currBlockInfo.pMappedData = pBlock->GetMappedData();
- // It is not originally mapped - map it.
- if (currBlockInfo.pMappedData == VMA_NULL)
- {
- pDefragCtx->res = pBlock->Map(m_hAllocator, 1, &currBlockInfo.pMappedData);
- if (pDefragCtx->res == VK_SUCCESS)
- {
- currBlockInfo.flags |= BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION;
- }
- }
- }
- }
-
- // Go over all moves. Do actual data transfer.
- if (pDefragCtx->res == VK_SUCCESS)
- {
- const VkDeviceSize nonCoherentAtomSize = m_hAllocator->m_PhysicalDeviceProperties.limits.nonCoherentAtomSize;
- VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
-
- for (size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex)
- {
- const VmaDefragmentationMove& move = moves[moveIndex];
-
- const BlockInfo& srcBlockInfo = blockInfo[move.srcBlockIndex];
- const BlockInfo& dstBlockInfo = blockInfo[move.dstBlockIndex];
-
- VMA_ASSERT(srcBlockInfo.pMappedData && dstBlockInfo.pMappedData);
-
- // Invalidate source.
- if (isNonCoherent)
- {
- VmaDeviceMemoryBlock* const pSrcBlock = m_Blocks[move.srcBlockIndex];
- memRange.memory = pSrcBlock->GetDeviceMemory();
- memRange.offset = VmaAlignDown(move.srcOffset, nonCoherentAtomSize);
- memRange.size = VMA_MIN(
- VmaAlignUp(move.size + (move.srcOffset - memRange.offset), nonCoherentAtomSize),
- pSrcBlock->m_pMetadata->GetSize() - memRange.offset);
- (*m_hAllocator->GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hAllocator->m_hDevice, 1, &memRange);
- }
-
- // THE PLACE WHERE ACTUAL DATA COPY HAPPENS.
- memmove(
- reinterpret_cast(dstBlockInfo.pMappedData) + move.dstOffset,
- reinterpret_cast(srcBlockInfo.pMappedData) + move.srcOffset,
- static_cast(move.size));
-
- if (IsCorruptionDetectionEnabled())
- {
- VmaWriteMagicValue(dstBlockInfo.pMappedData, move.dstOffset + move.size);
- }
-
- // Flush destination.
- if (isNonCoherent)
- {
- VmaDeviceMemoryBlock* const pDstBlock = m_Blocks[move.dstBlockIndex];
- memRange.memory = pDstBlock->GetDeviceMemory();
- memRange.offset = VmaAlignDown(move.dstOffset, nonCoherentAtomSize);
- memRange.size = VMA_MIN(
- VmaAlignUp(move.size + (move.dstOffset - memRange.offset), nonCoherentAtomSize),
- pDstBlock->m_pMetadata->GetSize() - memRange.offset);
- (*m_hAllocator->GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hAllocator->m_hDevice, 1, &memRange);
- }
- }
- }
-
- // Go over all blocks in reverse order. Unmap those that were mapped just for defragmentation.
- // Regardless of pCtx->res == VK_SUCCESS.
- for (size_t blockIndex = blockCount; blockIndex--; )
- {
- const BlockInfo& currBlockInfo = blockInfo[blockIndex];
- if ((currBlockInfo.flags & BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION) != 0)
- {
- VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];
- pBlock->Unmap(m_hAllocator, 1);
- }
- }
-}
-
-void VmaBlockVector::ApplyDefragmentationMovesGpu(
- VmaBlockVectorDefragmentationContext* pDefragCtx,
- VmaVector>& moves,
- VkCommandBuffer commandBuffer)
-{
- const size_t blockCount = m_Blocks.size();
-
- pDefragCtx->blockContexts.resize(blockCount);
- memset(pDefragCtx->blockContexts.data(), 0, blockCount * sizeof(VmaBlockDefragmentationContext));
-
- // Go over all moves. Mark blocks that are used with BLOCK_FLAG_USED.
- const size_t moveCount = moves.size();
- for (size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex)
- {
- const VmaDefragmentationMove& move = moves[moveIndex];
-
- //if(move.type == VMA_ALLOCATION_TYPE_UNKNOWN)
- {
- // Old school move still require us to map the whole block
- pDefragCtx->blockContexts[move.srcBlockIndex].flags |= VmaBlockDefragmentationContext::BLOCK_FLAG_USED;
- pDefragCtx->blockContexts[move.dstBlockIndex].flags |= VmaBlockDefragmentationContext::BLOCK_FLAG_USED;
- }
- }
-
- VMA_ASSERT(pDefragCtx->res == VK_SUCCESS);
-
- // Go over all blocks. Create and bind buffer for whole block if necessary.
- {
- VkBufferCreateInfo bufCreateInfo;
- VmaFillGpuDefragmentationBufferCreateInfo(bufCreateInfo);
-
- for (size_t blockIndex = 0; pDefragCtx->res == VK_SUCCESS && blockIndex < blockCount; ++blockIndex)
- {
- VmaBlockDefragmentationContext& currBlockCtx = pDefragCtx->blockContexts[blockIndex];
- VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];
- if ((currBlockCtx.flags & VmaBlockDefragmentationContext::BLOCK_FLAG_USED) != 0)
- {
- bufCreateInfo.size = pBlock->m_pMetadata->GetSize();
- pDefragCtx->res = (*m_hAllocator->GetVulkanFunctions().vkCreateBuffer)(
- m_hAllocator->m_hDevice, &bufCreateInfo, m_hAllocator->GetAllocationCallbacks(), &currBlockCtx.hBuffer);
- if (pDefragCtx->res == VK_SUCCESS)
- {
- pDefragCtx->res = (*m_hAllocator->GetVulkanFunctions().vkBindBufferMemory)(
- m_hAllocator->m_hDevice, currBlockCtx.hBuffer, pBlock->GetDeviceMemory(), 0);
- }
- }
- }
- }
-
- // Go over all moves. Post data transfer commands to command buffer.
- if (pDefragCtx->res == VK_SUCCESS)
- {
- for (size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex)
- {
- const VmaDefragmentationMove& move = moves[moveIndex];
-
- const VmaBlockDefragmentationContext& srcBlockCtx = pDefragCtx->blockContexts[move.srcBlockIndex];
- const VmaBlockDefragmentationContext& dstBlockCtx = pDefragCtx->blockContexts[move.dstBlockIndex];
-
- VMA_ASSERT(srcBlockCtx.hBuffer && dstBlockCtx.hBuffer);
-
- VkBufferCopy region = {
- move.srcOffset,
- move.dstOffset,
- move.size };
- (*m_hAllocator->GetVulkanFunctions().vkCmdCopyBuffer)(
- commandBuffer, srcBlockCtx.hBuffer, dstBlockCtx.hBuffer, 1, ®ion);
- }
- }
-
- // Save buffers to defrag context for later destruction.
- if (pDefragCtx->res == VK_SUCCESS && moveCount > 0)
- {
- pDefragCtx->res = VK_NOT_READY;
- }
-}
-
-void VmaBlockVector::FreeEmptyBlocks(VmaDefragmentationStats* pDefragmentationStats)
-{
- for (size_t blockIndex = m_Blocks.size(); blockIndex--; )
- {
- VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex];
- if (pBlock->m_pMetadata->IsEmpty())
- {
- if (m_Blocks.size() > m_MinBlockCount)
- {
- if (pDefragmentationStats != VMA_NULL)
- {
- ++pDefragmentationStats->deviceMemoryBlocksFreed;
- pDefragmentationStats->bytesFreed += pBlock->m_pMetadata->GetSize();
- }
-
- VmaVectorRemove(m_Blocks, blockIndex);
- pBlock->Destroy(m_hAllocator);
- vma_delete(m_hAllocator, pBlock);
- }
- else
- {
- break;
- }
- }
- }
-}
-
-bool VmaBlockVector::HasEmptyBlock() const
+bool VmaBlockVector::HasEmptyBlock()
{
for (size_t index = 0, count = m_Blocks.size(); index < count; ++index)
{
@@ -13359,228 +12889,6 @@ void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json)
}
#endif // VMA_STATS_STRING_ENABLED
-void VmaBlockVector::Defragment(
- class VmaBlockVectorDefragmentationContext* pCtx,
- VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags,
- VkDeviceSize& maxCpuBytesToMove, uint32_t& maxCpuAllocationsToMove,
- VkDeviceSize& maxGpuBytesToMove, uint32_t& maxGpuAllocationsToMove,
- VkCommandBuffer commandBuffer)
-{
- pCtx->res = VK_SUCCESS;
-
- const VkMemoryPropertyFlags memPropFlags =
- m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags;
- const bool isHostVisible = (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
-
- const bool canDefragmentOnCpu = maxCpuBytesToMove > 0 && maxCpuAllocationsToMove > 0 &&
- isHostVisible;
- const bool canDefragmentOnGpu = maxGpuBytesToMove > 0 && maxGpuAllocationsToMove > 0 &&
- !IsCorruptionDetectionEnabled() &&
- ((1u << m_MemoryTypeIndex) & m_hAllocator->GetGpuDefragmentationMemoryTypeBits()) != 0;
-
- // There are options to defragment this memory type.
- if (canDefragmentOnCpu || canDefragmentOnGpu)
- {
- bool defragmentOnGpu;
- // There is only one option to defragment this memory type.
- if (canDefragmentOnGpu != canDefragmentOnCpu)
- {
- defragmentOnGpu = canDefragmentOnGpu;
- }
- // Both options are available: Heuristics to choose the best one.
- else
- {
- defragmentOnGpu = (memPropFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 ||
- m_hAllocator->IsIntegratedGpu();
- }
-
- bool overlappingMoveSupported = !defragmentOnGpu;
-
- if (m_hAllocator->m_UseMutex)
- {
- if (flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)
- {
- if (!m_Mutex.TryLockWrite())
- {
- pCtx->res = VK_ERROR_INITIALIZATION_FAILED;
- return;
- }
- }
- else
- {
- m_Mutex.LockWrite();
- pCtx->mutexLocked = true;
- }
- }
-
- pCtx->Begin(overlappingMoveSupported, flags);
-
- // Defragment.
-
- const VkDeviceSize maxBytesToMove = defragmentOnGpu ? maxGpuBytesToMove : maxCpuBytesToMove;
- const uint32_t maxAllocationsToMove = defragmentOnGpu ? maxGpuAllocationsToMove : maxCpuAllocationsToMove;
- VmaDefragmentationAlgorithm* algo = pCtx->GetAlgorithm();
- pCtx->res = algo->Defragment(pCtx->defragmentationMoves, maxBytesToMove, maxAllocationsToMove, flags);
-
- // Accumulate statistics.
- if (pStats != VMA_NULL)
- {
- const VkDeviceSize bytesMoved = algo->GetBytesMoved();
- const uint32_t allocationsMoved = algo->GetAllocationsMoved();
- pStats->bytesMoved += bytesMoved;
- pStats->allocationsMoved += allocationsMoved;
- VMA_ASSERT(bytesMoved <= maxBytesToMove);
- VMA_ASSERT(allocationsMoved <= maxAllocationsToMove);
- if (defragmentOnGpu)
- {
- maxGpuBytesToMove -= bytesMoved;
- maxGpuAllocationsToMove -= allocationsMoved;
- }
- else
- {
- maxCpuBytesToMove -= bytesMoved;
- maxCpuAllocationsToMove -= allocationsMoved;
- }
- }
-
- if (flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)
- {
- if (m_hAllocator->m_UseMutex)
- m_Mutex.UnlockWrite();
-
- if (pCtx->res >= VK_SUCCESS && !pCtx->defragmentationMoves.empty())
- pCtx->res = VK_NOT_READY;
-
- return;
- }
-
- if (pCtx->res >= VK_SUCCESS)
- {
- if (defragmentOnGpu)
- {
- ApplyDefragmentationMovesGpu(pCtx, pCtx->defragmentationMoves, commandBuffer);
- }
- else
- {
- ApplyDefragmentationMovesCpu(pCtx, pCtx->defragmentationMoves);
- }
- }
- }
-}
-
-void VmaBlockVector::DefragmentationEnd(
- class VmaBlockVectorDefragmentationContext* pCtx,
- uint32_t flags,
- VmaDefragmentationStats* pStats)
-{
- if (flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL && m_hAllocator->m_UseMutex)
- {
- VMA_ASSERT(pCtx->mutexLocked == false);
-
- // Incremental defragmentation doesn't hold the lock, so when we enter here we don't actually have any
- // lock protecting us. Since we mutate state here, we have to take the lock out now
- m_Mutex.LockWrite();
- pCtx->mutexLocked = true;
- }
-
- // If the mutex isn't locked we didn't do any work and there is nothing to delete.
- if (pCtx->mutexLocked || !m_hAllocator->m_UseMutex)
- {
- // Destroy buffers.
- for (size_t blockIndex = pCtx->blockContexts.size(); blockIndex--;)
- {
- VmaBlockDefragmentationContext& blockCtx = pCtx->blockContexts[blockIndex];
- if (blockCtx.hBuffer)
- {
- (*m_hAllocator->GetVulkanFunctions().vkDestroyBuffer)(m_hAllocator->m_hDevice, blockCtx.hBuffer, m_hAllocator->GetAllocationCallbacks());
- }
- }
-
- if (pCtx->res >= VK_SUCCESS)
- {
- FreeEmptyBlocks(pStats);
- }
- }
-
- if (pCtx->mutexLocked)
- {
- VMA_ASSERT(m_hAllocator->m_UseMutex);
- m_Mutex.UnlockWrite();
- }
-}
-
-uint32_t VmaBlockVector::ProcessDefragmentations(
- class VmaBlockVectorDefragmentationContext* pCtx,
- VmaDefragmentationPassMoveInfo* pMove, uint32_t maxMoves)
-{
- VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex);
-
- const uint32_t moveCount = VMA_MIN(uint32_t(pCtx->defragmentationMoves.size()) - pCtx->defragmentationMovesProcessed, maxMoves);
-
- for (uint32_t i = 0; i < moveCount; ++i)
- {
- VmaDefragmentationMove& move = pCtx->defragmentationMoves[pCtx->defragmentationMovesProcessed + i];
-
- pMove->allocation = move.hAllocation;
- pMove->memory = move.pDstBlock->GetDeviceMemory();
- pMove->offset = move.dstOffset;
-
- ++pMove;
- }
-
- pCtx->defragmentationMovesProcessed += moveCount;
-
- return moveCount;
-}
-
-void VmaBlockVector::CommitDefragmentations(
- class VmaBlockVectorDefragmentationContext* pCtx,
- VmaDefragmentationStats* pStats)
-{
- VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex);
-
- for (uint32_t i = pCtx->defragmentationMovesCommitted; i < pCtx->defragmentationMovesProcessed; ++i)
- {
- const VmaDefragmentationMove& move = pCtx->defragmentationMoves[i];
-
- move.pSrcBlock->m_pMetadata->Free(move.hAllocation->GetAllocHandle());
- move.hAllocation->ChangeBlockAllocation(m_hAllocator, move.pDstBlock, move.dstHandle);
- }
-
- pCtx->defragmentationMovesCommitted = pCtx->defragmentationMovesProcessed;
- FreeEmptyBlocks(pStats);
-}
-
-size_t VmaBlockVector::CalcAllocationCount() const
-{
- size_t result = 0;
- for (size_t i = 0; i < m_Blocks.size(); ++i)
- {
- result += m_Blocks[i]->m_pMetadata->GetAllocationCount();
- }
- return result;
-}
-
-bool VmaBlockVector::IsBufferImageGranularityConflictPossible() const
-{
- if (m_BufferImageGranularity == 1)
- {
- return false;
- }
- VmaSuballocationType lastSuballocType = VMA_SUBALLOCATION_TYPE_FREE;
- for (size_t i = 0, count = m_Blocks.size(); i < count; ++i)
- {
- VmaDeviceMemoryBlock* const pBlock = m_Blocks[i];
- VMA_ASSERT(m_Algorithm == 0);
- VmaBlockMetadata_Generic* const pMetadata = (VmaBlockMetadata_Generic*)pBlock->m_pMetadata;
- if (pMetadata->IsBufferImageGranularityConflictPossible(m_BufferImageGranularity, lastSuballocType))
- {
- return true;
- }
- }
- return false;
-}
-
VkResult VmaBlockVector::CheckCorruption()
{
if (!IsCorruptionDetectionEnabled())
@@ -13604,1244 +12912,784 @@ VkResult VmaBlockVector::CheckCorruption()
#endif // _VMA_BLOCK_VECTOR_FUNCTIONS
-#ifndef _VMA_DEFRAGMENTATION_ALGORITHM_GENERIC_FUNCTIONS
-VmaDefragmentationAlgorithm_Generic::VmaDefragmentationAlgorithm_Generic(
- VmaAllocator hAllocator,
- VmaBlockVector* pBlockVector,
- bool overlappingMoveSupported)
- : VmaDefragmentationAlgorithm(hAllocator, pBlockVector),
- m_Blocks(VmaStlAllocator(hAllocator->GetAllocationCallbacks())),
- m_AllocationCount(0),
- m_AllAllocations(false),
- m_BytesMoved(0),
- m_AllocationsMoved(0)
-{
- // Create block info for each block.
- const size_t blockCount = m_pBlockVector->m_Blocks.size();
- for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
- {
- BlockInfo* pBlockInfo = vma_new(m_hAllocator, BlockInfo)(m_hAllocator->GetAllocationCallbacks());
- pBlockInfo->m_OriginalBlockIndex = blockIndex;
- pBlockInfo->m_pBlock = m_pBlockVector->m_Blocks[blockIndex];
- m_Blocks.push_back(pBlockInfo);
- }
-
- // Sort them by m_pBlock pointer value.
- VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockPointerLess());
-}
-
-VmaDefragmentationAlgorithm_Generic::~VmaDefragmentationAlgorithm_Generic()
-{
- for (size_t i = m_Blocks.size(); i--; )
- {
- vma_delete(m_hAllocator, m_Blocks[i]);
- }
-}
-
-void VmaDefragmentationAlgorithm_Generic::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged)
-{
- VmaDeviceMemoryBlock* pBlock = hAlloc->GetBlock();
- BlockInfoVector::iterator it = VmaBinaryFindFirstNotLess(m_Blocks.begin(), m_Blocks.end(), pBlock, BlockPointerLess());
- if (it != m_Blocks.end() && (*it)->m_pBlock == pBlock)
- {
- AllocationInfo allocInfo = AllocationInfo(hAlloc, pChanged);
- (*it)->m_Allocations.push_back(allocInfo);
- }
- else
- {
- VMA_ASSERT(0);
- }
-
- ++m_AllocationCount;
-}
-
-VkResult VmaDefragmentationAlgorithm_Generic::DefragmentRound(
- VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- bool freeOldAllocations)
-{
- if (m_Blocks.empty())
- {
- return VK_SUCCESS;
- }
-
- // This is a choice based on research.
- // Option 1:
- uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT;
- // Option 2:
- //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT;
-
- size_t srcBlockMinIndex = 0;
- // When FAST_ALGORITHM, move allocations from only last out of blocks that contain non-movable allocations.
- /*
- if(m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT)
- {
- const size_t blocksWithNonMovableCount = CalcBlocksWithNonMovableCount();
- if(blocksWithNonMovableCount > 0)
- {
- srcBlockMinIndex = blocksWithNonMovableCount - 1;
- }
- }
- */
-
- size_t srcBlockIndex = m_Blocks.size() - 1;
- size_t srcAllocIndex = SIZE_MAX;
- for (;;)
- {
- // 1. Find next allocation to move.
- // 1.1. Start from last to first m_Blocks - they are sorted from most "destination" to most "source".
- // 1.2. Then start from last to first m_Allocations.
- while (srcAllocIndex >= m_Blocks[srcBlockIndex]->m_Allocations.size())
- {
- if (m_Blocks[srcBlockIndex]->m_Allocations.empty())
- {
- // Finished: no more allocations to process.
- if (srcBlockIndex == srcBlockMinIndex)
- {
- return VK_SUCCESS;
- }
- else
- {
- --srcBlockIndex;
- srcAllocIndex = SIZE_MAX;
- }
- }
- else
- {
- srcAllocIndex = m_Blocks[srcBlockIndex]->m_Allocations.size() - 1;
- }
- }
-
- BlockInfo* pSrcBlockInfo = m_Blocks[srcBlockIndex];
- AllocationInfo& allocInfo = pSrcBlockInfo->m_Allocations[srcAllocIndex];
-
- const VkDeviceSize size = allocInfo.m_hAllocation->GetSize();
- const VkDeviceSize srcOffset = allocInfo.m_hAllocation->GetOffset();
- const VkDeviceSize alignment = allocInfo.m_hAllocation->GetAlignment();
- const VmaSuballocationType suballocType = allocInfo.m_hAllocation->GetSuballocationType();
-
- // 2. Try to find new place for this allocation in preceding or current block.
- for (size_t dstBlockIndex = 0; dstBlockIndex <= srcBlockIndex; ++dstBlockIndex)
- {
- BlockInfo* pDstBlockInfo = m_Blocks[dstBlockIndex];
- VmaBlockMetadata* pMetadata = pDstBlockInfo->m_pBlock->m_pMetadata;
- VmaAllocationRequest dstAllocRequest;
- if (pMetadata->CreateAllocationRequest(
- size,
- alignment,
- false, // upperAddress
- suballocType,
- strategy,
- &dstAllocRequest) &&
- MoveMakesSense(
- dstBlockIndex, pMetadata->GetAllocationOffset(dstAllocRequest.allocHandle), srcBlockIndex, srcOffset))
- {
- // Reached limit on number of allocations or bytes to move.
- if ((m_AllocationsMoved + 1 > maxAllocationsToMove) ||
- (m_BytesMoved + size > maxBytesToMove))
- {
- return VK_SUCCESS;
- }
-
- VmaDefragmentationMove move = {};
- move.srcBlockIndex = pSrcBlockInfo->m_OriginalBlockIndex;
- move.dstBlockIndex = pDstBlockInfo->m_OriginalBlockIndex;
- move.srcOffset = srcOffset;
- move.dstOffset = pMetadata->GetAllocationOffset(dstAllocRequest.allocHandle);
- move.size = size;
- move.hAllocation = allocInfo.m_hAllocation;
- move.pSrcBlock = pSrcBlockInfo->m_pBlock;
- move.pDstBlock = pDstBlockInfo->m_pBlock;
- move.dstHandle = dstAllocRequest.allocHandle;
-
- moves.push_back(move);
-
- pDstBlockInfo->m_pBlock->m_pMetadata->Alloc(dstAllocRequest, suballocType, allocInfo.m_hAllocation);
-
- if (freeOldAllocations)
- {
- pSrcBlockInfo->m_pBlock->m_pMetadata->Free(allocInfo.m_hAllocation->GetAllocHandle());
- allocInfo.m_hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlockInfo->m_pBlock, dstAllocRequest.allocHandle);
- }
-
- if (allocInfo.m_pChanged != VMA_NULL)
- {
- *allocInfo.m_pChanged = VK_TRUE;
- }
-
- ++m_AllocationsMoved;
- m_BytesMoved += size;
-
- VmaVectorRemove(pSrcBlockInfo->m_Allocations, srcAllocIndex);
-
- break;
- }
- }
-
- // If not processed, this allocInfo remains in pBlockInfo->m_Allocations for next round.
-
- if (srcAllocIndex > 0)
- {
- --srcAllocIndex;
- }
- else
- {
- if (srcBlockIndex > 0)
- {
- --srcBlockIndex;
- srcAllocIndex = SIZE_MAX;
- }
- else
- {
- return VK_SUCCESS;
- }
- }
- }
-}
-
-bool VmaDefragmentationAlgorithm_Generic::AllocationInfoSizeGreater::operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const
-{
- return lhs.m_hAllocation->GetSize() > rhs.m_hAllocation->GetSize();
-}
-
-bool VmaDefragmentationAlgorithm_Generic::AllocationInfoOffsetGreater::operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const
-{
- return lhs.m_hAllocation->GetOffset() > rhs.m_hAllocation->GetOffset();
-}
-
-VmaDefragmentationAlgorithm_Generic::BlockInfo::BlockInfo(const VkAllocationCallbacks* pAllocationCallbacks)
- : m_OriginalBlockIndex(SIZE_MAX),
- m_pBlock(VMA_NULL),
- m_HasNonMovableAllocations(true),
- m_Allocations(pAllocationCallbacks) {}
-
-void VmaDefragmentationAlgorithm_Generic::BlockInfo::CalcHasNonMovableAllocations()
-{
- const size_t blockAllocCount = m_pBlock->m_pMetadata->GetAllocationCount();
- const size_t defragmentAllocCount = m_Allocations.size();
- m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount;
-}
-
-void VmaDefragmentationAlgorithm_Generic::BlockInfo::SortAllocationsBySizeDescending()
-{
- VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater());
-}
-
-void VmaDefragmentationAlgorithm_Generic::BlockInfo::SortAllocationsByOffsetDescending()
-{
- VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoOffsetGreater());
-}
-
-bool VmaDefragmentationAlgorithm_Generic::BlockPointerLess::operator()(const BlockInfo* pLhsBlockInfo, const VmaDeviceMemoryBlock* pRhsBlock) const
-{
- return pLhsBlockInfo->m_pBlock < pRhsBlock;
-}
-bool VmaDefragmentationAlgorithm_Generic::BlockPointerLess::operator()(const BlockInfo* pLhsBlockInfo, const BlockInfo* pRhsBlockInfo) const
-{
- return pLhsBlockInfo->m_pBlock < pRhsBlockInfo->m_pBlock;
-}
-
-bool VmaDefragmentationAlgorithm_Generic::BlockInfoCompareMoveDestination::operator()(const BlockInfo* pLhsBlockInfo, const BlockInfo* pRhsBlockInfo) const
-{
- if (pLhsBlockInfo->m_HasNonMovableAllocations && !pRhsBlockInfo->m_HasNonMovableAllocations)
- {
- return true;
- }
- if (!pLhsBlockInfo->m_HasNonMovableAllocations && pRhsBlockInfo->m_HasNonMovableAllocations)
- {
- return false;
- }
- if (pLhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize() < pRhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize())
- {
- return true;
- }
- return false;
-}
-
-bool VmaDefragmentationAlgorithm_Generic::MoveMakesSense(
- size_t dstBlockIndex, VkDeviceSize dstOffset,
- size_t srcBlockIndex, VkDeviceSize srcOffset)
-{
- if (dstBlockIndex < srcBlockIndex)
- {
- return true;
- }
- if (dstBlockIndex > srcBlockIndex)
- {
- return false;
- }
- if (dstOffset < srcOffset)
- {
- return true;
- }
- return false;
-}
-
-size_t VmaDefragmentationAlgorithm_Generic::CalcBlocksWithNonMovableCount() const
-{
- size_t result = 0;
- for (size_t i = 0; i < m_Blocks.size(); ++i)
- {
- if (m_Blocks[i]->m_HasNonMovableAllocations)
- {
- ++result;
- }
- }
- return result;
-}
-
-VkResult VmaDefragmentationAlgorithm_Generic::Defragment(
- VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- VmaDefragmentationFlags flags)
-{
- if (!m_AllAllocations && m_AllocationCount == 0)
- {
- return VK_SUCCESS;
- }
-
- const size_t blockCount = m_Blocks.size();
- for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
- {
- BlockInfo* pBlockInfo = m_Blocks[blockIndex];
-
- if (m_AllAllocations)
- {
- VmaBlockMetadata_Generic* pMetadata = (VmaBlockMetadata_Generic*)pBlockInfo->m_pBlock->m_pMetadata;
- VMA_ASSERT(!pMetadata->IsVirtual());
- for (VmaSuballocationList::const_iterator it = pMetadata->m_Suballocations.begin();
- it != pMetadata->m_Suballocations.end();
- ++it)
- {
- if (it->type != VMA_SUBALLOCATION_TYPE_FREE)
- {
- AllocationInfo allocInfo = AllocationInfo((VmaAllocation)it->userData, VMA_NULL);
- pBlockInfo->m_Allocations.push_back(allocInfo);
- }
- }
- }
-
- pBlockInfo->CalcHasNonMovableAllocations();
-
- // This is a choice based on research.
- // Option 1:
- pBlockInfo->SortAllocationsByOffsetDescending();
- // Option 2:
- //pBlockInfo->SortAllocationsBySizeDescending();
- }
-
- // Sort m_Blocks this time by the main criterium, from most "destination" to most "source" blocks.
- VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockInfoCompareMoveDestination());
-
- // This is a choice based on research.
- const uint32_t roundCount = 2;
-
- // Execute defragmentation rounds (the main part).
- VkResult result = VK_SUCCESS;
- for (uint32_t round = 0; (round < roundCount) && (result == VK_SUCCESS); ++round)
- {
- result = DefragmentRound(moves, maxBytesToMove, maxAllocationsToMove, !(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL));
- }
-
- return result;
-}
-#endif // _VMA_DEFRAGMENTATION_ALGORITHM_GENERIC_FUNCTIONS
-
-#ifndef _VMA_DEFRAGMENTATION_ALGORITHM_FAST_FUNCTIONS
-VmaDefragmentationAlgorithm_Fast::VmaDefragmentationAlgorithm_Fast(
- VmaAllocator hAllocator,
- VmaBlockVector* pBlockVector,
- bool overlappingMoveSupported)
- : VmaDefragmentationAlgorithm(hAllocator, pBlockVector),
- m_OverlappingMoveSupported(overlappingMoveSupported),
- m_AllocationCount(0),
- m_AllAllocations(false),
- m_BytesMoved(0),
- m_AllocationsMoved(0),
- m_BlockInfos(VmaStlAllocator(hAllocator->GetAllocationCallbacks()))
-{
- VMA_ASSERT(VMA_DEBUG_MARGIN == 0);
-}
-
-VkResult VmaDefragmentationAlgorithm_Fast::Defragment(
- VmaVector>& moves,
- VkDeviceSize maxBytesToMove,
- uint32_t maxAllocationsToMove,
- VmaDefragmentationFlags flags)
-{
- VMA_ASSERT(m_AllAllocations || m_pBlockVector->CalcAllocationCount() == m_AllocationCount);
-
- const size_t blockCount = m_pBlockVector->GetBlockCount();
- if (blockCount == 0 || maxBytesToMove == 0 || maxAllocationsToMove == 0)
- {
- return VK_SUCCESS;
- }
-
- PreprocessMetadata();
-
- // Sort blocks in order from most destination.
-
- m_BlockInfos.resize(blockCount);
- for (size_t i = 0; i < blockCount; ++i)
- {
- m_BlockInfos[i].origBlockIndex = i;
- }
-
- VMA_SORT(m_BlockInfos.begin(), m_BlockInfos.end(), [this](const BlockInfo& lhs, const BlockInfo& rhs) -> bool {
- return m_pBlockVector->GetBlock(lhs.origBlockIndex)->m_pMetadata->GetSumFreeSize() <
- m_pBlockVector->GetBlock(rhs.origBlockIndex)->m_pMetadata->GetSumFreeSize();
- });
-
- // THE MAIN ALGORITHM
-
- FreeSpaceDatabase freeSpaceDb;
-
- size_t dstBlockInfoIndex = 0;
- size_t dstOrigBlockIndex = m_BlockInfos[dstBlockInfoIndex].origBlockIndex;
- VmaDeviceMemoryBlock* pDstBlock = m_pBlockVector->GetBlock(dstOrigBlockIndex);
- VmaBlockMetadata_Generic* pDstMetadata = (VmaBlockMetadata_Generic*)pDstBlock->m_pMetadata;
- VkDeviceSize dstBlockSize = pDstMetadata->GetSize();
- VkDeviceSize dstOffset = 0;
-
- bool end = false;
- for (size_t srcBlockInfoIndex = 0; !end && srcBlockInfoIndex < blockCount; ++srcBlockInfoIndex)
- {
- const size_t srcOrigBlockIndex = m_BlockInfos[srcBlockInfoIndex].origBlockIndex;
- VmaDeviceMemoryBlock* const pSrcBlock = m_pBlockVector->GetBlock(srcOrigBlockIndex);
- VmaBlockMetadata_Generic* const pSrcMetadata = (VmaBlockMetadata_Generic*)pSrcBlock->m_pMetadata;
- for (VmaSuballocationList::iterator srcSuballocIt = pSrcMetadata->m_Suballocations.begin();
- !end && srcSuballocIt != pSrcMetadata->m_Suballocations.end(); )
- {
- VmaAllocation const pAlloc = (VmaAllocation)srcSuballocIt->userData;
- const VkDeviceSize srcAllocAlignment = pAlloc->GetAlignment();
- const VkDeviceSize srcAllocSize = srcSuballocIt->size;
- if (m_AllocationsMoved == maxAllocationsToMove ||
- m_BytesMoved + srcAllocSize > maxBytesToMove)
- {
- end = true;
- break;
- }
- const VkDeviceSize srcAllocOffset = srcSuballocIt->offset;
-
- VmaDefragmentationMove move = {};
- // Try to place it in one of free spaces from the database.
- size_t freeSpaceInfoIndex;
- VkDeviceSize dstAllocOffset;
- if (freeSpaceDb.Fetch(srcAllocAlignment, srcAllocSize,
- freeSpaceInfoIndex, dstAllocOffset))
- {
- size_t freeSpaceOrigBlockIndex = m_BlockInfos[freeSpaceInfoIndex].origBlockIndex;
- VmaDeviceMemoryBlock* pFreeSpaceBlock = m_pBlockVector->GetBlock(freeSpaceOrigBlockIndex);
- VmaBlockMetadata_Generic* pFreeSpaceMetadata = (VmaBlockMetadata_Generic*)pFreeSpaceBlock->m_pMetadata;
-
- // Same block
- if (freeSpaceInfoIndex == srcBlockInfoIndex)
- {
- VMA_ASSERT(dstAllocOffset <= srcAllocOffset);
-
- // MOVE OPTION 1: Move the allocation inside the same block by decreasing offset.
-
- VmaSuballocation suballoc = *srcSuballocIt;
- suballoc.offset = dstAllocOffset;
- ((VmaAllocation)(suballoc.userData))->ChangeAllocHandle((VmaAllocHandle)(dstAllocOffset + 1));
- m_BytesMoved += srcAllocSize;
- ++m_AllocationsMoved;
-
- VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt;
- ++nextSuballocIt;
- pSrcMetadata->m_Suballocations.erase(srcSuballocIt);
- srcSuballocIt = nextSuballocIt;
-
- InsertSuballoc(pFreeSpaceMetadata, suballoc);
-
- move.srcBlockIndex = srcOrigBlockIndex;
- move.dstBlockIndex = freeSpaceOrigBlockIndex;
- move.srcOffset = srcAllocOffset;
- move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
- move.size = srcAllocSize;
-
- moves.push_back(move);
- }
- // Different block
- else
- {
- // MOVE OPTION 2: Move the allocation to a different block.
-
- VMA_ASSERT(freeSpaceInfoIndex < srcBlockInfoIndex);
-
- VmaSuballocation suballoc = *srcSuballocIt;
- suballoc.offset = dstAllocOffset;
- ((VmaAllocation)(suballoc.userData))->ChangeBlockAllocation(m_hAllocator, pFreeSpaceBlock, (VmaAllocHandle)(dstAllocOffset + 1));
- m_BytesMoved += srcAllocSize;
- ++m_AllocationsMoved;
-
- VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt;
- ++nextSuballocIt;
- pSrcMetadata->m_Suballocations.erase(srcSuballocIt);
- srcSuballocIt = nextSuballocIt;
-
- InsertSuballoc(pFreeSpaceMetadata, suballoc);
-
- move.srcBlockIndex = srcOrigBlockIndex;
- move.dstBlockIndex = freeSpaceOrigBlockIndex;
- move.srcOffset = srcAllocOffset;
- move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
- move.size = srcAllocSize;
-
- moves.push_back(move);
- }
- }
- else
- {
- dstAllocOffset = VmaAlignUp(dstOffset, srcAllocAlignment);
-
- // If the allocation doesn't fit before the end of dstBlock, forward to next block.
- while (dstBlockInfoIndex < srcBlockInfoIndex &&
- dstAllocOffset + srcAllocSize > dstBlockSize)
- {
- // But before that, register remaining free space at the end of dst block.
- freeSpaceDb.Register(dstBlockInfoIndex, dstOffset, dstBlockSize - dstOffset);
-
- ++dstBlockInfoIndex;
- dstOrigBlockIndex = m_BlockInfos[dstBlockInfoIndex].origBlockIndex;
- pDstBlock = m_pBlockVector->GetBlock(dstOrigBlockIndex);
- pDstMetadata = (VmaBlockMetadata_Generic*)pDstBlock->m_pMetadata;
- dstBlockSize = pDstMetadata->GetSize();
- dstOffset = 0;
- dstAllocOffset = 0;
- }
-
- // Same block
- if (dstBlockInfoIndex == srcBlockInfoIndex)
- {
- VMA_ASSERT(dstAllocOffset <= srcAllocOffset);
-
- const bool overlap = dstAllocOffset + srcAllocSize > srcAllocOffset;
-
- bool skipOver = overlap;
- if (overlap && m_OverlappingMoveSupported && dstAllocOffset < srcAllocOffset)
- {
- // If destination and source place overlap, skip if it would move it
- // by only < 1/64 of its size.
- skipOver = (srcAllocOffset - dstAllocOffset) * 64 < srcAllocSize;
- }
-
- if (skipOver)
- {
- freeSpaceDb.Register(dstBlockInfoIndex, dstOffset, srcAllocOffset - dstOffset);
-
- dstOffset = srcAllocOffset + srcAllocSize;
- ++srcSuballocIt;
- }
- // MOVE OPTION 1: Move the allocation inside the same block by decreasing offset.
- else
- {
- srcSuballocIt->offset = dstAllocOffset;
- ((VmaAllocation)(srcSuballocIt->userData))->ChangeAllocHandle((VmaAllocHandle)(dstAllocOffset + 1));
- dstOffset = dstAllocOffset + srcAllocSize;
- m_BytesMoved += srcAllocSize;
- ++m_AllocationsMoved;
- ++srcSuballocIt;
-
- move.srcBlockIndex = srcOrigBlockIndex;
- move.dstBlockIndex = dstOrigBlockIndex;
- move.srcOffset = srcAllocOffset;
- move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
- move.size = srcAllocSize;
-
- moves.push_back(move);
- }
- }
- // Different block
- else
- {
- // MOVE OPTION 2: Move the allocation to a different block.
-
- VMA_ASSERT(dstBlockInfoIndex < srcBlockInfoIndex);
- VMA_ASSERT(dstAllocOffset + srcAllocSize <= dstBlockSize);
-
- VmaSuballocation suballoc = *srcSuballocIt;
- suballoc.offset = dstAllocOffset;
- ((VmaAllocation)(suballoc.userData))->ChangeBlockAllocation(m_hAllocator, pDstBlock, (VmaAllocHandle)(dstAllocOffset + 1));
- dstOffset = dstAllocOffset + srcAllocSize;
- m_BytesMoved += srcAllocSize;
- ++m_AllocationsMoved;
-
- VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt;
- ++nextSuballocIt;
- pSrcMetadata->m_Suballocations.erase(srcSuballocIt);
- srcSuballocIt = nextSuballocIt;
-
- pDstMetadata->m_Suballocations.push_back(suballoc);
-
- move.srcBlockIndex = srcOrigBlockIndex;
- move.dstBlockIndex = dstOrigBlockIndex;
- move.srcOffset = srcAllocOffset;
- move.dstOffset = dstAllocOffset;
- move.dstHandle = (VmaAllocHandle)(dstAllocOffset + 1);
- move.size = srcAllocSize;
-
- moves.push_back(move);
- }
- }
- }
- }
-
- m_BlockInfos.clear();
-
- PostprocessMetadata();
-
- return VK_SUCCESS;
-}
-
-VmaDefragmentationAlgorithm_Fast::FreeSpaceDatabase::FreeSpaceDatabase()
-{
- FreeSpace s = {};
- s.blockInfoIndex = SIZE_MAX;
- for (size_t i = 0; i < MAX_COUNT; ++i)
- {
- m_FreeSpaces[i] = s;
- }
-}
-
-void VmaDefragmentationAlgorithm_Fast::FreeSpaceDatabase::Register(size_t blockInfoIndex, VkDeviceSize offset, VkDeviceSize size)
-{
- // Find first invalid or the smallest structure.
- size_t bestIndex = SIZE_MAX;
- for (size_t i = 0; i < MAX_COUNT; ++i)
- {
- // Empty structure.
- if (m_FreeSpaces[i].blockInfoIndex == SIZE_MAX)
- {
- bestIndex = i;
- break;
- }
- if (m_FreeSpaces[i].size < size &&
- (bestIndex == SIZE_MAX || m_FreeSpaces[bestIndex].size > m_FreeSpaces[i].size))
- {
- bestIndex = i;
- }
- }
-
- if (bestIndex != SIZE_MAX)
- {
- m_FreeSpaces[bestIndex].blockInfoIndex = blockInfoIndex;
- m_FreeSpaces[bestIndex].offset = offset;
- m_FreeSpaces[bestIndex].size = size;
- }
-}
-
-bool VmaDefragmentationAlgorithm_Fast::FreeSpaceDatabase::Fetch(VkDeviceSize alignment, VkDeviceSize size,
- size_t& outBlockInfoIndex, VkDeviceSize& outDstOffset)
-{
- size_t bestIndex = SIZE_MAX;
- VkDeviceSize bestFreeSpaceAfter = 0;
- for (size_t i = 0; i < MAX_COUNT; ++i)
- {
- // Structure is valid.
- if (m_FreeSpaces[i].blockInfoIndex != SIZE_MAX)
- {
- const VkDeviceSize dstOffset = VmaAlignUp(m_FreeSpaces[i].offset, alignment);
- // Allocation fits into this structure.
- if (dstOffset + size <= m_FreeSpaces[i].offset + m_FreeSpaces[i].size)
- {
- const VkDeviceSize freeSpaceAfter = (m_FreeSpaces[i].offset + m_FreeSpaces[i].size) -
- (dstOffset + size);
- if (bestIndex == SIZE_MAX || freeSpaceAfter > bestFreeSpaceAfter)
- {
- bestIndex = i;
- bestFreeSpaceAfter = freeSpaceAfter;
- }
- }
- }
- }
-
- if (bestIndex != SIZE_MAX)
- {
- outBlockInfoIndex = m_FreeSpaces[bestIndex].blockInfoIndex;
- outDstOffset = VmaAlignUp(m_FreeSpaces[bestIndex].offset, alignment);
-
- // Leave this structure for remaining empty space.
- const VkDeviceSize alignmentPlusSize = (outDstOffset - m_FreeSpaces[bestIndex].offset) + size;
- m_FreeSpaces[bestIndex].offset += alignmentPlusSize;
- m_FreeSpaces[bestIndex].size -= alignmentPlusSize;
-
- return true;
- }
-
- return false;
-}
-
-void VmaDefragmentationAlgorithm_Fast::PreprocessMetadata()
-{
- const size_t blockCount = m_pBlockVector->GetBlockCount();
- for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
- {
- VmaBlockMetadata_Generic* const pMetadata =
- (VmaBlockMetadata_Generic*)m_pBlockVector->GetBlock(blockIndex)->m_pMetadata;
- pMetadata->m_FreeCount = 0;
- pMetadata->m_SumFreeSize = pMetadata->GetSize();
- pMetadata->m_FreeSuballocationsBySize.clear();
- for (VmaSuballocationList::iterator it = pMetadata->m_Suballocations.begin();
- it != pMetadata->m_Suballocations.end(); )
- {
- if (it->type == VMA_SUBALLOCATION_TYPE_FREE)
- {
- VmaSuballocationList::iterator nextIt = it;
- ++nextIt;
- pMetadata->m_Suballocations.erase(it);
- it = nextIt;
- }
- else
- {
- ++it;
- }
- }
- }
-}
-
-void VmaDefragmentationAlgorithm_Fast::PostprocessMetadata()
-{
- const size_t blockCount = m_pBlockVector->GetBlockCount();
- for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
- {
- VmaBlockMetadata_Generic* const pMetadata =
- (VmaBlockMetadata_Generic*)m_pBlockVector->GetBlock(blockIndex)->m_pMetadata;
- const VkDeviceSize blockSize = pMetadata->GetSize();
-
- // No allocations in this block - entire area is free.
- if (pMetadata->m_Suballocations.empty())
- {
- pMetadata->m_FreeCount = 1;
- //pMetadata->m_SumFreeSize is already set to blockSize.
- VmaSuballocation suballoc = {
- 0, // offset
- blockSize, // size
- VMA_NULL, // hAllocation
- VMA_SUBALLOCATION_TYPE_FREE };
- pMetadata->m_Suballocations.push_back(suballoc);
- pMetadata->RegisterFreeSuballocation(pMetadata->m_Suballocations.begin());
- }
- // There are some allocations in this block.
- else
- {
- VkDeviceSize offset = 0;
- VmaSuballocationList::iterator it;
- for (it = pMetadata->m_Suballocations.begin();
- it != pMetadata->m_Suballocations.end();
- ++it)
- {
- VMA_ASSERT(it->type != VMA_SUBALLOCATION_TYPE_FREE);
- VMA_ASSERT(it->offset >= offset);
-
- // Need to insert preceding free space.
- if (it->offset > offset)
- {
- ++pMetadata->m_FreeCount;
- const VkDeviceSize freeSize = it->offset - offset;
- VmaSuballocation suballoc = {
- offset, // offset
- freeSize, // size
- VMA_NULL, // hAllocation
- VMA_SUBALLOCATION_TYPE_FREE };
- VmaSuballocationList::iterator precedingFreeIt = pMetadata->m_Suballocations.insert(it, suballoc);
- pMetadata->m_FreeSuballocationsBySize.push_back(precedingFreeIt);
- }
-
- pMetadata->m_SumFreeSize -= it->size;
- offset = it->offset + it->size;
- }
-
- // Need to insert trailing free space.
- if (offset < blockSize)
- {
- ++pMetadata->m_FreeCount;
- const VkDeviceSize freeSize = blockSize - offset;
- VmaSuballocation suballoc = {
- offset, // offset
- freeSize, // size
- VMA_NULL, // hAllocation
- VMA_SUBALLOCATION_TYPE_FREE };
- VMA_ASSERT(it == pMetadata->m_Suballocations.end());
- VmaSuballocationList::iterator trailingFreeIt = pMetadata->m_Suballocations.insert(it, suballoc);
- pMetadata->m_FreeSuballocationsBySize.push_back(trailingFreeIt);
- }
-
- VMA_SORT(
- pMetadata->m_FreeSuballocationsBySize.begin(),
- pMetadata->m_FreeSuballocationsBySize.end(),
- VmaSuballocationItemSizeLess());
- }
-
- VMA_HEAVY_ASSERT(pMetadata->Validate());
- }
-}
-
-void VmaDefragmentationAlgorithm_Fast::InsertSuballoc(VmaBlockMetadata_Generic* pMetadata, const VmaSuballocation& suballoc)
-{
- VmaSuballocationList& suballocs = pMetadata->m_Suballocations;
- VmaSuballocationList::iterator elementAfter;
- const VkDeviceSize last = suballocs.rbegin()->offset;
- const VkDeviceSize first = suballocs.begin()->offset;
-
- if (last <= suballoc.offset)
- elementAfter = suballocs.end();
- else if (first >= suballoc.offset)
- elementAfter = suballocs.begin();
- else
- {
- const size_t suballocCount = suballocs.size();
- const VkDeviceSize step = (last - first + suballocs.begin()->size) / suballocCount;
- // If offset to be inserted is closer to the end of range, search from the end
- if ((suballoc.offset - first) / step > suballocCount / 2)
- {
- elementAfter = suballocs.begin();
- for (VmaSuballocationList::reverse_iterator suballocItem = ++suballocs.rbegin();
- suballocItem != suballocs.rend();
- ++suballocItem)
- {
- if (suballocItem->offset <= suballoc.offset)
- {
- elementAfter = --suballocItem;
- break;
- }
- }
- }
- else
- {
- elementAfter = suballocs.end();
- for (VmaSuballocationList::iterator suballocItem = ++suballocs.begin();
- suballocItem != suballocs.end();
- ++suballocItem)
- {
- if (suballocItem->offset >= suballoc.offset)
- {
- elementAfter = suballocItem;
- break;
- }
- }
- }
- }
- pMetadata->m_Suballocations.insert(elementAfter, suballoc);
-}
-#endif // _VMA_DEFRAGMENTATION_ALGORITHM_FAST_FUNCTIONS
-
-#ifndef _VMA_BLOCK_VECTOR_DEFRAGMENTATION_CONTEXT_FUNCTIONS
-VmaBlockVectorDefragmentationContext::VmaBlockVectorDefragmentationContext(
- VmaAllocator hAllocator,
- VmaPool hCustomPool,
- VmaBlockVector* pBlockVector)
- : res(VK_SUCCESS),
- mutexLocked(false),
- blockContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks())),
- defragmentationMoves(VmaStlAllocator(hAllocator->GetAllocationCallbacks())),
- defragmentationMovesProcessed(0),
- defragmentationMovesCommitted(0),
- hasDefragmentationPlan(0),
- m_hAllocator(hAllocator),
- m_hCustomPool(hCustomPool),
- m_pBlockVector(pBlockVector),
- m_pAlgorithm(VMA_NULL),
- m_Allocations(VmaStlAllocator(hAllocator->GetAllocationCallbacks())),
- m_AllAllocations(false) {}
-
-VmaBlockVectorDefragmentationContext::~VmaBlockVectorDefragmentationContext()
-{
- vma_delete(m_hAllocator, m_pAlgorithm);
-}
-
-void VmaBlockVectorDefragmentationContext::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged)
-{
- AllocInfo info = { hAlloc, pChanged };
- m_Allocations.push_back(info);
-}
-
-void VmaBlockVectorDefragmentationContext::Begin(bool overlappingMoveSupported, VmaDefragmentationFlags flags)
-{
- const bool allAllocations = m_AllAllocations ||
- m_Allocations.size() == m_pBlockVector->CalcAllocationCount();
-
- /********************************
- HERE IS THE CHOICE OF DEFRAGMENTATION ALGORITHM.
- ********************************/
-
- /*
- Fast algorithm is supported only when certain criteria are met:
- - VMA_DEBUG_MARGIN is 0.
- - All allocations in this block vector are movable.
- - There is no possibility of image/buffer granularity conflict.
- - The defragmentation is not incremental
- */
- if (VMA_DEBUG_MARGIN == 0 &&
- allAllocations &&
- !m_pBlockVector->IsBufferImageGranularityConflictPossible() &&
- !(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL))
- {
- m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm_Fast)(
- m_hAllocator, m_pBlockVector, overlappingMoveSupported);
- }
- else
- {
- m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm_Generic)(
- m_hAllocator, m_pBlockVector, overlappingMoveSupported);
- }
-
- if (allAllocations)
- {
- m_pAlgorithm->AddAll();
- }
- else
- {
- for (size_t i = 0, count = m_Allocations.size(); i < count; ++i)
- {
- m_pAlgorithm->AddAllocation(m_Allocations[i].hAlloc, m_Allocations[i].pChanged);
- }
- }
-}
-#endif // _VMA_BLOCK_VECTOR_DEFRAGMENTATION_CONTEXT_FUNCTIONS
-
#ifndef _VMA_DEFRAGMENTATION_CONTEXT_FUNCTIONS
VmaDefragmentationContext_T::VmaDefragmentationContext_T(
VmaAllocator hAllocator,
- uint32_t flags,
- VmaDefragmentationStats* pStats)
- : m_hAllocator(hAllocator),
- m_Flags(flags),
- m_pStats(pStats),
- m_CustomPoolContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks()))
+ const VmaDefragmentationInfo& info)
+ : m_MaxPassBytes(info.maxBytesPerPass == 0 ? VK_WHOLE_SIZE : info.maxBytesPerPass),
+ m_MaxPassAllocations(info.maxAllocationsPerPass == 0 ? UINT32_MAX : info.maxAllocationsPerPass),
+ m_MoveAllocator(hAllocator->GetAllocationCallbacks()),
+ m_Moves(m_MoveAllocator)
{
- memset(m_DefaultPoolContexts, 0, sizeof(m_DefaultPoolContexts));
+ m_Algorithm = info.flags & VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK;
+
+ if (info.pool != VMA_NULL)
+ {
+ m_BlockVectorCount = 1;
+ m_PoolBlockVector = &info.pool->m_BlockVector;
+ m_pBlockVectors = &m_PoolBlockVector;
+ m_PoolBlockVector->SortByFreeSize();
+ }
+ else
+ {
+ m_BlockVectorCount = hAllocator->GetMemoryTypeCount();
+ m_PoolBlockVector = VMA_NULL;
+ m_pBlockVectors = hAllocator->m_pBlockVectors;
+ for (uint32_t i = 0; i < m_BlockVectorCount; ++i)
+ {
+ VmaBlockVector* vector = m_pBlockVectors[i];
+ if (vector != VMA_NULL)
+ vector->SortByFreeSize();
+ }
+ }
+
+ switch (m_Algorithm)
+ {
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
+ {
+ if (hAllocator->GetBufferImageGranularity() > 1)
+ {
+ m_AlgorithmState = vma_new_array(hAllocator, StateExtensive, m_BlockVectorCount);
+ }
+ break;
+ }
+ }
}
VmaDefragmentationContext_T::~VmaDefragmentationContext_T()
{
- for (size_t i = m_CustomPoolContexts.size(); i--; )
+ if (m_AlgorithmState)
{
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[i];
- pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_Flags, m_pStats);
- vma_delete(m_hAllocator, pBlockVectorCtx);
- }
- for (size_t i = m_hAllocator->m_MemProps.memoryTypeCount; i--; )
- {
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[i];
- if (pBlockVectorCtx)
+ switch (m_Algorithm)
{
- pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_Flags, m_pStats);
- vma_delete(m_hAllocator, pBlockVectorCtx);
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
+ vma_delete_array(m_MoveAllocator.m_pCallbacks, reinterpret_cast(m_AlgorithmState), m_BlockVectorCount);
+ break;
+ default:
+ VMA_ASSERT(0);
}
}
}
-void VmaDefragmentationContext_T::AddPools(uint32_t poolCount, const VmaPool* pPools)
+VkResult VmaDefragmentationContext_T::DefragmentPassBegin(VmaDefragmentationPassMoveInfo& moveInfo)
{
- for (uint32_t poolIndex = 0; poolIndex < poolCount; ++poolIndex)
+ if (m_PoolBlockVector != VMA_NULL)
{
- VmaPool pool = pPools[poolIndex];
- VMA_ASSERT(pool);
- // Pools with algorithm other than default are not defragmented.
- if (pool->m_BlockVector.GetAlgorithm() == 0)
+ if (m_PoolBlockVector->GetBlockCount() > 1)
+ ComputeDefragmentation(*m_PoolBlockVector, 0);
+ else if (m_PoolBlockVector->GetBlockCount() == 1)
+ ReallocWithinBlock(*m_PoolBlockVector, m_PoolBlockVector->GetBlock(0));
+ }
+ else
+ {
+ for (uint32_t i = 0; i < m_BlockVectorCount; ++i)
{
- VmaBlockVectorDefragmentationContext* pBlockVectorDefragCtx = VMA_NULL;
-
- for (size_t i = m_CustomPoolContexts.size(); i--; )
+ if (m_pBlockVectors[i] != VMA_NULL)
{
- if (m_CustomPoolContexts[i]->GetCustomPool() == pool)
+ if (m_pBlockVectors[i]->GetBlockCount() > 1)
{
- pBlockVectorDefragCtx = m_CustomPoolContexts[i];
- break;
+ if (ComputeDefragmentation(*m_pBlockVectors[i], i))
+ break;
+ }
+ else if (m_pBlockVectors[i]->GetBlockCount() == 1)
+ {
+ if (ReallocWithinBlock(*m_pBlockVectors[i], m_pBlockVectors[i]->GetBlock(0)))
+ break;
}
}
-
- if (!pBlockVectorDefragCtx)
- {
- pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)(
- m_hAllocator,
- pool,
- &pool->m_BlockVector);
- m_CustomPoolContexts.push_back(pBlockVectorDefragCtx);
- }
-
- pBlockVectorDefragCtx->AddAll();
- }
- }
-}
-
-void VmaDefragmentationContext_T::AddAllocations(
- uint32_t allocationCount,
- const VmaAllocation* pAllocations,
- VkBool32* pAllocationsChanged)
-{
- // Dispatch pAllocations among defragmentators. Create them when necessary.
- for (uint32_t allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
- {
- const VmaAllocation hAlloc = pAllocations[allocIndex];
- VMA_ASSERT(hAlloc);
- // DedicatedAlloc cannot be defragmented.
- if (hAlloc->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK)
- {
- VmaBlockVectorDefragmentationContext* pBlockVectorDefragCtx = VMA_NULL;
-
- const VmaPool hAllocPool = hAlloc->GetBlock()->GetParentPool();
- // This allocation belongs to custom pool.
- if (hAllocPool != VK_NULL_HANDLE)
- {
- // Pools with algorithm other than default are not defragmented.
- if (hAllocPool->m_BlockVector.GetAlgorithm() == 0)
- {
- for (size_t i = m_CustomPoolContexts.size(); i--; )
- {
- if (m_CustomPoolContexts[i]->GetCustomPool() == hAllocPool)
- {
- pBlockVectorDefragCtx = m_CustomPoolContexts[i];
- break;
- }
- }
- if (!pBlockVectorDefragCtx)
- {
- pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)(
- m_hAllocator,
- hAllocPool,
- &hAllocPool->m_BlockVector);
- m_CustomPoolContexts.push_back(pBlockVectorDefragCtx);
- }
- }
- }
- // This allocation belongs to default pool.
- else
- {
- const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex();
- pBlockVectorDefragCtx = m_DefaultPoolContexts[memTypeIndex];
- if (!pBlockVectorDefragCtx)
- {
- VMA_ASSERT(m_hAllocator->m_pBlockVectors[memTypeIndex] && "Trying to use unsupported memory type!");
-
- pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)(
- m_hAllocator,
- VMA_NULL, // hCustomPool
- m_hAllocator->m_pBlockVectors[memTypeIndex]);
- m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx;
- }
- }
-
- if (pBlockVectorDefragCtx)
- {
- VkBool32* const pChanged = (pAllocationsChanged != VMA_NULL) ?
- &pAllocationsChanged[allocIndex] : VMA_NULL;
- pBlockVectorDefragCtx->AddAllocation(hAlloc, pChanged);
- }
- }
- }
-}
-
-VkResult VmaDefragmentationContext_T::Defragment(
- VkDeviceSize maxCpuBytesToMove, uint32_t maxCpuAllocationsToMove,
- VkDeviceSize maxGpuBytesToMove, uint32_t maxGpuAllocationsToMove,
- VkCommandBuffer commandBuffer, VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags)
-{
- if (pStats)
- {
- memset(pStats, 0, sizeof(VmaDefragmentationStats));
- }
-
- if (flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)
- {
- // For incremental defragmetnations, we just earmark how much we can move
- // The real meat is in the defragmentation steps
- m_MaxCpuBytesToMove = maxCpuBytesToMove;
- m_MaxCpuAllocationsToMove = maxCpuAllocationsToMove;
-
- m_MaxGpuBytesToMove = maxGpuBytesToMove;
- m_MaxGpuAllocationsToMove = maxGpuAllocationsToMove;
-
- if (m_MaxCpuBytesToMove == 0 && m_MaxCpuAllocationsToMove == 0 &&
- m_MaxGpuBytesToMove == 0 && m_MaxGpuAllocationsToMove == 0)
- return VK_SUCCESS;
-
- return VK_NOT_READY;
- }
-
- if (commandBuffer == VK_NULL_HANDLE)
- {
- maxGpuBytesToMove = 0;
- maxGpuAllocationsToMove = 0;
- }
-
- VkResult res = VK_SUCCESS;
-
- // Process default pools.
- for (uint32_t memTypeIndex = 0;
- memTypeIndex < m_hAllocator->GetMemoryTypeCount() && res >= VK_SUCCESS;
- ++memTypeIndex)
- {
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex];
- if (pBlockVectorCtx)
- {
- VMA_ASSERT(pBlockVectorCtx->GetBlockVector());
- pBlockVectorCtx->GetBlockVector()->Defragment(
- pBlockVectorCtx,
- pStats, flags,
- maxCpuBytesToMove, maxCpuAllocationsToMove,
- maxGpuBytesToMove, maxGpuAllocationsToMove,
- commandBuffer);
- if (pBlockVectorCtx->res != VK_SUCCESS)
- {
- res = pBlockVectorCtx->res;
- }
}
}
- // Process custom pools.
- for (size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size();
- customCtxIndex < customCtxCount && res >= VK_SUCCESS;
- ++customCtxIndex)
+ moveInfo.moveCount = static_cast(m_Moves.size());
+ if (moveInfo.moveCount > 0)
{
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex];
- VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector());
- pBlockVectorCtx->GetBlockVector()->Defragment(
- pBlockVectorCtx,
- pStats, flags,
- maxCpuBytesToMove, maxCpuAllocationsToMove,
- maxGpuBytesToMove, maxGpuAllocationsToMove,
- commandBuffer);
- if (pBlockVectorCtx->res != VK_SUCCESS)
- {
- res = pBlockVectorCtx->res;
- }
+ moveInfo.pMoves = m_Moves.data();
+ return VK_INCOMPLETE;
}
- return res;
-}
-
-VkResult VmaDefragmentationContext_T::DefragmentPassBegin(VmaDefragmentationPassInfo* pInfo)
-{
- VmaDefragmentationPassMoveInfo* pCurrentMove = pInfo->pMoves;
- uint32_t movesLeft = pInfo->moveCount;
-
- // Process default pools.
- for (uint32_t memTypeIndex = 0;
- memTypeIndex < m_hAllocator->GetMemoryTypeCount();
- ++memTypeIndex)
- {
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex];
- if (pBlockVectorCtx)
- {
- VMA_ASSERT(pBlockVectorCtx->GetBlockVector());
-
- if (!pBlockVectorCtx->hasDefragmentationPlan)
- {
- pBlockVectorCtx->GetBlockVector()->Defragment(
- pBlockVectorCtx,
- m_pStats, m_Flags,
- m_MaxCpuBytesToMove, m_MaxCpuAllocationsToMove,
- m_MaxGpuBytesToMove, m_MaxGpuAllocationsToMove,
- VK_NULL_HANDLE);
-
- if (pBlockVectorCtx->res < VK_SUCCESS)
- continue;
-
- pBlockVectorCtx->hasDefragmentationPlan = true;
- }
-
- const uint32_t processed = pBlockVectorCtx->GetBlockVector()->ProcessDefragmentations(
- pBlockVectorCtx,
- pCurrentMove, movesLeft);
-
- movesLeft -= processed;
- pCurrentMove += processed;
- }
- }
-
- // Process custom pools.
- for (size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size();
- customCtxIndex < customCtxCount;
- ++customCtxIndex)
- {
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex];
- VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector());
-
- if (!pBlockVectorCtx->hasDefragmentationPlan)
- {
- pBlockVectorCtx->GetBlockVector()->Defragment(
- pBlockVectorCtx,
- m_pStats, m_Flags,
- m_MaxCpuBytesToMove, m_MaxCpuAllocationsToMove,
- m_MaxGpuBytesToMove, m_MaxGpuAllocationsToMove,
- VK_NULL_HANDLE);
-
- if (pBlockVectorCtx->res < VK_SUCCESS)
- continue;
-
- pBlockVectorCtx->hasDefragmentationPlan = true;
- }
-
- const uint32_t processed = pBlockVectorCtx->GetBlockVector()->ProcessDefragmentations(
- pBlockVectorCtx,
- pCurrentMove, movesLeft);
-
- movesLeft -= processed;
- pCurrentMove += processed;
- }
-
- pInfo->moveCount = pInfo->moveCount - movesLeft;
-
+ moveInfo.pMoves = VMA_NULL;
return VK_SUCCESS;
}
-VkResult VmaDefragmentationContext_T::DefragmentPassEnd()
+VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMoveInfo& moveInfo)
{
- VkResult res = VK_SUCCESS;
+ VMA_ASSERT(moveInfo.moveCount > 0 ? moveInfo.pMoves != VMA_NULL : true);
- // Process default pools.
- for (uint32_t memTypeIndex = 0;
- memTypeIndex < m_hAllocator->GetMemoryTypeCount();
- ++memTypeIndex)
+ VkResult result = VK_SUCCESS;
+ VmaVector> immovableBlocks({ m_MoveAllocator.m_pCallbacks });
+ for (uint32_t i = 0; i < moveInfo.moveCount; ++i)
{
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex];
- if (pBlockVectorCtx)
- {
- VMA_ASSERT(pBlockVectorCtx->GetBlockVector());
+ VmaDefragmentationMove& move = moveInfo.pMoves[i];
+ size_t prevCount = 0, currentCount = 0;
+ VkDeviceSize freedBlockSize = 0;
- if (!pBlockVectorCtx->hasDefragmentationPlan)
+ uint32_t vectorIndex;
+ VmaBlockVector* vector;
+ if (m_PoolBlockVector != VMA_NULL)
+ {
+ vectorIndex = 0;
+ vector = m_PoolBlockVector;
+ }
+ else
+ {
+ vectorIndex = move.srcAllocation->GetMemoryTypeIndex();
+ vector = m_pBlockVectors[vectorIndex];
+ VMA_ASSERT(vector != VMA_NULL);
+ }
+
+ VmaAllocation dst = reinterpret_cast(move.internalData);
+ switch (move.operation)
+ {
+ case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY:
+ {
+ move.srcAllocation->SwapBlockAllocation(dst);
+ prevCount = vector->GetBlockCount();
+ freedBlockSize = dst->GetBlock()->m_pMetadata->GetSize();
+ vector->Free(dst, false);
+ currentCount = vector->GetBlockCount();
+
+ result = VK_INCOMPLETE;
+ break;
+ }
+ case VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE:
+ {
+ m_Stats.bytesMoved -= move.srcAllocation->GetSize();
+ vector->Free(dst, false);
+
+ VmaDeviceMemoryBlock* newBlock = move.srcAllocation->GetBlock();
+ bool notPresent = true;
+ for (const ImmovableBlock& block : immovableBlocks)
{
- res = VK_NOT_READY;
+ if (block.block == newBlock)
+ {
+ notPresent = false;
+ break;
+ }
+ }
+ if (notPresent)
+ immovableBlocks.push_back({ vectorIndex, newBlock });
+ break;
+ }
+ case VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY:
+ {
+ prevCount = vector->GetBlockCount();
+ freedBlockSize = move.srcAllocation->GetBlock()->m_pMetadata->GetSize();
+ vector->Free(move.srcAllocation, false);
+ currentCount = vector->GetBlockCount();
+ freedBlockSize *= prevCount - currentCount;
+
+ VkDeviceSize dstBlockSize = dst->GetBlock()->m_pMetadata->GetSize();
+ vector->Free(dst, false);
+ freedBlockSize += dstBlockSize * (currentCount - vector->GetBlockCount());
+ currentCount = vector->GetBlockCount();
+
+ result = VK_INCOMPLETE;
+ break;
+ }
+ default:
+ VMA_ASSERT(0);
+ }
+
+ if (prevCount > currentCount)
+ {
+ size_t freedBlocks = prevCount - currentCount;
+ m_Stats.deviceMemoryBlocksFreed += static_cast(freedBlocks);
+ m_Stats.bytesFreed += freedBlockSize;
+ }
+
+ switch (m_Algorithm)
+ {
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
+ {
+ if (m_AlgorithmState != VMA_NULL)
+ {
+ // Avoid unnecessary tries to allocate when new free block is avaiable
+ StateExtensive& state = reinterpret_cast(m_AlgorithmState)[vectorIndex];
+ if (state.firstFreeBlock != SIZE_MAX)
+ {
+ state.firstFreeBlock -= prevCount - currentCount;
+ if (state.firstFreeBlock != 0)
+ state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty();
+ }
+ }
+ }
+ }
+ }
+ moveInfo.moveCount = 0;
+ moveInfo.pMoves = VMA_NULL;
+ m_Moves.clear();
+
+ // Move blocks with immovable allocations according to algorithm
+ if (immovableBlocks.size() > 0)
+ {
+ switch (m_Algorithm)
+ {
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
+ {
+ if (m_AlgorithmState != VMA_NULL)
+ {
+ bool swapped = false;
+ // Move to the start of free blocks range
+ for (const ImmovableBlock& block : immovableBlocks)
+ {
+ StateExtensive& state = reinterpret_cast(m_AlgorithmState)[block.vectorIndex];
+ if (state.operation != StateExtensive::Operation::Cleanup)
+ {
+ VmaBlockVector* vector = m_pBlockVectors[block.vectorIndex];
+ for (size_t i = 0, count = vector->GetBlockCount() - m_ImmovableBlockCount; i < count; ++i)
+ {
+ if (vector->GetBlock(i) == block.block)
+ {
+ VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[vector->GetBlockCount() - ++m_ImmovableBlockCount]);
+ if (state.firstFreeBlock != SIZE_MAX)
+ {
+ if (i < state.firstFreeBlock - 1)
+ {
+ VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[--state.firstFreeBlock]);
+ }
+ }
+ swapped = true;
+ break;
+ }
+ }
+ }
+ }
+ if (swapped)
+ result = VK_INCOMPLETE;
+ break;
+ }
+ }
+ default:
+ {
+ // Move to the begining
+ for (const ImmovableBlock& block : immovableBlocks)
+ {
+ VmaBlockVector* vector = m_pBlockVectors[block.vectorIndex];
+ for (size_t i = m_ImmovableBlockCount; vector->GetBlockCount(); ++i)
+ {
+ if (vector->GetBlock(i) == block.block)
+ {
+ VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[m_ImmovableBlockCount++]);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+bool VmaDefragmentationContext_T::ComputeDefragmentation(VmaBlockVector& vector, size_t index)
+{
+ switch (m_Algorithm)
+ {
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT:
+ return ComputeDefragmentation_Fast(vector);
+ default: // Default algoritm
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT:
+ return ComputeDefragmentation_Balanced(vector);
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT:
+ return ComputeDefragmentation_Full(vector);
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
+ return ComputeDefragmentation_Extensive(vector, index);
+ }
+}
+
+VmaDefragmentationContext_T::MoveAllocationData VmaDefragmentationContext_T::GetMoveData(
+ VmaAllocHandle handle, VmaBlockMetadata* metadata)
+{
+ MoveAllocationData moveData;
+ moveData.move.srcAllocation = (VmaAllocation)metadata->GetAllocationUserData(handle);
+ moveData.size = moveData.move.srcAllocation->GetSize();
+ moveData.alignment = moveData.move.srcAllocation->GetAlignment();
+ moveData.type = moveData.move.srcAllocation->GetSuballocationType();
+ moveData.flags = 0;
+
+ if (moveData.move.srcAllocation->IsPersistentMap())
+ moveData.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
+ if (moveData.move.srcAllocation->IsMappingAllowed())
+ moveData.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
+
+ return moveData;
+}
+
+bool VmaDefragmentationContext_T::IncrementCounters(uint32_t& allocations, VkDeviceSize bytes)
+{
+ if (++allocations >= m_MaxPassAllocations || bytes >= m_MaxPassBytes)
+ {
+ m_Stats.bytesMoved += bytes;
+ m_Stats.allocationsMoved += allocations;
+ return true;
+ }
+ return false;
+}
+
+bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, VmaDeviceMemoryBlock* block)
+{
+ VkDeviceSize currentBytesMoved = 0;
+ uint32_t currentAllocsMoved = 0;
+ VmaBlockMetadata* metadata = block->m_pMetadata;
+
+ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
+ handle != VK_NULL_HANDLE;
+ handle = metadata->GetNextAllocation(handle))
+ {
+ MoveAllocationData moveData = GetMoveData(handle, metadata);
+ // Ignore newly created allocations by defragmentation algorithm
+ if (moveData.move.srcAllocation->GetUserData() == this)
+ continue;
+ VmaAllocation& dst = reinterpret_cast(moveData.move.internalData);
+
+ VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
+ if (offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
+ {
+ VmaAllocationRequest request = {};
+ if (metadata->CreateAllocationRequest(
+ moveData.size,
+ moveData.alignment,
+ false,
+ moveData.type,
+ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
+ &request))
+ {
+ if (metadata->GetAllocationOffset(request.allocHandle) < offset)
+ {
+ if (vector.CommitAllocationRequest(
+ request,
+ block,
+ moveData.alignment,
+ moveData.flags,
+ this,
+ moveData.type,
+ &dst) == VK_SUCCESS)
+ {
+ moveData.move.dstMemory = dst->GetMemory();
+ moveData.move.dstOffset = dst->GetOffset();
+ m_Moves.push_back(moveData.move);
+ currentBytesMoved += moveData.size;
+
+ if (IncrementCounters(currentAllocsMoved, currentBytesMoved))
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ m_Stats.bytesMoved += currentBytesMoved;
+ m_Stats.allocationsMoved += currentAllocsMoved;
+ return false;
+}
+
+bool VmaDefragmentationContext_T::AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector)
+{
+ VkDeviceSize currentBytesMoved = 0;
+ uint32_t currentAllocsMoved = 0;
+ VmaAllocation& dst = reinterpret_cast(data.move.internalData);
+
+ for (; start < end; ++start)
+ {
+ VmaDeviceMemoryBlock* dstBlock = vector.GetBlock(start);
+ if (dstBlock->m_pMetadata->GetSumFreeSize() >= data.size)
+ {
+ if (vector.AllocateFromBlock(dstBlock,
+ data.size,
+ data.alignment,
+ data.flags,
+ this,
+ data.type,
+ 0,
+ &dst) == VK_SUCCESS)
+ {
+ data.move.dstMemory = dst->GetMemory();
+ data.move.dstOffset = dst->GetOffset();
+ m_Moves.push_back(data.move);
+ currentBytesMoved += data.size;
+
+ if (IncrementCounters(currentAllocsMoved, currentBytesMoved))
+ return true;
+ break;
+ }
+ }
+ }
+
+ m_Stats.bytesMoved += currentBytesMoved;
+ m_Stats.allocationsMoved += currentAllocsMoved;
+ return false;
+}
+
+bool VmaDefragmentationContext_T::ComputeDefragmentation_Fast(VmaBlockVector& vector)
+{
+ // Move only between blocks
+
+ // Go through allocations in last blocks and try to fit them inside first ones
+ for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i)
+ {
+ VmaBlockMetadata* metadata = vector.GetBlock(i)->m_pMetadata;
+
+ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
+ handle != VK_NULL_HANDLE;
+ handle = metadata->GetNextAllocation(handle))
+ {
+ MoveAllocationData moveData = GetMoveData(handle, metadata);
+ // Ignore newly created allocations by defragmentation algorithm
+ if (moveData.move.srcAllocation->GetUserData() == this)
continue;
+
+ // Check all previous blocks for free space
+ if (AllocInOtherBlock(0, i, moveData, vector))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool VmaDefragmentationContext_T::ComputeDefragmentation_Balanced(VmaBlockVector& vector)
+{
+ // Go over every allocation and try to fit it in previous blocks at lowest offsets,
+ // if not possible: realloc within single block to minimize offset (exclude offset == 0),
+ // but only if there are noticable gaps between them (some heuristic, ex. average size of allocation in block)
+
+ VkDeviceSize currentBytesMoved = 0;
+ uint32_t currentAllocsMoved = 0;
+
+ for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i)
+ {
+ VmaDeviceMemoryBlock* block = vector.GetBlock(i);
+ VmaBlockMetadata* metadata = block->m_pMetadata;
+
+ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
+ handle != VK_NULL_HANDLE;
+ handle = metadata->GetNextAllocation(handle))
+ {
+ MoveAllocationData moveData = GetMoveData(handle, metadata);
+ // Ignore newly created allocations by defragmentation algorithm
+ if (moveData.move.srcAllocation->GetUserData() == this)
+ continue;
+
+ // Check all previous blocks for free space
+ const size_t prevMoveCount = m_Moves.size();
+ if (AllocInOtherBlock(0, i, moveData, vector))
+ return true;
+
+ // If no room found then realloc within block for lower offset
+ VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
+ if (prevMoveCount == m_Moves.size() && offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
+ {
+ VmaAllocationRequest request = {};
+ if (metadata->CreateAllocationRequest(
+ moveData.size,
+ moveData.alignment,
+ false,
+ moveData.type,
+ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
+ &request))
+ {
+ if (metadata->GetAllocationOffset(request.allocHandle) < offset)
+ {
+ VmaAllocation& dst = reinterpret_cast(moveData.move.internalData);
+ if (vector.CommitAllocationRequest(
+ request,
+ block,
+ moveData.alignment,
+ moveData.flags,
+ this,
+ moveData.type,
+ &dst) == VK_SUCCESS)
+ {
+ moveData.move.dstMemory = dst->GetMemory();
+ moveData.move.dstOffset = dst->GetOffset();
+ m_Moves.push_back(moveData.move);
+ currentBytesMoved += moveData.size;
+
+ if (IncrementCounters(currentAllocsMoved, currentBytesMoved))
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ m_Stats.bytesMoved += currentBytesMoved;
+ m_Stats.allocationsMoved += currentAllocsMoved;
+ return false;
+}
+
+bool VmaDefragmentationContext_T::ComputeDefragmentation_Full(VmaBlockVector& vector)
+{
+ // Go over every allocation and try to fit it in previous blocks at lowest offsets,
+ // if not possible: realloc within single block to minimize offset (exclude offset == 0)
+
+ VkDeviceSize currentBytesMoved = 0;
+ uint32_t currentAllocsMoved = 0;
+
+ for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i)
+ {
+ VmaDeviceMemoryBlock* block = vector.GetBlock(i);
+ VmaBlockMetadata* metadata = block->m_pMetadata;
+
+ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
+ handle != VK_NULL_HANDLE;
+ handle = metadata->GetNextAllocation(handle))
+ {
+ MoveAllocationData moveData = GetMoveData(handle, metadata);
+ // Ignore newly created allocations by defragmentation algorithm
+ if (moveData.move.srcAllocation->GetUserData() == this)
+ continue;
+
+ // Check all previous blocks for free space
+ const size_t prevMoveCount = m_Moves.size();
+ if (AllocInOtherBlock(0, i, moveData, vector))
+ return true;
+
+ // If no room found then realloc within block for lower offset
+ VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
+ if (prevMoveCount == m_Moves.size() && offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
+ {
+ VmaAllocationRequest request = {};
+ if (metadata->CreateAllocationRequest(
+ moveData.size,
+ moveData.alignment,
+ false,
+ moveData.type,
+ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
+ &request))
+ {
+ if (metadata->GetAllocationOffset(request.allocHandle) < offset)
+ {
+ VmaAllocation& dst = reinterpret_cast(moveData.move.internalData);
+ if (vector.CommitAllocationRequest(
+ request,
+ block,
+ moveData.alignment,
+ moveData.flags,
+ this,
+ moveData.type,
+ &dst) == VK_SUCCESS)
+ {
+ moveData.move.dstMemory = dst->GetMemory();
+ moveData.move.dstOffset = dst->GetOffset();
+ m_Moves.push_back(moveData.move);
+ currentBytesMoved += moveData.size;
+
+ if (IncrementCounters(currentAllocsMoved, currentBytesMoved))
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ m_Stats.bytesMoved += currentBytesMoved;
+ m_Stats.allocationsMoved += currentAllocsMoved;
+ return false;
+}
+
+bool VmaDefragmentationContext_T::ComputeDefragmentation_Extensive(VmaBlockVector& vector, size_t index)
+{
+ // First free single block, then populate it to the brim, then free another block, and so on
+
+ // Fallback to previous algorithm since without granularity conflicts it can achieve max packing
+ if (vector.m_BufferImageGranularity == 1)
+ return ComputeDefragmentation_Full(vector);
+
+ VMA_ASSERT(m_AlgorithmState != VMA_NULL);
+
+ StateExtensive& vectorState = reinterpret_cast(m_AlgorithmState)[index];
+
+ bool texturePresent = false, bufferPresent = false, otherPresent = false;
+ switch (vectorState.operation)
+ {
+ case StateExtensive::Operation::Done: // Vector defragmented
+ return false;
+ case StateExtensive::Operation::FindFreeBlockBuffer:
+ case StateExtensive::Operation::FindFreeBlockTexture:
+ case StateExtensive::Operation::FindFreeBlockAll:
+ {
+ // No free blocks, have to clear last one
+ size_t last = (vectorState.firstFreeBlock == SIZE_MAX ? vector.GetBlockCount() : vectorState.firstFreeBlock) - 1;
+ VmaBlockMetadata* freeMetadata = vector.GetBlock(last)->m_pMetadata;
+
+ const size_t prevMoveCount = m_Moves.size();
+ for (VmaAllocHandle handle = freeMetadata->GetAllocationListBegin();
+ handle != VK_NULL_HANDLE;
+ handle = freeMetadata->GetNextAllocation(handle))
+ {
+ MoveAllocationData moveData = GetMoveData(handle, freeMetadata);
+
+ // Check all previous blocks for free space
+ if (AllocInOtherBlock(0, last, moveData, vector))
+ {
+ // Full clear performed already
+ if (prevMoveCount != m_Moves.size() && freeMetadata->GetNextAllocation(handle) == VK_NULL_HANDLE)
+ reinterpret_cast(m_AlgorithmState)[index] = last;
+ return true;
+ }
+ }
+
+ if (prevMoveCount == m_Moves.size())
+ {
+ // Cannot perform full clear, have to move data in other blocks around
+ if (last != 0)
+ {
+ for (size_t i = last - 1; i; --i)
+ {
+ if (ReallocWithinBlock(vector, vector.GetBlock(i)))
+ return true;
+ }
}
- pBlockVectorCtx->GetBlockVector()->CommitDefragmentations(
- pBlockVectorCtx, m_pStats);
-
- if (pBlockVectorCtx->defragmentationMoves.size() != pBlockVectorCtx->defragmentationMovesCommitted)
- res = VK_NOT_READY;
+ if (prevMoveCount == m_Moves.size())
+ {
+ // No possible reallocs within blocks, try to move them around fast
+ return ComputeDefragmentation_Fast(vector);
+ }
}
- }
-
- // Process custom pools.
- for (size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size();
- customCtxIndex < customCtxCount;
- ++customCtxIndex)
- {
- VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex];
- VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector());
-
- if (!pBlockVectorCtx->hasDefragmentationPlan)
+ else
{
- res = VK_NOT_READY;
- continue;
+ switch (vectorState.operation)
+ {
+ case StateExtensive::Operation::FindFreeBlockBuffer:
+ vectorState.operation = StateExtensive::Operation::MoveBuffers;
+ break;
+ default:
+ VMA_ASSERT(0);
+ case StateExtensive::Operation::FindFreeBlockTexture:
+ vectorState.operation = StateExtensive::Operation::MoveTextures;
+ break;
+ case StateExtensive::Operation::FindFreeBlockAll:
+ vectorState.operation = StateExtensive::Operation::MoveAll;
+ break;
+ }
+ vectorState.firstFreeBlock = last;
+ // Nothing done, block found without reallocations, can perform another reallocs in same pass
+ if (prevMoveCount == m_Moves.size())
+ return ComputeDefragmentation_Extensive(vector, index);
}
+ break;
+ }
+ case StateExtensive::Operation::MoveTextures:
+ {
+ if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL, vector,
+ vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent))
+ {
+ if (texturePresent)
+ {
+ vectorState.operation = StateExtensive::Operation::FindFreeBlockTexture;
+ return ComputeDefragmentation_Extensive(vector, index);
+ }
- pBlockVectorCtx->GetBlockVector()->CommitDefragmentations(
- pBlockVectorCtx, m_pStats);
+ if (!bufferPresent && !otherPresent)
+ {
+ vectorState.operation = StateExtensive::Operation::Cleanup;
+ break;
+ }
- if (pBlockVectorCtx->defragmentationMoves.size() != pBlockVectorCtx->defragmentationMovesCommitted)
- res = VK_NOT_READY;
+ // No more textures to move, check buffers
+ vectorState.operation = StateExtensive::Operation::MoveBuffers;
+ bufferPresent = false;
+ otherPresent = false;
+ }
+ else
+ break;
+ }
+ case StateExtensive::Operation::MoveBuffers:
+ {
+ if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_BUFFER, vector,
+ vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent))
+ {
+ if (bufferPresent)
+ {
+ vectorState.operation = StateExtensive::Operation::FindFreeBlockBuffer;
+ return ComputeDefragmentation_Extensive(vector, index);
+ }
+
+ if (!otherPresent)
+ {
+ vectorState.operation = StateExtensive::Operation::Cleanup;
+ break;
+ }
+
+ // No more buffers to move, check all others
+ vectorState.operation = StateExtensive::Operation::MoveAll;
+ otherPresent = false;
+ }
+ else
+ break;
+ }
+ case StateExtensive::Operation::MoveAll:
+ {
+ if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_FREE, vector,
+ vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent))
+ {
+ if (otherPresent)
+ {
+ vectorState.operation = StateExtensive::Operation::FindFreeBlockBuffer;
+ return ComputeDefragmentation_Extensive(vector, index);
+ }
+ // Everything moved
+ vectorState.operation = StateExtensive::Operation::Cleanup;
+ }
+ break;
+ }
}
- return res;
+ if (vectorState.operation == StateExtensive::Operation::Cleanup)
+ {
+ // All other work done, pack data in blocks even tighter if possible
+ const size_t prevMoveCount = m_Moves.size();
+ for (size_t i = 0; i < vector.GetBlockCount(); ++i)
+ {
+ if (ReallocWithinBlock(vector, vector.GetBlock(i)))
+ return true;
+ }
+
+ if (prevMoveCount == m_Moves.size())
+ vectorState.operation = StateExtensive::Operation::Done;
+ }
+ return false;
+}
+
+bool VmaDefragmentationContext_T::MoveDataToFreeBlocks(VmaSuballocationType currentType,
+ VmaBlockVector& vector, size_t firstFreeBlock,
+ bool& texturePresent, bool& bufferPresent, bool& otherPresent)
+{
+ const size_t prevMoveCount = m_Moves.size();
+ for (size_t i = firstFreeBlock ; i;)
+ {
+ VmaDeviceMemoryBlock* block = vector.GetBlock(--i);
+ VmaBlockMetadata* metadata = block->m_pMetadata;
+
+ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
+ handle != VK_NULL_HANDLE;
+ handle = metadata->GetNextAllocation(handle))
+ {
+ MoveAllocationData moveData = GetMoveData(handle, metadata);
+ // Ignore newly created allocations by defragmentation algorithm
+ if (moveData.move.srcAllocation->GetUserData() == this)
+ continue;
+
+ // Move only single type of resources at once
+ if (!VmaIsBufferImageGranularityConflict(moveData.type, currentType))
+ {
+ // Try to fit allocation into free blocks
+ if (AllocInOtherBlock(firstFreeBlock, vector.GetBlockCount(), moveData, vector))
+ return false;
+ }
+
+ if (!VmaIsBufferImageGranularityConflict(moveData.type, VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL))
+ texturePresent = true;
+ else if (!VmaIsBufferImageGranularityConflict(moveData.type, VMA_SUBALLOCATION_TYPE_BUFFER))
+ bufferPresent = true;
+ else
+ otherPresent = true;
+ }
+ }
+ return prevMoveCount == m_Moves.size();
}
#endif // _VMA_DEFRAGMENTATION_CONTEXT_FUNCTIONS
@@ -16142,57 +14990,6 @@ void VmaAllocator_T::GetHeapBudgets(VmaBudget* outBudgets, uint32_t firstHeap, u
}
}
-VkResult VmaAllocator_T::DefragmentationBegin(
- const VmaDefragmentationInfo2& info,
- VmaDefragmentationStats* pStats,
- VmaDefragmentationContext* pContext)
-{
- if(info.pAllocationsChanged != VMA_NULL)
- {
- memset(info.pAllocationsChanged, 0, info.allocationCount * sizeof(VkBool32));
- }
-
- *pContext = vma_new(this, VmaDefragmentationContext_T)(
- this, info.flags, pStats);
-
- (*pContext)->AddPools(info.poolCount, info.pPools);
- (*pContext)->AddAllocations(
- info.allocationCount, info.pAllocations, info.pAllocationsChanged);
-
- VkResult res = (*pContext)->Defragment(
- info.maxCpuBytesToMove, info.maxCpuAllocationsToMove,
- info.maxGpuBytesToMove, info.maxGpuAllocationsToMove,
- info.commandBuffer, pStats, info.flags);
-
- if(res != VK_NOT_READY)
- {
- vma_delete(this, *pContext);
- *pContext = VMA_NULL;
- }
-
- return res;
-}
-
-VkResult VmaAllocator_T::DefragmentationEnd(
- VmaDefragmentationContext context)
-{
- vma_delete(this, context);
- return VK_SUCCESS;
-}
-
-VkResult VmaAllocator_T::DefragmentationPassBegin(
- VmaDefragmentationPassInfo* pInfo,
- VmaDefragmentationContext context)
-{
- return context->DefragmentPassBegin(pInfo);
-}
-
-VkResult VmaAllocator_T::DefragmentationPassEnd(
- VmaDefragmentationContext context)
-{
- return context->DefragmentPassEnd();
-}
-
void VmaAllocator_T::GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo)
{
pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex();
@@ -17762,123 +16559,64 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(
return allocator->CheckCorruption(memoryTypeBits);
}
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragment(
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentation(
VmaAllocator allocator,
- const VmaAllocation* pAllocations,
- size_t allocationCount,
- VkBool32* pAllocationsChanged,
- const VmaDefragmentationInfo *pDefragmentationInfo,
- VmaDefragmentationStats* pDefragmentationStats)
-{
- // Deprecated interface, reimplemented using new one.
-
- VmaDefragmentationInfo2 info2 = {};
- info2.allocationCount = (uint32_t)allocationCount;
- info2.pAllocations = pAllocations;
- info2.pAllocationsChanged = pAllocationsChanged;
- if(pDefragmentationInfo != VMA_NULL)
- {
- info2.maxCpuAllocationsToMove = pDefragmentationInfo->maxAllocationsToMove;
- info2.maxCpuBytesToMove = pDefragmentationInfo->maxBytesToMove;
- }
- else
- {
- info2.maxCpuAllocationsToMove = UINT32_MAX;
- info2.maxCpuBytesToMove = VK_WHOLE_SIZE;
- }
- // info2.flags, maxGpuAllocationsToMove, maxGpuBytesToMove, commandBuffer deliberately left zero.
-
- VmaDefragmentationContext ctx;
- VkResult res = vmaDefragmentationBegin(allocator, &info2, pDefragmentationStats, &ctx);
- if(res == VK_NOT_READY)
- {
- res = vmaDefragmentationEnd( allocator, ctx);
- }
- return res;
-}
-
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationBegin(
- VmaAllocator allocator,
- const VmaDefragmentationInfo2* pInfo,
- VmaDefragmentationStats* pStats,
- VmaDefragmentationContext *pContext)
+ const VmaDefragmentationInfo* pInfo,
+ VmaDefragmentationContext* pContext)
{
VMA_ASSERT(allocator && pInfo && pContext);
- // Degenerate case: Nothing to defragment.
- if(pInfo->allocationCount == 0 && pInfo->poolCount == 0)
- {
- return VK_SUCCESS;
- }
-
- VMA_ASSERT(pInfo->allocationCount == 0 || pInfo->pAllocations != VMA_NULL);
- VMA_ASSERT(pInfo->poolCount == 0 || pInfo->pPools != VMA_NULL);
- VMA_HEAVY_ASSERT(VmaValidatePointerArray(pInfo->allocationCount, pInfo->pAllocations));
- VMA_HEAVY_ASSERT(VmaValidatePointerArray(pInfo->poolCount, pInfo->pPools));
-
- VMA_DEBUG_LOG("vmaDefragmentationBegin");
+ VMA_DEBUG_LOG("vmaBeginDefragmentation");
VMA_DEBUG_GLOBAL_MUTEX_LOCK
- VkResult res = allocator->DefragmentationBegin(*pInfo, pStats, pContext);
-
- return res;
+ *pContext = vma_new(allocator, VmaDefragmentationContext_T)(allocator, *pInfo);
+ return VK_SUCCESS;
}
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationEnd(
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentation(
VmaAllocator allocator,
- VmaDefragmentationContext context)
+ VmaDefragmentationContext context,
+ VmaDefragmentationStats* pStats)
{
- VMA_ASSERT(allocator);
+ VMA_ASSERT(allocator && context);
- VMA_DEBUG_LOG("vmaDefragmentationEnd");
+ VMA_DEBUG_LOG("vmaEndDefragmentation");
- if(context != VK_NULL_HANDLE)
- {
- VMA_DEBUG_GLOBAL_MUTEX_LOCK
- return allocator->DefragmentationEnd(context);
- }
- else
- {
- return VK_SUCCESS;
- }
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK
+
+ if (pStats)
+ context->GetStats(*pStats);
+ vma_delete(allocator, context);
+ return VK_SUCCESS;
}
VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass(
- VmaAllocator allocator,
- VmaDefragmentationContext context,
- VmaDefragmentationPassInfo* pInfo
- )
+ VmaAllocator VMA_NOT_NULL allocator,
+ VmaDefragmentationContext VMA_NOT_NULL context,
+ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo)
{
- VMA_ASSERT(allocator);
- VMA_ASSERT(pInfo);
+ VMA_ASSERT(context && pPassInfo);
VMA_DEBUG_LOG("vmaBeginDefragmentationPass");
VMA_DEBUG_GLOBAL_MUTEX_LOCK
- if(context == VK_NULL_HANDLE)
- {
- pInfo->moveCount = 0;
- return VK_SUCCESS;
- }
-
- return allocator->DefragmentationPassBegin(pInfo, context);
+ return context->DefragmentPassBegin(*pPassInfo);
}
VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass(
- VmaAllocator allocator,
- VmaDefragmentationContext context)
+ VmaAllocator VMA_NOT_NULL allocator,
+ VmaDefragmentationContext VMA_NOT_NULL context,
+ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo)
{
- VMA_ASSERT(allocator);
+ VMA_ASSERT(context && pPassInfo);
VMA_DEBUG_LOG("vmaEndDefragmentationPass");
+
VMA_DEBUG_GLOBAL_MUTEX_LOCK
- if(context == VK_NULL_HANDLE)
- return VK_SUCCESS;
-
- return allocator->DefragmentationPassEnd(context);
+ return context->DefragmentPassEnd(*pPassInfo);
}
VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory(
@@ -19196,39 +17934,6 @@ you can achieve behavior of a ring buffer / queue.
Ring buffer is available only in pools with one memory block -
VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined.
-\section buddy_algorithm Buddy allocation algorithm
-
-There is another allocation algorithm that can be used with custom pools, called
-"buddy". Its internal data structure is based on a binary tree of blocks, each having
-size that is a power of two and a half of its parent's size. When you want to
-allocate memory of certain size, a free node in the tree is located. If it is too
-large, it is recursively split into two halves (called "buddies"). However, if
-requested allocation size is not a power of two, the size of the allocation is
-aligned up to the nearest power of two and the remaining space is wasted. When
-two buddy nodes become free, they are merged back into one larger node.
-
-![Buddy allocator](../gfx/Buddy_allocator.png)
-
-The advantage of buddy allocation algorithm over default algorithm is faster
-allocation and deallocation, as well as smaller external fragmentation. The
-disadvantage is more wasted space (internal fragmentation).
-For more information, please search the Internet for "Buddy memory allocation" -
-sources that describe this concept in general.
-
-To use buddy allocation algorithm with a custom pool, add flag
-#VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating
-#VmaPool object.
-
-Several limitations apply to pools that use buddy algorithm:
-
-- It is recommended to use VmaPoolCreateInfo::blockSize that is a power of two.
- Otherwise, only largest power of two smaller than the size is used for
- allocations. The remaining space always stays unused.
-- [Margins](@ref debugging_memory_usage_margins) and
- [corruption detection](@ref debugging_memory_usage_corruption_detection)
- don't work in such pools.
-- [Defragmentation](@ref defragmentation) doesn't work with allocations made from
- such pool.
\page defragmentation Defragmentation
@@ -19238,213 +17943,68 @@ to find a continuous range of free memory for a new allocation despite there is
enough free space, just scattered across many small free ranges between existing
allocations.
-To mitigate this problem, you can use defragmentation feature:
-structure #VmaDefragmentationInfo2, function vmaDefragmentationBegin(), vmaDefragmentationEnd().
-Given set of allocations,
-this function can move them to compact used memory, ensure more continuous free
-space and possibly also free some `VkDeviceMemory` blocks.
-
-What the defragmentation does is:
-
-- Updates #VmaAllocation objects to point to new `VkDeviceMemory` and offset.
- After allocation has been moved, its VmaAllocationInfo::deviceMemory and/or
- VmaAllocationInfo::offset changes. You must query them again using
- vmaGetAllocationInfo() if you need them.
-- Moves actual data in memory.
-
-What it doesn't do, so you need to do it yourself:
-
-- Recreate buffers and images that were bound to allocations that were defragmented and
- bind them with their new places in memory.
- You must use `vkDestroyBuffer()`, `vkDestroyImage()`,
- `vkCreateBuffer()`, `vkCreateImage()`, vmaBindBufferMemory(), vmaBindImageMemory()
- for that purpose and NOT vmaDestroyBuffer(),
- vmaDestroyImage(), vmaCreateBuffer(), vmaCreateImage(), because you don't need to
- destroy or create allocation objects!
-- Recreate views and update descriptors that point to these buffers and images.
-
-\section defragmentation_cpu Defragmenting CPU memory
-
-Following example demonstrates how you can run defragmentation on CPU.
-Only allocations created in memory types that are `HOST_VISIBLE` can be defragmented.
-Others are ignored.
-
-The way it works is:
-
-- It temporarily maps entire memory blocks when necessary.
-- It moves data using `memmove()` function.
-
-\code
-// Given following variables already initialized:
-VkDevice device;
-VmaAllocator allocator;
-std::vector buffers;
-std::vector allocations;
-
-
-const uint32_t allocCount = (uint32_t)allocations.size();
-std::vector allocationsChanged(allocCount);
-
-VmaDefragmentationInfo2 defragInfo = {};
-defragInfo.allocationCount = allocCount;
-defragInfo.pAllocations = allocations.data();
-defragInfo.pAllocationsChanged = allocationsChanged.data();
-defragInfo.maxCpuBytesToMove = VK_WHOLE_SIZE; // No limit.
-defragInfo.maxCpuAllocationsToMove = UINT32_MAX; // No limit.
-
-VmaDefragmentationContext defragCtx;
-vmaDefragmentationBegin(allocator, &defragInfo, nullptr, &defragCtx);
-vmaDefragmentationEnd(allocator, defragCtx);
-
-for(uint32_t i = 0; i < allocCount; ++i)
-{
- if(allocationsChanged[i])
- {
- // Destroy buffer that is immutably bound to memory region which is no longer valid.
- vkDestroyBuffer(device, buffers[i], nullptr);
-
- // Create new buffer with same parameters.
- VkBufferCreateInfo bufferInfo = ...;
- vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]);
-
- // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning.
-
- // Bind new buffer to new memory region. Data contained in it is already moved.
- VmaAllocationInfo allocInfo;
- vmaGetAllocationInfo(allocator, allocations[i], &allocInfo);
- vmaBindBufferMemory(allocator, allocations[i], buffers[i]);
- }
-}
-\endcode
-
-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](@ref choosing_memory_type_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.
-
-\section defragmentation_gpu Defragmenting GPU memory
-
-It is also possible to defragment allocations created in memory types that are not `HOST_VISIBLE`.
-To do that, you need to pass a command buffer that meets requirements as described in
-VmaDefragmentationInfo2::commandBuffer. The way it works is:
-
-- It creates temporary buffers and binds them to entire memory blocks when necessary.
-- It issues `vkCmdCopyBuffer()` to passed command buffer.
+To mitigate this problem, you can use defragmentation feature.
+It doesn't happen automatically thought and needs your cooperation,
+because VMA is a low level library that only allocates memory.
+It cannot recreate buffers and images in a new place as it doesn't remember the contents of `VkBufferCreateInfo` / `VkImageCreateInfo` structures.
+It cannot copy their contents as it doesn't record any commands to a command buffer.
Example:
\code
-// Given following variables already initialized:
-VkDevice device;
-VmaAllocator allocator;
-VkCommandBuffer commandBuffer;
-std::vector buffers;
-std::vector allocations;
-
-
-const uint32_t allocCount = (uint32_t)allocations.size();
-std::vector allocationsChanged(allocCount);
-
-VkCommandBufferBeginInfo cmdBufBeginInfo = ...;
-vkBeginCommandBuffer(commandBuffer, &cmdBufBeginInfo);
-
-VmaDefragmentationInfo2 defragInfo = {};
-defragInfo.allocationCount = allocCount;
-defragInfo.pAllocations = allocations.data();
-defragInfo.pAllocationsChanged = allocationsChanged.data();
-defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE; // Notice it is "GPU" this time.
-defragInfo.maxGpuAllocationsToMove = UINT32_MAX; // Notice it is "GPU" this time.
-defragInfo.commandBuffer = commandBuffer;
+VmaDefragmentationInfo defragInfo = {};
+defragInfo.pool = myPool;
+defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT;
VmaDefragmentationContext defragCtx;
-vmaDefragmentationBegin(allocator, &defragInfo, nullptr, &defragCtx);
+VkResult res = vmaBeginDefragmentation(allocator, &defragInfo, &defragCtx);
+// Check res...
-vkEndCommandBuffer(commandBuffer);
-
-// Submit commandBuffer.
-// Wait for a fence that ensures commandBuffer execution finished.
-
-vmaDefragmentationEnd(allocator, defragCtx);
-
-for(uint32_t i = 0; i < allocCount; ++i)
+for(;;)
{
- if(allocationsChanged[i])
+ VmaDefragmentationPassMoveInfo pass;
+ res = vmaBeginDefragmentationPass(allocator, defragCtx, &pass);
+ if(res == VK_SUCCESS)
+ break;
+ else if(res == VK_INCOMPLETE)
{
- // Destroy buffer that is immutably bound to memory region which is no longer valid.
- vkDestroyBuffer(device, buffers[i], nullptr);
-
- // Create new buffer with same parameters.
- VkBufferCreateInfo bufferInfo = ...;
- vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]);
-
- // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning.
-
- // Bind new buffer to new memory region. Data contained in it is already moved.
- VmaAllocationInfo allocInfo;
- vmaGetAllocationInfo(allocator, allocations[i], &allocInfo);
- vmaBindBufferMemory(allocator, allocations[i], buffers[i]);
+ for(uint32_t i = 0; i < pass.moveCount; ++i)
+ {
+ //- Inspect pass.pMoves[i].srcAllocation, identify what buffer or image it represents.
+ //- Recreate this buffer or image at pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset.
+ //- Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place.
+ }
+ //- Make sure the copy commands finished executing.
+ //- Update appropriate descriptors to point to the new places.
+ vmaEndDefragmentationPass(allocator, defragCtx, &pass);
}
+ else
+ // Handle error...
}
+
+vmaEndDefragmentation(allocator, defragCtx, nullptr);
\endcode
-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 can defragment a specific custom pool by setting VmaDefragmentationInfo::pool
+(like in the example above) or all the default pools by setting this member to null.
-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().
+Unlike in previous iterations of the defragmentation API, there is no list of "movable" allocations passed as a parameter.
+Defragmentation algorithm tries to move all suitable allocations.
+You can, however, refuse to move some of them inside a defragmentation pass, by setting
+`pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE.
+However, this is not recommended and may result in suboptimal packing of the allocations after defragmentation.
+If you cannot ensure any allocation can be moved, it is better to keep movable allocations separate in a custom pool.
-\section defragmentation_additional_notes Additional notes
+You can also decide to destroy an allocation instead of moving it.
+You should then set `pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY.
-It is only legal to defragment allocations bound to:
+You can perform the defragmentation incrementally to limit the number of allocations and bytes to be moved
+in each pass, e.g. to call it in sync with render frames and not to experience too big hitches.
+See members: VmaDefragmentationInfo::maxBytesPerPass, VmaDefragmentationInfo::maxAllocationsPerPass.
-- buffers
-- images created with `VK_IMAGE_CREATE_ALIAS_BIT`, `VK_IMAGE_TILING_LINEAR`, and
- being currently in `VK_IMAGE_LAYOUT_GENERAL` or `VK_IMAGE_LAYOUT_PREINITIALIZED`.
-
-Defragmentation of images created with `VK_IMAGE_TILING_OPTIMAL` or in any other
-layout may give undefined results.
-
-If you defragment allocations bound to images, new images to be bound to new
-memory region after defragmentation should be created with `VK_IMAGE_LAYOUT_PREINITIALIZED`
-and then transitioned to their original layout from before defragmentation if
-needed using an image memory barrier.
-
-While using defragmentation, you may experience validation layer warnings, which you just need to ignore.
-See [Validation layer warnings](@ref general_considerations_validation_layer_warnings).
-
-Please don't expect memory to be fully compacted after defragmentation.
-Algorithms inside are based on some heuristics that try to maximize number of Vulkan
-memory blocks to make totally empty to release them, as well as to maximize continuous
-empty space inside remaining blocks, while minimizing the number and size of allocations that
-need to be moved. Some fragmentation may still remain - this is normal.
-
-\section defragmentation_custom_algorithm Writing custom defragmentation algorithm
-
-If you want to implement your own, custom defragmentation algorithm,
-there is infrastructure prepared for that,
-but it is not exposed through the library API - you need to hack its source code.
-Here are steps needed to do this:
-
--# Main thing you need to do is to define your own class derived from base abstract
- class `VmaDefragmentationAlgorithm` and implement your version of its pure virtual methods.
- See definition and comments of this class for details.
--# Your code needs to interact with device memory block metadata.
- If you need more access to its data than it is provided by its public interface,
- declare your new class as a friend class e.g. in class `VmaBlockMetadata_Generic`.
--# If you want to create a flag that would enable your algorithm or pass some additional
- flags to configure it, add them to `VmaDefragmentationFlagBits` and use them in
- VmaDefragmentationInfo2::flags.
--# Modify function `VmaBlockVectorDefragmentationContext::Begin` to create object
- of your new class whenever needed.
+It is also safe to perform the defragmentation asynchronously to render frames and other Vulkan and VMA
+usage, possibly from multiple threads, with the exception that allocations
+returned in VmaDefragmentationPassMoveInfo::pMoves shouldn't be destroyed until the defragmentation pass is ended.
\page statistics Statistics
@@ -19809,7 +18369,6 @@ allocations, which have their own memory block of specific size.
It is thus not applied to allocations made using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag
or those automatically decided to put into dedicated allocations, e.g. due to its
large size or recommended by VK_KHR_dedicated_allocation extension.
-Margins are also not active in custom pools created with #VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT flag.
Margins appear in [JSON dump](@ref statistics_json_dump) as part of free space.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a55a6ab..a14bc8a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -69,6 +69,9 @@ if(VMA_BUILD_SAMPLE)
# Set VmaSample as startup project
set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT "VmaSample")
+
+ # Add C++ warnings and security checks
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /sdl /W3")
# Enable multithreaded compiling
target_compile_options(VmaSample PRIVATE "/MP")
diff --git a/src/Tests.cpp b/src/Tests.cpp
index 0b455f2..9937691 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -56,7 +56,7 @@ enum CONFIG_TYPE
CONFIG_TYPE_COUNT
};
-static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_SMALL;
+static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_AVERAGE;
//static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_LARGE;
enum class FREE_ORDER { FORWARD, BACKWARD, RANDOM, COUNT };
@@ -75,12 +75,8 @@ static const char* AlgorithmToStr(uint32_t algorithm)
{
case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT:
return "Linear";
- case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT:
- return "Buddy";
- case VMA_POOL_CREATE_TLSF_ALGORITHM_BIT:
- return "TLSF";
case 0:
- return "Default";
+ return "TLSF";
default:
assert(0);
return "";
@@ -93,18 +89,34 @@ static const char* VirtualAlgorithmToStr(uint32_t algorithm)
{
case VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT:
return "Linear";
- case VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT:
- return "Buddy";
- case VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT:
- return "TLSF";
case 0:
- return "Default";
+ return "TLSF";
default:
assert(0);
return "";
}
}
+static const wchar_t* DefragmentationAlgorithmToStr(uint32_t algorithm)
+{
+ switch (algorithm)
+ {
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT:
+ return L"Balanced";
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT:
+ return L"Fast";
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT:
+ return L"Full";
+ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
+ return L"Extensive";
+ case 0:
+ return L"Default";
+ default:
+ assert(0);
+ return L"";
+ }
+}
+
struct AllocationSize
{
uint32_t Probability;
@@ -135,9 +147,6 @@ struct Result
VkDeviceSize FreeRangeSizeAvg, FreeRangeSizeMax;
};
-void TestDefragmentationSimple();
-void TestDefragmentationFull();
-
struct PoolTestConfig
{
uint32_t RandSeed;
@@ -1169,7 +1178,7 @@ static void GetMemReq(VmaAllocationCreateInfo& outMemReq)
}
static void CreateBuffer(
- VmaPool pool,
+ VmaAllocationCreateInfo allocCreateInfo,
const VkBufferCreateInfo& bufCreateInfo,
bool persistentlyMapped,
AllocInfo& outAllocInfo)
@@ -1177,10 +1186,8 @@ static void CreateBuffer(
outAllocInfo = {};
outAllocInfo.m_BufferInfo = bufCreateInfo;
- VmaAllocationCreateInfo allocCreateInfo = {};
- allocCreateInfo.pool = pool;
- if(persistentlyMapped)
- allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
+ if (persistentlyMapped)
+ allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
VmaAllocationInfo vmaAllocInfo = {};
ERR_GUARD_VULKAN( vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &outAllocInfo.m_Buffer, &outAllocInfo.m_Allocation, &vmaAllocInfo) );
@@ -1205,6 +1212,45 @@ static void CreateBuffer(
}
}
+void CreateImage(
+ VmaAllocationCreateInfo allocCreateInfo,
+ const VkImageCreateInfo& imgCreateInfo,
+ VkImageLayout dstLayout,
+ bool persistentlyMapped,
+ AllocInfo& outAllocInfo)
+{
+ if (persistentlyMapped)
+ allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
+ outAllocInfo.CreateImage(imgCreateInfo, allocCreateInfo, dstLayout);
+
+ // Perform barrier into destination layout
+ if (dstLayout != imgCreateInfo.initialLayout)
+ {
+ BeginSingleTimeCommands();
+
+ VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
+ barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ barrier.oldLayout = imgCreateInfo.initialLayout;
+ barrier.newLayout = dstLayout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = outAllocInfo.m_Image;
+ barrier.subresourceRange =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ 0, VK_REMAINING_MIP_LEVELS,
+ 0, VK_REMAINING_ARRAY_LAYERS
+ };
+
+ vkCmdPipelineBarrier(g_hTemporaryCommandBuffer,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
+ 0, nullptr, 0, nullptr, 1, &barrier);
+
+ EndSingleTimeCommands();
+ }
+}
+
static void CreateAllocation(AllocInfo& outAllocation)
{
outAllocation.m_Allocation = nullptr;
@@ -1227,7 +1273,7 @@ static void CreateAllocation(AllocInfo& outAllocation)
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = bufferSize;
- bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
VkResult res = vmaCreateBuffer(g_hAllocator, &bufferInfo, &vmaMemReq, &outAllocation.m_Buffer, &outAllocation.m_Allocation, &allocInfo);
outAllocation.m_BufferInfo = bufferInfo;
@@ -1253,7 +1299,7 @@ static void CreateAllocation(AllocInfo& outAllocation)
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
- imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
VkResult res = vmaCreateImage(g_hAllocator, &imageInfo, &vmaMemReq, &outAllocation.m_Image, &outAllocation.m_Allocation, &allocInfo);
outAllocation.m_ImageInfo = imageInfo;
@@ -1305,16 +1351,23 @@ static void ValidateAllocationData(const AllocInfo& allocation)
uint32_t value = allocation.m_StartValue;
bool ok = true;
- size_t i;
- TEST(allocInfo.size % 4 == 0);
- for(i = 0; i < allocInfo.size / sizeof(uint32_t); ++i)
+ if(allocation.m_Buffer)
{
- if(data[i] != value++)
+ TEST(allocInfo.size % 4 == 0);
+ for(size_t i = 0; i < allocInfo.size / sizeof(uint32_t); ++i)
{
- ok = false;
- break;
+ if(data[i] != value++)
+ {
+ ok = false;
+ break;
+ }
}
}
+ else
+ {
+ TEST(allocation.m_Image);
+ // Images not currently supported.
+ }
TEST(ok);
if(allocInfo.pMappedData == nullptr)
@@ -1357,26 +1410,240 @@ static void RecreateAllocationResource(AllocInfo& allocation)
}
}
-static void Defragment(AllocInfo* allocs, size_t allocCount,
- const VmaDefragmentationInfo* defragmentationInfo = nullptr,
- VmaDefragmentationStats* defragmentationStats = nullptr)
+static void ProcessDefragmentationPass(VmaDefragmentationPassMoveInfo& stepInfo)
{
- std::vector vmaAllocs(allocCount);
- for(size_t i = 0; i < allocCount; ++i)
- vmaAllocs[i] = allocs[i].m_Allocation;
+ std::vector beginImageBarriers;
+ std::vector finalizeImageBarriers;
- std::vector allocChanged(allocCount);
-
- ERR_GUARD_VULKAN( vmaDefragment(g_hAllocator, vmaAllocs.data(), allocCount, allocChanged.data(),
- defragmentationInfo, defragmentationStats) );
+ VkPipelineStageFlags beginSrcStageMask = 0;
+ VkPipelineStageFlags beginDstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- for(size_t i = 0; i < allocCount; ++i)
+ VkPipelineStageFlags finalizeSrcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ VkPipelineStageFlags finalizeDstStageMask = 0;
+
+ bool wantsMemoryBarrier = false;
+
+ VkMemoryBarrier beginMemoryBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
+ VkMemoryBarrier finalizeMemoryBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
+
+ for (uint32_t i = 0; i < stepInfo.moveCount; ++i)
{
- if(allocChanged[i])
+ if (stepInfo.pMoves[i].operation == VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY)
{
- RecreateAllocationResource(allocs[i]);
+ VmaAllocationInfo info;
+ vmaGetAllocationInfo(g_hAllocator, stepInfo.pMoves[i].srcAllocation, &info);
+
+ AllocInfo* allocInfo = (AllocInfo*)info.pUserData;
+
+ if (allocInfo->m_Image)
+ {
+ VkImage newImage;
+
+ const VkResult result = vkCreateImage(g_hDevice, &allocInfo->m_ImageInfo, g_Allocs, &newImage);
+ TEST(result >= VK_SUCCESS);
+
+ vkBindImageMemory(g_hDevice, newImage, stepInfo.pMoves[i].dstMemory, stepInfo.pMoves[i].dstOffset);
+ allocInfo->m_NewImage = newImage;
+
+ // Keep track of our pipeline stages that we need to wait/signal on
+ beginSrcStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ finalizeDstStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+
+ // We need one pipeline barrier and two image layout transitions here
+ // First we'll have to turn our newly created image into VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
+ // And the second one is turning the old image into VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
+
+ VkImageSubresourceRange subresourceRange = {
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ 0, VK_REMAINING_MIP_LEVELS,
+ 0, VK_REMAINING_ARRAY_LAYERS
+ };
+
+ VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = newImage;
+ barrier.subresourceRange = subresourceRange;
+
+ beginImageBarriers.push_back(barrier);
+
+ // Second barrier to convert the existing image. This one actually needs a real barrier
+ barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ barrier.oldLayout = allocInfo->m_ImageLayout;
+ barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ barrier.image = allocInfo->m_Image;
+
+ beginImageBarriers.push_back(barrier);
+
+ // And lastly we need a barrier that turns our new image into the layout of the old one
+ barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+ barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ barrier.newLayout = allocInfo->m_ImageLayout;
+ barrier.image = newImage;
+
+ finalizeImageBarriers.push_back(barrier);
+ }
+ else if (allocInfo->m_Buffer)
+ {
+ VkBuffer newBuffer;
+
+ const VkResult result = vkCreateBuffer(g_hDevice, &allocInfo->m_BufferInfo, g_Allocs, &newBuffer);
+ TEST(result >= VK_SUCCESS);
+
+ vkBindBufferMemory(g_hDevice, newBuffer, stepInfo.pMoves[i].dstMemory, stepInfo.pMoves[i].dstOffset);
+ allocInfo->m_NewBuffer = newBuffer;
+
+ // Keep track of our pipeline stages that we need to wait/signal on
+ beginSrcStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ finalizeDstStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+
+ beginMemoryBarrier.srcAccessMask |= VK_ACCESS_MEMORY_WRITE_BIT;
+ beginMemoryBarrier.dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT;
+
+ finalizeMemoryBarrier.srcAccessMask |= VK_ACCESS_TRANSFER_WRITE_BIT;
+ finalizeMemoryBarrier.dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT;
+
+ wantsMemoryBarrier = true;
+ }
}
}
+
+ if (!beginImageBarriers.empty() || wantsMemoryBarrier)
+ {
+ const uint32_t memoryBarrierCount = wantsMemoryBarrier ? 1 : 0;
+
+ vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, beginSrcStageMask, beginDstStageMask, 0,
+ memoryBarrierCount, &beginMemoryBarrier,
+ 0, nullptr,
+ (uint32_t)beginImageBarriers.size(), beginImageBarriers.data());
+ }
+
+ for (uint32_t i = 0; i < stepInfo.moveCount; ++i)
+ {
+ if (stepInfo.pMoves[i].operation == VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY)
+ {
+ VmaAllocationInfo info;
+ vmaGetAllocationInfo(g_hAllocator, stepInfo.pMoves[i].srcAllocation, &info);
+
+ AllocInfo* allocInfo = (AllocInfo*)info.pUserData;
+
+ if (allocInfo->m_Image)
+ {
+ std::vector imageCopies;
+
+ // Copy all mips of the source image into the target image
+ VkOffset3D offset = { 0, 0, 0 };
+ VkExtent3D extent = allocInfo->m_ImageInfo.extent;
+
+ VkImageSubresourceLayers subresourceLayers = {
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ 0,
+ 0, 1
+ };
+
+ for (uint32_t mip = 0; mip < allocInfo->m_ImageInfo.mipLevels; ++mip)
+ {
+ subresourceLayers.mipLevel = mip;
+
+ VkImageCopy imageCopy{
+ subresourceLayers,
+ offset,
+ subresourceLayers,
+ offset,
+ extent
+ };
+
+ imageCopies.push_back(imageCopy);
+
+ extent.width = std::max(uint32_t(1), extent.width >> 1);
+ extent.height = std::max(uint32_t(1), extent.height >> 1);
+ extent.depth = std::max(uint32_t(1), extent.depth >> 1);
+ }
+
+ vkCmdCopyImage(
+ g_hTemporaryCommandBuffer,
+ allocInfo->m_Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ allocInfo->m_NewImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ (uint32_t)imageCopies.size(), imageCopies.data());
+ }
+ else if (allocInfo->m_Buffer)
+ {
+ VkBufferCopy region = {
+ 0,
+ 0,
+ allocInfo->m_BufferInfo.size };
+
+ vkCmdCopyBuffer(g_hTemporaryCommandBuffer,
+ allocInfo->m_Buffer, allocInfo->m_NewBuffer,
+ 1, ®ion);
+ }
+ }
+ }
+
+ if (!finalizeImageBarriers.empty() || wantsMemoryBarrier)
+ {
+ const uint32_t memoryBarrierCount = wantsMemoryBarrier ? 1 : 0;
+
+ vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, finalizeSrcStageMask, finalizeDstStageMask, 0,
+ memoryBarrierCount, &finalizeMemoryBarrier,
+ 0, nullptr,
+ (uint32_t)finalizeImageBarriers.size(), finalizeImageBarriers.data());
+ }
+}
+
+static void Defragment(VmaDefragmentationInfo& defragmentationInfo,
+ VmaDefragmentationStats* defragmentationStats = nullptr)
+{
+ VmaDefragmentationContext defragCtx = nullptr;
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragmentationInfo, &defragCtx);
+ TEST(res == VK_SUCCESS);
+
+ VmaDefragmentationPassMoveInfo pass;
+ while ((res = vmaBeginDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_INCOMPLETE)
+ {
+ BeginSingleTimeCommands();
+ ProcessDefragmentationPass(pass);
+ EndSingleTimeCommands();
+
+ // Destroy old buffers/images and replace them with new handles.
+ for(size_t i = 0; i < pass.moveCount; ++i)
+ {
+ VmaAllocation const alloc = pass.pMoves[i].srcAllocation;
+ VmaAllocationInfo vmaAllocInfo;
+ vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
+ AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
+
+ if(allocInfo->m_Buffer)
+ {
+ assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
+ vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
+ allocInfo->m_Buffer = allocInfo->m_NewBuffer;
+ allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ }
+ else if(allocInfo->m_Image)
+ {
+ assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
+ vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
+ allocInfo->m_Image = allocInfo->m_NewImage;
+ allocInfo->m_NewImage = VK_NULL_HANDLE;
+ }
+ else
+ assert(0);
+ }
+ if ((res = vmaEndDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_SUCCESS)
+ break;
+ TEST(res == VK_INCOMPLETE);
+ }
+ TEST(res == VK_SUCCESS);
+
+ res = vmaEndDefragmentation(g_hAllocator, defragCtx, defragmentationStats);
+ TEST(res == VK_SUCCESS);
}
static void ValidateAllocationsData(const AllocInfo* allocs, size_t allocCount)
@@ -1397,41 +1664,47 @@ void TestDefragmentationSimple()
const VkDeviceSize MIN_BUF_SIZE = 32;
const VkDeviceSize MAX_BUF_SIZE = BUF_SIZE * 4;
- auto RandomBufSize = [&]() -> VkDeviceSize {
+ auto RandomBufSize = [&]() -> VkDeviceSize
+ {
return align_up(rand.Generate() % (MAX_BUF_SIZE - MIN_BUF_SIZE + 1) + MIN_BUF_SIZE, 32);
};
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.size = BUF_SIZE;
- bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
- VmaAllocationCreateInfo exampleAllocCreateInfo = {};
- exampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
- exampleAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
+ VmaAllocationCreateInfo allocCreateInfo = {};
+ allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
+ allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
uint32_t memTypeIndex = UINT32_MAX;
- vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufCreateInfo, &exampleAllocCreateInfo, &memTypeIndex);
+ vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &memTypeIndex);
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.blockSize = BLOCK_SIZE;
poolCreateInfo.memoryTypeIndex = memTypeIndex;
VmaPool pool;
- ERR_GUARD_VULKAN( vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) );
+ TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS);
+ allocCreateInfo.pool = pool;
+
+ VmaDefragmentationInfo defragInfo = {};
+ defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT;
+ defragInfo.pool = pool;
// Defragmentation of empty pool.
{
- VmaDefragmentationInfo2 defragInfo = {};
- defragInfo.maxCpuBytesToMove = VK_WHOLE_SIZE;
- defragInfo.maxCpuAllocationsToMove = UINT32_MAX;
- defragInfo.poolCount = 1;
- defragInfo.pPools = &pool;
+ VmaDefragmentationContext defragCtx = nullptr;
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragInfo, &defragCtx);
+ TEST(res == VK_SUCCESS);
+
+ VmaDefragmentationPassMoveInfo pass;
+ res = vmaBeginDefragmentationPass(g_hAllocator, defragCtx, &pass);
+ TEST(res == VK_SUCCESS);
VmaDefragmentationStats defragStats = {};
- VmaDefragmentationContext defragCtx = nullptr;
- VkResult res = vmaDefragmentationBegin(g_hAllocator, &defragInfo, &defragStats, &defragCtx);
- TEST(res >= VK_SUCCESS);
- vmaDefragmentationEnd(g_hAllocator, defragCtx);
+ res = vmaEndDefragmentation(g_hAllocator, defragCtx, &defragStats);
+ TEST(res == VK_SUCCESS);
TEST(defragStats.allocationsMoved == 0 && defragStats.bytesFreed == 0 &&
defragStats.bytesMoved == 0 && defragStats.deviceMemoryBlocksFreed == 0);
}
@@ -1440,7 +1713,7 @@ void TestDefragmentationSimple()
// persistentlyMappedOption = 0 - not persistently mapped.
// persistentlyMappedOption = 1 - persistently mapped.
- for(uint32_t persistentlyMappedOption = 0; persistentlyMappedOption < 2; ++persistentlyMappedOption)
+ for (uint32_t persistentlyMappedOption = 0; persistentlyMappedOption < 2; ++persistentlyMappedOption)
{
wprintf(L" Persistently mapped option = %u\n", persistentlyMappedOption);
const bool persistentlyMapped = persistentlyMappedOption != 0;
@@ -1450,26 +1723,28 @@ void TestDefragmentationSimple()
// Fill 2 blocks. Remove odd buffers. Defragment everything.
// Expected result: at least 1 block freed.
{
- for(size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
+ for (size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
{
AllocInfo allocInfo;
- CreateBuffer(pool, bufCreateInfo, persistentlyMapped, allocInfo);
+ CreateBuffer(allocCreateInfo, bufCreateInfo, persistentlyMapped, allocInfo);
allocations.push_back(allocInfo);
}
- for(size_t i = 1; i < allocations.size(); ++i)
+ for (size_t i = 1; i < allocations.size(); ++i)
{
DestroyAllocation(allocations[i]);
allocations.erase(allocations.begin() + i);
}
+
+ // Set data for defragmentation retrieval
+ for (auto& alloc : allocations)
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
VmaDefragmentationStats defragStats;
- Defragment(allocations.data(), allocations.size(), nullptr, &defragStats);
- TEST(defragStats.allocationsMoved > 0 && defragStats.bytesMoved > 0);
- TEST(defragStats.deviceMemoryBlocksFreed >= 1);
+ Defragment(defragInfo, &defragStats);
+ TEST(defragStats.allocationsMoved == 4 && defragStats.bytesMoved == 4 * BUF_SIZE);
ValidateAllocationsData(allocations.data(), allocations.size());
-
DestroyAllAllocations(allocations);
}
@@ -1478,32 +1753,76 @@ void TestDefragmentationSimple()
// Fill 2 blocks. Remove odd buffers. Defragment one buffer at time.
// Expected result: Each of 4 interations makes some progress.
{
- for(size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
+ for (size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
{
AllocInfo allocInfo;
- CreateBuffer(pool, bufCreateInfo, persistentlyMapped, allocInfo);
+ CreateBuffer(allocCreateInfo, bufCreateInfo, persistentlyMapped, allocInfo);
allocations.push_back(allocInfo);
}
- for(size_t i = 1; i < allocations.size(); ++i)
+ for (size_t i = 1; i < allocations.size(); ++i)
{
DestroyAllocation(allocations[i]);
allocations.erase(allocations.begin() + i);
}
- VmaDefragmentationInfo defragInfo = {};
- defragInfo.maxAllocationsToMove = 1;
- defragInfo.maxBytesToMove = BUF_SIZE;
+ // Set data for defragmentation retrieval
+ for (auto& alloc : allocations)
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
- for(size_t i = 0; i < BLOCK_SIZE / BUF_SIZE / 2; ++i)
+ defragInfo.maxAllocationsPerPass = 1;
+ defragInfo.maxBytesPerPass = BUF_SIZE;
+
+ VmaDefragmentationContext defragCtx = nullptr;
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragInfo, &defragCtx);
+ TEST(res == VK_SUCCESS);
+
+ for (size_t i = 0; i < BLOCK_SIZE / BUF_SIZE / 2; ++i)
{
- VmaDefragmentationStats defragStats;
- Defragment(allocations.data(), allocations.size(), &defragInfo, &defragStats);
- TEST(defragStats.allocationsMoved > 0 && defragStats.bytesMoved > 0);
+ VmaDefragmentationPassMoveInfo pass;
+ res = vmaBeginDefragmentationPass(g_hAllocator, defragCtx, &pass);
+ TEST(res == VK_INCOMPLETE);
+
+ BeginSingleTimeCommands();
+ ProcessDefragmentationPass(pass);
+ EndSingleTimeCommands();
+
+ // Destroy old buffers/images and replace them with new handles.
+ for (size_t i = 0; i < pass.moveCount; ++i)
+ {
+ VmaAllocation const alloc = pass.pMoves[i].srcAllocation;
+ VmaAllocationInfo vmaAllocInfo;
+ vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
+ AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
+
+ if (allocInfo->m_Buffer)
+ {
+ assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
+ vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
+ allocInfo->m_Buffer = allocInfo->m_NewBuffer;
+ allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ }
+ else if (allocInfo->m_Image)
+ {
+ assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
+ vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
+ allocInfo->m_Image = allocInfo->m_NewImage;
+ allocInfo->m_NewImage = VK_NULL_HANDLE;
+ }
+ else
+ assert(0);
+ }
+
+ res = vmaEndDefragmentationPass(g_hAllocator, defragCtx, &pass);
+ TEST(res == VK_INCOMPLETE);
}
- ValidateAllocationsData(allocations.data(), allocations.size());
+ VmaDefragmentationStats defragStats = {};
+ res = vmaEndDefragmentation(g_hAllocator, defragCtx, &defragStats);
+ TEST(res == VK_SUCCESS);
+ TEST(defragStats.allocationsMoved == 4 && defragStats.bytesMoved == 4 * BUF_SIZE);
+ ValidateAllocationsData(allocations.data(), allocations.size());
DestroyAllAllocations(allocations);
}
@@ -1513,19 +1832,19 @@ void TestDefragmentationSimple()
// Defragment while having some percent of them unmovable.
// Expected result: Just simple validation.
{
- for(size_t i = 0; i < 100; ++i)
+ for (size_t i = 0; i < 100; ++i)
{
VkBufferCreateInfo localBufCreateInfo = bufCreateInfo;
localBufCreateInfo.size = RandomBufSize();
AllocInfo allocInfo;
- CreateBuffer(pool, bufCreateInfo, persistentlyMapped, allocInfo);
+ CreateBuffer(allocCreateInfo, localBufCreateInfo, persistentlyMapped, allocInfo);
allocations.push_back(allocInfo);
}
const uint32_t percentToDelete = 60;
const size_t numberToDelete = allocations.size() * percentToDelete / 100;
- for(size_t i = 0; i < numberToDelete; ++i)
+ for (size_t i = 0; i < numberToDelete; ++i)
{
size_t indexToDelete = rand.Generate() % (uint32_t)allocations.size();
DestroyAllocation(allocations[indexToDelete]);
@@ -1535,139 +1854,279 @@ void TestDefragmentationSimple()
// Non-movable allocations will be at the beginning of allocations array.
const uint32_t percentNonMovable = 20;
const size_t numberNonMovable = allocations.size() * percentNonMovable / 100;
- for(size_t i = 0; i < numberNonMovable; ++i)
+ for (size_t i = 0; i < numberNonMovable; ++i)
{
size_t indexNonMovable = i + rand.Generate() % (uint32_t)(allocations.size() - i);
- if(indexNonMovable != i)
+ if (indexNonMovable != i)
std::swap(allocations[i], allocations[indexNonMovable]);
}
+ // Set data for defragmentation retrieval
+ for (auto& alloc : allocations)
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
+
+ defragInfo.maxAllocationsPerPass = 0;
+ defragInfo.maxBytesPerPass = 0;
+
+ VmaDefragmentationContext defragCtx = nullptr;
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragInfo, &defragCtx);
+ TEST(res == VK_SUCCESS);
+
+ VmaDefragmentationPassMoveInfo pass;
+ while ((res = vmaBeginDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_INCOMPLETE)
+ {
+ VmaDefragmentationMove* end = pass.pMoves + pass.moveCount;
+ for (uint32_t i = 0; i < numberNonMovable; ++i)
+ {
+ VmaDefragmentationMove* move = std::find_if(pass.pMoves, end, [&](VmaDefragmentationMove& move) { return move.srcAllocation == allocations[i].m_Allocation; });
+ if (move != end)
+ move->operation = VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
+ }
+
+ BeginSingleTimeCommands();
+ ProcessDefragmentationPass(pass);
+ EndSingleTimeCommands();
+
+ // Destroy old buffers/images and replace them with new handles.
+ for (size_t i = 0; i < pass.moveCount; ++i)
+ {
+ if (pass.pMoves[i].operation != VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE)
+ {
+ VmaAllocation const alloc = pass.pMoves[i].srcAllocation;
+ VmaAllocationInfo vmaAllocInfo;
+ vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
+ AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
+
+ if (allocInfo->m_Buffer)
+ {
+ assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
+ vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
+ allocInfo->m_Buffer = allocInfo->m_NewBuffer;
+ allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ }
+ else
+ assert(0);
+ }
+ }
+
+ if ((res = vmaEndDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_SUCCESS)
+ break;
+ TEST(res == VK_INCOMPLETE);
+ }
+ TEST(res == VK_SUCCESS);
+
VmaDefragmentationStats defragStats;
- Defragment(
- allocations.data() + numberNonMovable,
- allocations.size() - numberNonMovable,
- nullptr, &defragStats);
+ res = vmaEndDefragmentation(g_hAllocator, defragCtx, &defragStats);
+ TEST(res == VK_SUCCESS);
ValidateAllocationsData(allocations.data(), allocations.size());
-
DestroyAllAllocations(allocations);
}
}
- /*
- Allocation that must be move to an overlapping place using memmove().
- Create 2 buffers, second slightly bigger than the first. Delete first. Then defragment.
- */
- if(VMA_DEBUG_MARGIN == 0) // FAST algorithm works only when DEBUG_MARGIN disabled.
- {
- AllocInfo allocInfo[2];
-
- bufCreateInfo.size = BUF_SIZE;
- CreateBuffer(pool, bufCreateInfo, false, allocInfo[0]);
- const VkDeviceSize biggerBufSize = BUF_SIZE + BUF_SIZE / 256;
- bufCreateInfo.size = biggerBufSize;
- CreateBuffer(pool, bufCreateInfo, false, allocInfo[1]);
-
- DestroyAllocation(allocInfo[0]);
-
- VmaDefragmentationStats defragStats;
- Defragment(&allocInfo[1], 1, nullptr, &defragStats);
- // If this fails, it means we couldn't do memmove with overlapping regions.
- TEST(defragStats.allocationsMoved == 1 && defragStats.bytesMoved > 0);
-
- ValidateAllocationsData(&allocInfo[1], 1);
- DestroyAllocation(allocInfo[1]);
- }
-
vmaDestroyPool(g_hAllocator, pool);
}
-void TestDefragmentationWholePool()
+void TestDefragmentationAlgorithms()
{
- wprintf(L"Test defragmentation whole pool\n");
+ wprintf(L"Test defragmentation simple\n");
- RandomNumberGenerator rand(668);
+ RandomNumberGenerator rand(669);
const VkDeviceSize BUF_SIZE = 0x10000;
- const VkDeviceSize BLOCK_SIZE = BUF_SIZE * 8;
-
+ const uint32_t TEX_SIZE = 256;
+ const VkDeviceSize BLOCK_SIZE = BUF_SIZE * 200 + TEX_SIZE * 200;
+
+ const VkDeviceSize MIN_BUF_SIZE = 2048;
+ const VkDeviceSize MAX_BUF_SIZE = BUF_SIZE * 4;
+ auto RandomBufSize = [&]() -> VkDeviceSize
+ {
+ return align_up(rand.Generate() % (MAX_BUF_SIZE - MIN_BUF_SIZE + 1) + MIN_BUF_SIZE, 32);
+ };
+
+ const uint32_t MIN_TEX_SIZE = 512;
+ const uint32_t MAX_TEX_SIZE = TEX_SIZE * 4;
+ auto RandomTexSize = [&]() -> uint32_t
+ {
+ return align_up(rand.Generate() % (MAX_TEX_SIZE - MIN_TEX_SIZE + 1) + MIN_TEX_SIZE, 32);
+ };
+
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.size = BUF_SIZE;
- bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
- VmaAllocationCreateInfo exampleAllocCreateInfo = {};
- exampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
- exampleAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
+ VkImageCreateInfo imageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
+ imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+ imageCreateInfo.extent.depth = 1;
+ imageCreateInfo.mipLevels = 1;
+ imageCreateInfo.arrayLayers = 1;
+ imageCreateInfo.format = VK_FORMAT_R8_UNORM;
+ imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
+ imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+
+ VmaAllocationCreateInfo allocCreateInfo = {};
+ allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
+ allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
uint32_t memTypeIndex = UINT32_MAX;
- vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufCreateInfo, &exampleAllocCreateInfo, &memTypeIndex);
+ vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &memTypeIndex);
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.blockSize = BLOCK_SIZE;
poolCreateInfo.memoryTypeIndex = memTypeIndex;
- VmaDefragmentationStats defragStats[2];
- for(size_t caseIndex = 0; caseIndex < 2; ++caseIndex)
+ VmaPool pool;
+ TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS);
+ allocCreateInfo.pool = pool;
+
+ VmaDefragmentationInfo defragInfo = {};
+ defragInfo.pool = pool;
+
+ std::vector allocations;
+
+ for (uint8_t i = 0; i < 4; ++i)
{
- VmaPool pool;
- ERR_GUARD_VULKAN( vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) );
-
- std::vector allocations;
-
- // Buffers of fixed size.
- // Fill 2 blocks. Remove odd buffers. Defragment all of them.
- for(size_t i = 0; i < BLOCK_SIZE / BUF_SIZE * 2; ++i)
+ switch (i)
{
- AllocInfo allocInfo;
- CreateBuffer(pool, bufCreateInfo, false, allocInfo);
- allocations.push_back(allocInfo);
+ case 0:
+ defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT;
+ break;
+ case 1:
+ defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT;
+ break;
+ case 2:
+ defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT;
+ break;
+ case 3:
+ defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT;
+ break;
}
+ wprintf(L" Algorithm = %s\n", DefragmentationAlgorithmToStr(defragInfo.flags));
- for(size_t i = 1; i < allocations.size(); ++i)
+ // 0 - Without immovable allocations
+ // 1 - With immovable allocations
+ for (uint8_t j = 0; j < 2; ++j)
{
- DestroyAllocation(allocations[i]);
- allocations.erase(allocations.begin() + i);
+ for (size_t i = 0; i < 400; ++i)
+ {
+ bufCreateInfo.size = RandomBufSize();
+
+ AllocInfo allocInfo;
+ CreateBuffer(allocCreateInfo, bufCreateInfo, false, allocInfo);
+ allocations.push_back(allocInfo);
+ }
+ for (size_t i = 0; i < 100; ++i)
+ {
+ imageCreateInfo.extent.width = RandomTexSize();
+ imageCreateInfo.extent.height = RandomTexSize();
+
+ AllocInfo allocInfo;
+ CreateImage(allocCreateInfo, imageCreateInfo, VK_IMAGE_LAYOUT_GENERAL, false, allocInfo);
+ allocations.push_back(allocInfo);
+ }
+
+ const uint32_t percentToDelete = 55;
+ const size_t numberToDelete = allocations.size() * percentToDelete / 100;
+ for (size_t i = 0; i < numberToDelete; ++i)
+ {
+ size_t indexToDelete = rand.Generate() % (uint32_t)allocations.size();
+ DestroyAllocation(allocations[indexToDelete]);
+ allocations.erase(allocations.begin() + indexToDelete);
+ }
+
+ // Non-movable allocations will be at the beginning of allocations array.
+ const uint32_t percentNonMovable = 20;
+ const size_t numberNonMovable = j == 0 ? 0 : (allocations.size() * percentNonMovable / 100);
+ for (size_t i = 0; i < numberNonMovable; ++i)
+ {
+ size_t indexNonMovable = i + rand.Generate() % (uint32_t)(allocations.size() - i);
+ if (indexNonMovable != i)
+ std::swap(allocations[i], allocations[indexNonMovable]);
+ }
+
+ // Set data for defragmentation retrieval
+ for (auto& alloc : allocations)
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
+
+ std::wstring output = DefragmentationAlgorithmToStr(defragInfo.flags);
+ if (j == 0)
+ output += L"_NoMove";
+ else
+ output += L"_Move";
+ SaveAllocatorStatsToFile((output + L"_Before.json").c_str());
+
+ VmaDefragmentationContext defragCtx = nullptr;
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragInfo, &defragCtx);
+ TEST(res == VK_SUCCESS);
+
+ VmaDefragmentationPassMoveInfo pass;
+ while ((res = vmaBeginDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_INCOMPLETE)
+ {
+ VmaDefragmentationMove* end = pass.pMoves + pass.moveCount;
+ for (uint32_t i = 0; i < numberNonMovable; ++i)
+ {
+ VmaDefragmentationMove* move = std::find_if(pass.pMoves, end, [&](VmaDefragmentationMove& move) { return move.srcAllocation == allocations[i].m_Allocation; });
+ if (move != end)
+ move->operation = VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
+ }
+ for (uint32_t i = 0; i < pass.moveCount; ++i)
+ {
+ auto it = std::find_if(allocations.begin(), allocations.end(), [&](const AllocInfo& info) { return pass.pMoves[i].srcAllocation == info.m_Allocation; });
+ assert(it != allocations.end());
+ }
+
+ BeginSingleTimeCommands();
+ ProcessDefragmentationPass(pass);
+ EndSingleTimeCommands();
+
+ // Destroy old buffers/images and replace them with new handles.
+ for (size_t i = 0; i < pass.moveCount; ++i)
+ {
+ if (pass.pMoves[i].operation != VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE)
+ {
+ VmaAllocation const alloc = pass.pMoves[i].srcAllocation;
+ VmaAllocationInfo vmaAllocInfo;
+ vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
+ AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
+
+ if (allocInfo->m_Buffer)
+ {
+ assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
+ vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
+ allocInfo->m_Buffer = allocInfo->m_NewBuffer;
+ allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ }
+ else if (allocInfo->m_Image)
+ {
+ assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
+ vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
+ allocInfo->m_Image = allocInfo->m_NewImage;
+ allocInfo->m_NewImage = VK_NULL_HANDLE;
+ }
+ else
+ assert(0);
+ }
+ }
+
+ if ((res = vmaEndDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_SUCCESS)
+ break;
+ TEST(res == VK_INCOMPLETE);
+ }
+ TEST(res == VK_SUCCESS);
+
+ VmaDefragmentationStats defragStats;
+ res = vmaEndDefragmentation(g_hAllocator, defragCtx, &defragStats);
+ TEST(res == VK_SUCCESS);
+
+ SaveAllocatorStatsToFile((output + L"_After.json").c_str());
+ ValidateAllocationsData(allocations.data(), allocations.size());
+ DestroyAllAllocations(allocations);
}
-
- VmaDefragmentationInfo2 defragInfo = {};
- defragInfo.maxCpuAllocationsToMove = UINT32_MAX;
- defragInfo.maxCpuBytesToMove = VK_WHOLE_SIZE;
- std::vector allocationsToDefrag;
- if(caseIndex == 0)
- {
- defragInfo.poolCount = 1;
- defragInfo.pPools = &pool;
- }
- else
- {
- const size_t allocCount = allocations.size();
- allocationsToDefrag.resize(allocCount);
- std::transform(
- allocations.begin(), allocations.end(),
- allocationsToDefrag.begin(),
- [](const AllocInfo& allocInfo) { return allocInfo.m_Allocation; });
- defragInfo.allocationCount = (uint32_t)allocCount;
- defragInfo.pAllocations = allocationsToDefrag.data();
- }
-
- VmaDefragmentationContext defragCtx = VK_NULL_HANDLE;
- VkResult res = vmaDefragmentationBegin(g_hAllocator, &defragInfo, &defragStats[caseIndex], &defragCtx);
- TEST(res >= VK_SUCCESS);
- vmaDefragmentationEnd(g_hAllocator, defragCtx);
-
- TEST(defragStats[caseIndex].allocationsMoved > 0 && defragStats[caseIndex].bytesMoved > 0);
-
- ValidateAllocationsData(allocations.data(), allocations.size());
-
- DestroyAllAllocations(allocations);
-
- vmaDestroyPool(g_hAllocator, pool);
}
- TEST(defragStats[0].bytesMoved == defragStats[1].bytesMoved);
- TEST(defragStats[0].allocationsMoved == defragStats[1].allocationsMoved);
- TEST(defragStats[0].bytesFreed == defragStats[1].bytesFreed);
- TEST(defragStats[0].deviceMemoryBlocksFreed == defragStats[1].deviceMemoryBlocksFreed);
+ vmaDestroyPool(g_hAllocator, pool);
}
void TestDefragmentationFull()
@@ -1691,10 +2150,7 @@ void TestDefragmentationFull()
DestroyAllocation(allocations[index]);
allocations.erase(allocations.begin() + index);
}
-
- for(size_t i = 0; i < allocations.size(); ++i)
- ValidateAllocationData(allocations[i]);
-
+ //ValidateAllocationsData(allocations.data(), allocations.size()); // Ultra-slow
//SaveAllocatorStatsToFile(L"Before.csv");
{
@@ -1710,22 +2166,24 @@ void TestDefragmentationFull()
vmaAllocations.erase(vmaAllocations.begin() + index);
}
+ // Set data for defragmentation retrieval
+ for (auto& alloc : allocations)
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
+
const uint32_t defragCount = 1;
for(uint32_t defragIndex = 0; defragIndex < defragCount; ++defragIndex)
{
std::vector allocationsChanged(vmaAllocations.size());
- VmaDefragmentationInfo defragmentationInfo;
- defragmentationInfo.maxAllocationsToMove = UINT_MAX;
- defragmentationInfo.maxBytesToMove = SIZE_MAX;
+ VmaDefragmentationInfo defragmentationInfo = {};
+ defragmentationInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT;
wprintf(L"Defragmentation #%u\n", defragIndex);
time_point begTime = std::chrono::high_resolution_clock::now();
VmaDefragmentationStats stats;
- VkResult res = vmaDefragment(g_hAllocator, vmaAllocations.data(), vmaAllocations.size(), allocationsChanged.data(), &defragmentationInfo, &stats);
- TEST(res >= 0);
+ Defragment(defragmentationInfo, &stats);
float defragmentDuration = ToFloatSeconds(std::chrono::high_resolution_clock::now() - begTime);
@@ -1741,9 +2199,6 @@ void TestDefragmentationFull()
}
}
- for(size_t i = 0; i < allocations.size(); ++i)
- ValidateAllocationData(allocations[i]);
-
//wchar_t fileName[MAX_PATH];
//swprintf(fileName, MAX_PATH, L"After_%02u.csv", defragIndex);
//SaveAllocatorStatsToFile(fileName);
@@ -1751,6 +2206,7 @@ void TestDefragmentationFull()
}
// Destroy all remaining allocations.
+ //ValidateAllocationsData(allocations.data(), allocations.size()); // Ultra-slow
DestroyAllAllocations(allocations);
}
@@ -1773,7 +2229,6 @@ static void TestDefragmentationGpu()
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
- allocCreateInfo.flags = 0;
// Create all intended buffers.
for(size_t i = 0; i < bufCount; ++i)
@@ -1814,6 +2269,10 @@ static void TestDefragmentationGpu()
}
}
+ // Set data for defragmentation retrieval
+ for (auto& alloc : allocations)
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
+
// Fill them with meaningful data.
UploadGpuData(allocations.data(), allocations.size());
@@ -1843,25 +2302,9 @@ static void TestDefragmentationGpu()
const size_t movableAllocCount = allocationPtrs.size();
- BeginSingleTimeCommands();
-
- VmaDefragmentationInfo2 defragInfo = {};
- defragInfo.flags = 0;
- defragInfo.allocationCount = (uint32_t)movableAllocCount;
- defragInfo.pAllocations = allocationPtrs.data();
- defragInfo.pAllocationsChanged = allocationChanged.data();
- defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE;
- defragInfo.maxGpuAllocationsToMove = UINT32_MAX;
- defragInfo.commandBuffer = g_hTemporaryCommandBuffer;
-
- VmaDefragmentationStats stats = {};
- VmaDefragmentationContext ctx = VK_NULL_HANDLE;
- VkResult res = vmaDefragmentationBegin(g_hAllocator, &defragInfo, &stats, &ctx);
- TEST(res >= VK_SUCCESS);
-
- EndSingleTimeCommands();
-
- vmaDefragmentationEnd(g_hAllocator, ctx);
+ VmaDefragmentationInfo defragInfo = {};
+ VmaDefragmentationStats stats;
+ Defragment(defragInfo, &stats);
for(size_t i = 0; i < movableAllocCount; ++i)
{
@@ -1880,10 +2323,9 @@ static void TestDefragmentationGpu()
#endif
}
- ValidateGpuData(allocations.data(), allocations.size());
-
swprintf_s(fileName, L"GPU_defragmentation_B_after.json");
SaveAllocatorStatsToFile(fileName);
+ ValidateGpuData(allocations.data(), allocations.size());
// Destroy all remaining buffers.
for(size_t i = allocations.size(); i--; )
@@ -1892,187 +2334,6 @@ static void TestDefragmentationGpu()
}
}
-static void ProcessDefragmentationStepInfo(VmaDefragmentationPassInfo &stepInfo)
-{
- std::vector beginImageBarriers;
- std::vector finalizeImageBarriers;
-
- VkPipelineStageFlags beginSrcStageMask = 0;
- VkPipelineStageFlags beginDstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
-
- VkPipelineStageFlags finalizeSrcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- VkPipelineStageFlags finalizeDstStageMask = 0;
-
- bool wantsMemoryBarrier = false;
-
- VkMemoryBarrier beginMemoryBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
- VkMemoryBarrier finalizeMemoryBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
-
- for(uint32_t i = 0; i < stepInfo.moveCount; ++i)
- {
- VmaAllocationInfo info;
- vmaGetAllocationInfo(g_hAllocator, stepInfo.pMoves[i].allocation, &info);
-
- AllocInfo *allocInfo = (AllocInfo *)info.pUserData;
-
- if(allocInfo->m_Image)
- {
- VkImage newImage;
-
- const VkResult result = vkCreateImage(g_hDevice, &allocInfo->m_ImageInfo, g_Allocs, &newImage);
- TEST(result >= VK_SUCCESS);
-
- vkBindImageMemory(g_hDevice, newImage, stepInfo.pMoves[i].memory, stepInfo.pMoves[i].offset);
- allocInfo->m_NewImage = newImage;
-
- // Keep track of our pipeline stages that we need to wait/signal on
- beginSrcStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- finalizeDstStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
-
- // We need one pipeline barrier and two image layout transitions here
- // First we'll have to turn our newly created image into VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
- // And the second one is turning the old image into VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
-
- VkImageSubresourceRange subresourceRange = {
- VK_IMAGE_ASPECT_COLOR_BIT,
- 0, VK_REMAINING_MIP_LEVELS,
- 0, VK_REMAINING_ARRAY_LAYERS
- };
-
- VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.image = newImage;
- barrier.subresourceRange = subresourceRange;
-
- beginImageBarriers.push_back(barrier);
-
- // Second barrier to convert the existing image. This one actually needs a real barrier
- barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- barrier.oldLayout = allocInfo->m_ImageLayout;
- barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- barrier.image = allocInfo->m_Image;
-
- beginImageBarriers.push_back(barrier);
-
- // And lastly we need a barrier that turns our new image into the layout of the old one
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
- barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- barrier.newLayout = allocInfo->m_ImageLayout;
- barrier.image = newImage;
-
- finalizeImageBarriers.push_back(barrier);
- }
- else if(allocInfo->m_Buffer)
- {
- VkBuffer newBuffer;
-
- const VkResult result = vkCreateBuffer(g_hDevice, &allocInfo->m_BufferInfo, g_Allocs, &newBuffer);
- TEST(result >= VK_SUCCESS);
-
- vkBindBufferMemory(g_hDevice, newBuffer, stepInfo.pMoves[i].memory, stepInfo.pMoves[i].offset);
- allocInfo->m_NewBuffer = newBuffer;
-
- // Keep track of our pipeline stages that we need to wait/signal on
- beginSrcStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- finalizeDstStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
-
- beginMemoryBarrier.srcAccessMask |= VK_ACCESS_MEMORY_WRITE_BIT;
- beginMemoryBarrier.dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT;
-
- finalizeMemoryBarrier.srcAccessMask |= VK_ACCESS_TRANSFER_WRITE_BIT;
- finalizeMemoryBarrier.dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT;
-
- wantsMemoryBarrier = true;
- }
- }
-
- if(!beginImageBarriers.empty() || wantsMemoryBarrier)
- {
- const uint32_t memoryBarrierCount = wantsMemoryBarrier ? 1 : 0;
-
- vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, beginSrcStageMask, beginDstStageMask, 0,
- memoryBarrierCount, &beginMemoryBarrier,
- 0, nullptr,
- (uint32_t)beginImageBarriers.size(), beginImageBarriers.data());
- }
-
- for(uint32_t i = 0; i < stepInfo.moveCount; ++ i)
- {
- VmaAllocationInfo info;
- vmaGetAllocationInfo(g_hAllocator, stepInfo.pMoves[i].allocation, &info);
-
- AllocInfo *allocInfo = (AllocInfo *)info.pUserData;
-
- if(allocInfo->m_Image)
- {
- std::vector imageCopies;
-
- // Copy all mips of the source image into the target image
- VkOffset3D offset = { 0, 0, 0 };
- VkExtent3D extent = allocInfo->m_ImageInfo.extent;
-
- VkImageSubresourceLayers subresourceLayers = {
- VK_IMAGE_ASPECT_COLOR_BIT,
- 0,
- 0, 1
- };
-
- for(uint32_t mip = 0; mip < allocInfo->m_ImageInfo.mipLevels; ++ mip)
- {
- subresourceLayers.mipLevel = mip;
-
- VkImageCopy imageCopy{
- subresourceLayers,
- offset,
- subresourceLayers,
- offset,
- extent
- };
-
- imageCopies.push_back(imageCopy);
-
- extent.width = std::max(uint32_t(1), extent.width >> 1);
- extent.height = std::max(uint32_t(1), extent.height >> 1);
- extent.depth = std::max(uint32_t(1), extent.depth >> 1);
- }
-
- vkCmdCopyImage(
- g_hTemporaryCommandBuffer,
- allocInfo->m_Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- allocInfo->m_NewImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- (uint32_t)imageCopies.size(), imageCopies.data());
- }
- else if(allocInfo->m_Buffer)
- {
- VkBufferCopy region = {
- 0,
- 0,
- allocInfo->m_BufferInfo.size };
-
- vkCmdCopyBuffer(g_hTemporaryCommandBuffer,
- allocInfo->m_Buffer, allocInfo->m_NewBuffer,
- 1, ®ion);
- }
- }
-
- if(!finalizeImageBarriers.empty() || wantsMemoryBarrier)
- {
- const uint32_t memoryBarrierCount = wantsMemoryBarrier ? 1 : 0;
-
- vkCmdPipelineBarrier(g_hTemporaryCommandBuffer, finalizeSrcStageMask, finalizeDstStageMask, 0,
- memoryBarrierCount, &finalizeMemoryBarrier,
- 0, nullptr,
- (uint32_t)finalizeImageBarriers.size(), finalizeImageBarriers.data());
- }
-}
-
static void TestDefragmentationIncrementalBasic()
{
wprintf(L"Test defragmentation incremental basic\n");
@@ -2102,7 +2363,6 @@ static void TestDefragmentationIncrementalBasic()
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
- allocCreateInfo.flags = 0;
// Create all intended images.
for(size_t i = 0; i < imageCount; ++i)
@@ -2113,7 +2373,7 @@ static void TestDefragmentationIncrementalBasic()
imageInfo.extent.height = size;
AllocInfo alloc;
- alloc.CreateImage(imageInfo, allocCreateInfo, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+ CreateImage(allocCreateInfo, imageInfo, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, alloc);
alloc.m_StartValue = 0;
allocations.push_back(alloc);
@@ -2164,78 +2424,63 @@ static void TestDefragmentationIncrementalBasic()
// Defragment using GPU only.
{
- const size_t allocCount = allocations.size();
-
- std::vector allocationPtrs;
-
- for(size_t i = 0; i < allocCount; ++i)
- {
- allocationPtrs.push_back(allocations[i].m_Allocation);
- }
-
- const size_t movableAllocCount = allocationPtrs.size();
-
- VmaDefragmentationInfo2 defragInfo = {};
- defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_INCREMENTAL;
- defragInfo.allocationCount = (uint32_t)movableAllocCount;
- defragInfo.pAllocations = allocationPtrs.data();
- defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE;
- defragInfo.maxGpuAllocationsToMove = UINT32_MAX;
-
- VmaDefragmentationStats stats = {};
+ VmaDefragmentationInfo defragInfo = {};
VmaDefragmentationContext ctx = VK_NULL_HANDLE;
- VkResult res = vmaDefragmentationBegin(g_hAllocator, &defragInfo, &stats, &ctx);
- TEST(res >= VK_SUCCESS);
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragInfo, &ctx);
+ TEST(res == VK_SUCCESS);
- res = VK_NOT_READY;
-
- std::vector moveInfo;
- moveInfo.resize(movableAllocCount);
-
- while(res == VK_NOT_READY)
+ VmaDefragmentationPassMoveInfo pass;
+ while ((res = vmaBeginDefragmentationPass(g_hAllocator, ctx, &pass)) == VK_INCOMPLETE)
{
- VmaDefragmentationPassInfo stepInfo = {};
- stepInfo.pMoves = moveInfo.data();
- stepInfo.moveCount = (uint32_t)moveInfo.size();
-
- res = vmaBeginDefragmentationPass(g_hAllocator, ctx, &stepInfo);
- TEST(res >= VK_SUCCESS);
+ // Ignore data outside of test
+ for (uint32_t i = 0; i < pass.moveCount; ++i)
+ {
+ auto it = std::find_if(allocations.begin(), allocations.end(), [&](const AllocInfo& info) { return pass.pMoves[i].srcAllocation == info.m_Allocation; });
+ if (it == allocations.end())
+ pass.pMoves[i].operation = VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
+ }
BeginSingleTimeCommands();
- std::vector newHandles;
- ProcessDefragmentationStepInfo(stepInfo);
+ ProcessDefragmentationPass(pass);
EndSingleTimeCommands();
- res = vmaEndDefragmentationPass(g_hAllocator, ctx);
-
// Destroy old buffers/images and replace them with new handles.
- for(size_t i = 0; i < stepInfo.moveCount; ++i)
+ for (size_t i = 0; i < pass.moveCount; ++i)
{
- VmaAllocation const alloc = stepInfo.pMoves[i].allocation;
- VmaAllocationInfo vmaAllocInfo;
- vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
- AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
- if(allocInfo->m_Buffer)
+ if (pass.pMoves[i].operation != VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE)
{
- assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
- vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
- allocInfo->m_Buffer = allocInfo->m_NewBuffer;
- allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ VmaAllocation const alloc = pass.pMoves[i].srcAllocation;
+ VmaAllocationInfo vmaAllocInfo;
+ vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
+ AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
+
+ if (allocInfo->m_Buffer)
+ {
+ assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
+ vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
+ allocInfo->m_Buffer = allocInfo->m_NewBuffer;
+ allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ }
+ else if (allocInfo->m_Image)
+ {
+ assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
+ vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
+ allocInfo->m_Image = allocInfo->m_NewImage;
+ allocInfo->m_NewImage = VK_NULL_HANDLE;
+ }
+ else
+ assert(0);
}
- else if(allocInfo->m_Image)
- {
- assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
- vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
- allocInfo->m_Image = allocInfo->m_NewImage;
- allocInfo->m_NewImage = VK_NULL_HANDLE;
- }
- else
- assert(0);
}
+
+ if ((res = vmaEndDefragmentationPass(g_hAllocator, ctx, &pass)) == VK_SUCCESS)
+ break;
+ TEST(res == VK_INCOMPLETE);
}
- TEST(res >= VK_SUCCESS);
- vmaDefragmentationEnd(g_hAllocator, ctx);
+ TEST(res == VK_SUCCESS);
+ VmaDefragmentationStats stats = {};
+ vmaEndDefragmentation(g_hAllocator, ctx, &stats);
// If corruption detection is enabled, GPU defragmentation may not work on
// memory types that have this detection active, e.g. on Intel.
@@ -2286,7 +2531,6 @@ void TestDefragmentationIncrementalComplex()
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
- allocCreateInfo.flags = 0;
// Create all intended images.
for(size_t i = 0; i < imageCount; ++i)
@@ -2297,7 +2541,7 @@ void TestDefragmentationIncrementalComplex()
imageInfo.extent.height = size;
AllocInfo alloc;
- alloc.CreateImage(imageInfo, allocCreateInfo, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+ CreateImage(allocCreateInfo, imageInfo, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, alloc);
alloc.m_StartValue = 0;
allocations.push_back(alloc);
@@ -2331,12 +2575,8 @@ void TestDefragmentationIncrementalComplex()
{
// Set our user data pointers. A real application should probably be more clever here
- const size_t allocationCount = allocations.size();
- for(size_t i = 0; i < allocationCount; ++i)
- {
- AllocInfo &alloc = allocations[i];
+ for (auto& alloc : allocations)
vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &alloc);
- }
}
// Fill them with meaningful data.
@@ -2346,103 +2586,96 @@ void TestDefragmentationIncrementalComplex()
swprintf_s(fileName, L"GPU_defragmentation_incremental_complex_A_before.json");
SaveAllocatorStatsToFile(fileName);
+ const size_t maxAdditionalAllocations = 100;
std::vector additionalAllocations;
+ additionalAllocations.reserve(maxAdditionalAllocations);
#define MakeAdditionalAllocation() \
- do { \
- { \
- bufCreateInfo.size = align_up(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16); \
- bufCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; \
- \
- AllocInfo alloc; \
- alloc.CreateBuffer(bufCreateInfo, allocCreateInfo); \
- \
- additionalAllocations.push_back(alloc); \
- } \
- } while(0)
+ if (additionalAllocations.size() < maxAdditionalAllocations) \
+ { \
+ bufCreateInfo.size = align_up(bufSizeMin + rand.Generate() % (bufSizeMax - bufSizeMin), 16); \
+ bufCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; \
+ \
+ AllocInfo alloc; \
+ alloc.CreateBuffer(bufCreateInfo, allocCreateInfo); \
+ \
+ additionalAllocations.push_back(alloc); \
+ vmaSetAllocationUserData(g_hAllocator, alloc.m_Allocation, &additionalAllocations.back()); \
+ }
// Defragment using GPU only.
{
- const size_t allocCount = allocations.size();
+ VmaDefragmentationInfo defragInfo = {};
+ defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT;
- std::vector allocationPtrs;
-
- for(size_t i = 0; i < allocCount; ++i)
- {
- VmaAllocationInfo allocInfo = {};
- vmaGetAllocationInfo(g_hAllocator, allocations[i].m_Allocation, &allocInfo);
-
- allocationPtrs.push_back(allocations[i].m_Allocation);
- }
-
- const size_t movableAllocCount = allocationPtrs.size();
-
- VmaDefragmentationInfo2 defragInfo = {};
- defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_INCREMENTAL;
- defragInfo.allocationCount = (uint32_t)movableAllocCount;
- defragInfo.pAllocations = allocationPtrs.data();
- defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE;
- defragInfo.maxGpuAllocationsToMove = UINT32_MAX;
-
- VmaDefragmentationStats stats = {};
VmaDefragmentationContext ctx = VK_NULL_HANDLE;
- VkResult res = vmaDefragmentationBegin(g_hAllocator, &defragInfo, &stats, &ctx);
- TEST(res >= VK_SUCCESS);
-
- res = VK_NOT_READY;
-
- std::vector moveInfo;
- moveInfo.resize(movableAllocCount);
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragInfo, &ctx);
+ TEST(res == VK_SUCCESS);
MakeAdditionalAllocation();
- while(res == VK_NOT_READY)
+ VmaDefragmentationPassMoveInfo pass;
+ while((res = vmaBeginDefragmentationPass(g_hAllocator, ctx, &pass)) == VK_INCOMPLETE)
{
- VmaDefragmentationPassInfo stepInfo = {};
- stepInfo.pMoves = moveInfo.data();
- stepInfo.moveCount = (uint32_t)moveInfo.size();
+ MakeAdditionalAllocation();
- res = vmaBeginDefragmentationPass(g_hAllocator, ctx, &stepInfo);
- TEST(res >= VK_SUCCESS);
+ // Ignore data outside of test
+ for (uint32_t i = 0; i < pass.moveCount; ++i)
+ {
+ auto it = std::find_if(allocations.begin(), allocations.end(), [&](const AllocInfo& info) { return pass.pMoves[i].srcAllocation == info.m_Allocation; });
+ if (it == allocations.end())
+ {
+ auto it = std::find_if(additionalAllocations.begin(), additionalAllocations.end(), [&](const AllocInfo& info) { return pass.pMoves[i].srcAllocation == info.m_Allocation; });
+ if (it == additionalAllocations.end())
+ pass.pMoves[i].operation = VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE;
+ }
+ }
+
+ BeginSingleTimeCommands();
+ ProcessDefragmentationPass(pass);
+ EndSingleTimeCommands();
MakeAdditionalAllocation();
- BeginSingleTimeCommands();
- ProcessDefragmentationStepInfo(stepInfo);
- EndSingleTimeCommands();
-
- res = vmaEndDefragmentationPass(g_hAllocator, ctx);
-
// Destroy old buffers/images and replace them with new handles.
- for(size_t i = 0; i < stepInfo.moveCount; ++i)
+ for (size_t i = 0; i < pass.moveCount; ++i)
{
- VmaAllocation const alloc = stepInfo.pMoves[i].allocation;
- VmaAllocationInfo vmaAllocInfo;
- vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
- AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
- if(allocInfo->m_Buffer)
+ if (pass.pMoves[i].operation != VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE)
{
- assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
- vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
- allocInfo->m_Buffer = allocInfo->m_NewBuffer;
- allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ VmaAllocation const alloc = pass.pMoves[i].srcAllocation;
+ VmaAllocationInfo vmaAllocInfo;
+ vmaGetAllocationInfo(g_hAllocator, alloc, &vmaAllocInfo);
+ AllocInfo* allocInfo = (AllocInfo*)vmaAllocInfo.pUserData;
+
+ if (allocInfo->m_Buffer)
+ {
+ assert(allocInfo->m_NewBuffer && !allocInfo->m_Image && !allocInfo->m_NewImage);
+ vkDestroyBuffer(g_hDevice, allocInfo->m_Buffer, g_Allocs);
+ allocInfo->m_Buffer = allocInfo->m_NewBuffer;
+ allocInfo->m_NewBuffer = VK_NULL_HANDLE;
+ }
+ else if (allocInfo->m_Image)
+ {
+ assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
+ vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
+ allocInfo->m_Image = allocInfo->m_NewImage;
+ allocInfo->m_NewImage = VK_NULL_HANDLE;
+ }
+ else
+ assert(0);
}
- else if(allocInfo->m_Image)
- {
- assert(allocInfo->m_NewImage && !allocInfo->m_Buffer && !allocInfo->m_NewBuffer);
- vkDestroyImage(g_hDevice, allocInfo->m_Image, g_Allocs);
- allocInfo->m_Image = allocInfo->m_NewImage;
- allocInfo->m_NewImage = VK_NULL_HANDLE;
- }
- else
- assert(0);
}
+ if ((res = vmaEndDefragmentationPass(g_hAllocator, ctx, &pass)) == VK_SUCCESS)
+ break;
+ TEST(res == VK_INCOMPLETE);
+
MakeAdditionalAllocation();
}
- TEST(res >= VK_SUCCESS);
- vmaDefragmentationEnd(g_hAllocator, ctx);
+ TEST(res == VK_SUCCESS);
+ VmaDefragmentationStats stats = {};
+ vmaEndDefragmentation(g_hAllocator, ctx, &stats);
// If corruption detection is enabled, GPU defragmentation may not work on
// memory types that have this detection active, e.g. on Intel.
@@ -2862,7 +3095,7 @@ static void TestVirtualBlocksAlgorithms()
RandomNumberGenerator rand{3454335};
auto calcRandomAllocSize = [&rand]() -> VkDeviceSize { return rand.Generate() % 20 + 5; };
- for(size_t algorithmIndex = 0; algorithmIndex < 4; ++algorithmIndex)
+ for(size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
{
// Create the block
VmaVirtualBlockCreateInfo blockCreateInfo = {};
@@ -2871,8 +3104,6 @@ static void TestVirtualBlocksAlgorithms()
switch(algorithmIndex)
{
case 1: blockCreateInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT; break;
- case 2: blockCreateInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_BUDDY_ALGORITHM_BIT; break;
- case 3: blockCreateInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT; break;
}
VmaVirtualBlock block = nullptr;
VkResult res = vmaCreateVirtualBlock(&blockCreateInfo, &block);
@@ -3445,13 +3676,12 @@ static void TestDebugMargin()
TEST(vmaFindMemoryTypeIndexForBufferInfo(
g_hAllocator, &bufInfo, &allocCreateInfo, &poolCreateInfo.memoryTypeIndex) == VK_SUCCESS);
- for(size_t algorithmIndex = 0; algorithmIndex < 3; ++algorithmIndex)
+ for(size_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
{
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;
+ case 1: poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT; break;
default: assert(0);
}
VmaPool pool = VK_NULL_HANDLE;
@@ -3528,7 +3758,7 @@ static void TestDebugMarginNotInVirtualAllocator()
{
VmaVirtualBlockCreateInfo blockCreateInfo = {};
blockCreateInfo.size = ALLOCATION_COUNT * MEGABYTE;
- blockCreateInfo.flags = (algorithm == 1 ? VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT : 0);
+ blockCreateInfo.flags = (algorithm == 1 ? VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT : 0);
VmaVirtualBlock block = VK_NULL_HANDLE;
TEST(vmaCreateVirtualBlock(&blockCreateInfo, &block) == VK_SUCCESS);
@@ -4013,16 +4243,26 @@ static void TestAllocationAlgorithmsCorrectness()
const VkDeviceSize sizeUnit = isVirtual == 2 ? 1 : 0x10000;
const VkDeviceSize blockSize = (1llu << (LEVEL_COUNT - 1)) * sizeUnit;
- for(uint32_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
+ for(uint32_t algorithmIndex = 0; algorithmIndex < 1; ++algorithmIndex)
{
VmaPool pool = VK_NULL_HANDLE;
VmaVirtualBlock virtualBlock = VK_NULL_HANDLE;
+ uint32_t algorithm;
+ switch (algorithmIndex)
+ {
+ case 0:
+ algorithm = 0;
+ break;
+ default:
+ break;
+ }
+
if(isVirtual)
{
VmaVirtualBlockCreateInfo blockCreateInfo = {};
blockCreateInfo.pAllocationCallbacks = g_Allocs;
- blockCreateInfo.flags = algorithmIndex ? VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT : 0;
+ blockCreateInfo.flags = algorithm;
blockCreateInfo.size = blockSize;
TEST(vmaCreateVirtualBlock(&blockCreateInfo, &virtualBlock) == VK_SUCCESS);
}
@@ -4030,7 +4270,7 @@ static void TestAllocationAlgorithmsCorrectness()
{
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.blockSize = blockSize;
- poolCreateInfo.flags = algorithmIndex ? VMA_POOL_CREATE_TLSF_ALGORITHM_BIT : 0;
+ poolCreateInfo.flags = algorithm;
poolCreateInfo.minBlockCount = poolCreateInfo.maxBlockCount = 1;
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
@@ -4552,7 +4792,7 @@ static void BenchmarkAlgorithms(FILE* file)
for(uint32_t emptyIndex = 0; emptyIndex < emptyCount; ++emptyIndex)
{
- for(uint32_t algorithmIndex = 0; algorithmIndex < 4; ++algorithmIndex)
+ for(uint32_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
{
uint32_t algorithm = 0;
switch(algorithmIndex)
@@ -4560,14 +4800,8 @@ static void BenchmarkAlgorithms(FILE* file)
case 0:
break;
case 1:
- algorithm = VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT;
- break;
- case 2:
algorithm = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
break;
- case 3:
- algorithm = VMA_POOL_CREATE_TLSF_ALGORITHM_BIT;
- break;
default:
assert(0);
}
@@ -4777,14 +5011,27 @@ static void TestPool_SameSize()
// Defragment!
{
- std::vector allocationsToDefragment(items.size());
- for(size_t i = 0; i < items.size(); ++i)
- allocationsToDefragment[i] = items[i].Alloc;
+ VmaDefragmentationInfo defragmentationInfo = {};
+ defragmentationInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT;
+ defragmentationInfo.pool = pool;
+
+ VmaDefragmentationContext defragCtx = nullptr;
+ VkResult res = vmaBeginDefragmentation(g_hAllocator, &defragmentationInfo, &defragCtx);
+ TEST(res == VK_SUCCESS);
+
+ VmaDefragmentationPassMoveInfo pass;
+ while ((res = vmaBeginDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_INCOMPLETE)
+ {
+ if ((res = vmaEndDefragmentationPass(g_hAllocator, defragCtx, &pass)) == VK_SUCCESS)
+ break;
+ TEST(res == VK_INCOMPLETE);
+ }
+ TEST(res == VK_SUCCESS);
VmaDefragmentationStats defragmentationStats;
- res = vmaDefragment(g_hAllocator, allocationsToDefragment.data(), items.size(), nullptr, nullptr, &defragmentationStats);
+ res = vmaEndDefragmentation(g_hAllocator, defragCtx, &defragmentationStats);
TEST(res == VK_SUCCESS);
- TEST(defragmentationStats.deviceMemoryBlocksFreed == 2);
+ TEST(defragmentationStats.allocationsMoved == 24);
}
// Free all remaining items.
@@ -6879,7 +7126,7 @@ static void BasicTestTLSF()
VmaVirtualBlock block;
VmaVirtualBlockCreateInfo blockInfo = {};
- blockInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT;
+ blockInfo.flags = 0;
blockInfo.size = 50331648;
vmaCreateVirtualBlock(&blockInfo, &block);
@@ -6904,6 +7151,7 @@ static void BasicTestTLSF()
vmaDestroyVirtualBlock(block);
}
+#if 0
static void BasicTestBuddyAllocator()
{
wprintf(L"Basic test buddy allocator\n");
@@ -7007,6 +7255,7 @@ static void BasicTestBuddyAllocator()
vmaDestroyPool(g_hAllocator, pool);
}
+#endif // #if 0
static void BasicTestAllocatePages()
{
@@ -7187,7 +7436,7 @@ static void TestVirtualBlocksAlgorithmsBenchmark()
default: assert(0);
}
- for (uint8_t algorithmIndex = 0; algorithmIndex < 3; ++algorithmIndex)
+ for (uint8_t algorithmIndex = 0; algorithmIndex < 2; ++algorithmIndex)
{
switch (algorithmIndex)
{
@@ -7197,9 +7446,6 @@ static void TestVirtualBlocksAlgorithmsBenchmark()
case 1:
blockCreateInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT;
break;
- case 2:
- blockCreateInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT;
- break;
default:
assert(0);
}
@@ -7453,12 +7699,11 @@ void Test()
TestAllocationAlgorithmsCorrectness();
BasicTestTLSF();
- BasicTestBuddyAllocator();
BasicTestAllocatePages();
- if(VK_KHR_buffer_device_address_enabled)
+ if (VK_KHR_buffer_device_address_enabled)
TestBufferDeviceAddress();
- if(VK_EXT_memory_priority_enabled)
+ if (VK_EXT_memory_priority_enabled)
TestMemoryPriority();
{
@@ -7469,11 +7714,11 @@ void Test()
fclose(file);
}
- if(ConfigType >= CONFIG_TYPE_AVERAGE)
+ if (ConfigType >= CONFIG_TYPE_AVERAGE)
{
TestDefragmentationSimple();
+ TestDefragmentationAlgorithms();
TestDefragmentationFull();
- TestDefragmentationWholePool();
TestDefragmentationGpu();
TestDefragmentationIncrementalBasic();
TestDefragmentationIncrementalComplex();