diff --git a/docs/html/defragmentation.html b/docs/html/defragmentation.html
index 7fe71fc..ceb7eea 100644
--- a/docs/html/defragmentation.html
+++ b/docs/html/defragmentation.html
@@ -101,7 +101,7 @@ $(function() {
VkImage newImg;
res = vkCreateImage(device, &imgCreateInfo, nullptr, &newImg);
-
+
@@ -128,6 +128,7 @@ $(function() {
}
+VkResult vmaBindImageMemory(VmaAllocator allocator, VmaAllocation allocation, VkImage image)
Binds image to allocation.
void vmaEndDefragmentation(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationStats *pStats)
Ends defragmentation process.
void vmaGetAllocationInfo(VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo *pAllocationInfo)
Returns current information about specified allocation.
VkResult vmaBeginDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)
Starts single defragmentation pass.
@@ -140,33 +141,30 @@ $(function() {
Parameters for defragmentation.
Definition: vk_mem_alloc.h:1401
VmaPool pool
Custom pool to be defragmented.
Definition: vk_mem_alloc.h:1408
VmaDefragmentationFlags flags
Use combination of VmaDefragmentationFlagBits.
Definition: vk_mem_alloc.h:1403
-VkDeviceMemory dstMemory
Destination memory block where the allocation should be moved.
Definition: vk_mem_alloc.h:1429
-VkDeviceSize dstOffset
Destination offset where the allocation should be moved.
Definition: vk_mem_alloc.h:1431
-Parameters for incremental defragmentation steps.
Definition: vk_mem_alloc.h:1441
-uint32_t moveCount
Number of elements in the pMoves array.
Definition: vk_mem_alloc.h:1443
-VmaDefragmentationMove * pMoves
Array of moves to be performed by the user in the current defragmentation pass.
Definition: vk_mem_alloc.h:1467
+Parameters for incremental defragmentation steps.
Definition: vk_mem_alloc.h:1442
+uint32_t moveCount
Number of elements in the pMoves array.
Definition: vk_mem_alloc.h:1444
Although functions like vmaCreateBuffer(), vmaCreateImage(), vmaDestroyBuffer(), vmaDestroyImage() create/destroy an allocation and a buffer/image at once, these are just a shortcut for creating the resource, allocating memory, and binding them together. Defragmentation works on memory allocations only. You must handle the rest manually. Defragmentation is an iterative process that should repreat "passes" as long as related functions return VK_INCOMPLETE
not VK_SUCCESS
. In each pass:
- vmaBeginDefragmentationPass() function call:
- Calculates and returns the list of allocations to be moved in this pass. Note this can be a time-consuming process.
-- Reserves destination memory for them by creating internal allocations. Returns their
VkDeviceMemory
+ offset.
+- Reserves destination memory for them by creating temporary destination allocations that you can query for their
VkDeviceMemory
+ offset using vmaGetAllocationInfo().
- Inside the pass, you should:
- Inspect the returned list of allocations to be moved.
-- Create new buffers/images and bind them at the returned destination
VkDeviceMemory
+ offset.
+- Create new buffers/images and bind them at the returned destination temporary allocations.
- Copy data from source to destination resources if necessary.
- Destroy the source buffers/images, but NOT their allocations.
- vmaEndDefragmentationPass() function call:
- Frees the source memory reserved for the allocations that are moved.
-- Modifies VmaAllocation objects that are moved to point to the destination reserved memory.
+- Modifies source VmaAllocation objects that are moved to point to the destination reserved memory.
- Frees
VkDeviceMemory
blocks that became empty.
-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. 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.
+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. 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.
Inside a pass, for each allocation that should be moved:
- You should copy its data from the source to the destination place by calling e.g.
vkCmdCopyBuffer()
, vkCmdCopyImage()
.
@@ -175,12 +173,12 @@ $(function() {
- If a resource doesn't contain any meaningful data, e.g. it is a transient color attachment image to be cleared, filled, and used temporarily in each rendering frame, you can just recreate this image without copying its data.
- If the resource is in
HOST_VISIBLE
and HOST_COHERENT
memory, you can copy its data on the CPU using memcpy()
.
-- If you cannot move the allocation, you can set
pass.pMoves[i].operation
to VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE. This will cancel the move.
diff --git a/docs/html/functions.html b/docs/html/functions.html
index e14d24e..de199d2 100644
--- a/docs/html/functions.html
+++ b/docs/html/functions.html
@@ -88,8 +88,7 @@ $(function() {
- device : VmaAllocatorCreateInfo, VmaAllocatorInfo
- deviceMemory : VmaAllocationInfo
- deviceMemoryBlocksFreed : VmaDefragmentationStats
-- dstMemory : VmaDefragmentationMove
-- dstOffset : VmaDefragmentationMove
+- dstTmpAllocation : VmaDefragmentationMove
@@ -100,7 +99,6 @@ $(function() {
- i -
diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html
index e4a801e..f3dfd80 100644
--- a/docs/html/functions_vars.html
+++ b/docs/html/functions_vars.html
@@ -88,8 +88,7 @@ $(function() {
device : VmaAllocatorCreateInfo, VmaAllocatorInfo
deviceMemory : VmaAllocationInfo
deviceMemoryBlocksFreed : VmaDefragmentationStats
-dstMemory : VmaDefragmentationMove
-dstOffset : VmaDefragmentationMove
+dstTmpAllocation : VmaDefragmentationMove
@@ -100,7 +99,6 @@ $(function() {
- i -
diff --git a/docs/html/group__group__alloc.html b/docs/html/group__group__alloc.html
index 719170e..331f431 100644
--- a/docs/html/group__group__alloc.html
+++ b/docs/html/group__group__alloc.html
@@ -712,11 +712,11 @@ Functions
Operation performed on single defragmentation move. See structure VmaDefragmentationMove.
-Enumerator |
---|
VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY | 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().
+ |
Enumerator |
---|
VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY | Buffer/image has been recreated at dstTmpAllocation , 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_IGNORE | 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 | Set this value if you cannot move the allocation. New place reserved at dstTmpAllocation will be freed. srcAllocation will remain unchanged.
|
-VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY | 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 | Set this value if you decide to abandon the allocation and you destroyed the buffer/image. New place reserved at dstTmpAllocation will be freed, along with srcAllocation , which will be destroyed.
|
@@ -1862,7 +1862,7 @@ Functions
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:
If no more moves are possible you can end whole defragmentation.
diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js
index bc4a061..193d1da 100644
--- a/docs/html/search/all_3.js
+++ b/docs/html/search/all_3.js
@@ -6,6 +6,5 @@ var searchData=
['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']]],
- ['dstmemory_6',['dstMemory',['../struct_vma_defragmentation_move.html#a382fbec8dac2747abdc1883b69ef9458',1,'VmaDefragmentationMove']]],
- ['dstoffset_7',['dstOffset',['../struct_vma_defragmentation_move.html#a80c466b445bc272f82c7dbf1a971ba18',1,'VmaDefragmentationMove']]]
+ ['dsttmpallocation_6',['dstTmpAllocation',['../struct_vma_defragmentation_move.html#ab65b106adf209acd7313296d1075300e',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js
index be9f324..de9b72c 100644
--- a/docs/html/search/all_7.js
+++ b/docs/html/search/all_7.js
@@ -1,5 +1,4 @@
var searchData=
[
- ['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']]]
+ ['instance_0',['instance',['../struct_vma_allocator_create_info.html#a70dd42e29b1df1d1b9b61532ae0b370b',1,'VmaAllocatorCreateInfo::instance()'],['../struct_vma_allocator_info.html#a2ed6a4d2d3fea039d66a13f15d0ce5fe',1,'VmaAllocatorInfo::instance()']]]
];
diff --git a/docs/html/search/variables_2.js b/docs/html/search/variables_2.js
index b763c1a..4739a71 100644
--- a/docs/html/search/variables_2.js
+++ b/docs/html/search/variables_2.js
@@ -3,6 +3,5 @@ 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']]],
- ['dstmemory_3',['dstMemory',['../struct_vma_defragmentation_move.html#a382fbec8dac2747abdc1883b69ef9458',1,'VmaDefragmentationMove']]],
- ['dstoffset_4',['dstOffset',['../struct_vma_defragmentation_move.html#a80c466b445bc272f82c7dbf1a971ba18',1,'VmaDefragmentationMove']]]
+ ['dsttmpallocation_3',['dstTmpAllocation',['../struct_vma_defragmentation_move.html#ab65b106adf209acd7313296d1075300e',1,'VmaDefragmentationMove']]]
];
diff --git a/docs/html/search/variables_4.js b/docs/html/search/variables_4.js
index be9f324..de9b72c 100644
--- a/docs/html/search/variables_4.js
+++ b/docs/html/search/variables_4.js
@@ -1,5 +1,4 @@
var searchData=
[
- ['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']]]
+ ['instance_0',['instance',['../struct_vma_allocator_create_info.html#a70dd42e29b1df1d1b9b61532ae0b370b',1,'VmaAllocatorCreateInfo::instance()'],['../struct_vma_allocator_info.html#a2ed6a4d2d3fea039d66a13f15d0ce5fe',1,'VmaAllocatorInfo::instance()']]]
];
diff --git a/docs/html/struct_vma_defragmentation_move-members.html b/docs/html/struct_vma_defragmentation_move-members.html
index 056f74d..7aac213 100644
--- a/docs/html/struct_vma_defragmentation_move-members.html
+++ b/docs/html/struct_vma_defragmentation_move-members.html
@@ -68,9 +68,7 @@ $(function() {
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
index f9a3f4c..444d782 100644
--- a/docs/html/struct_vma_defragmentation_move.html
+++ b/docs/html/struct_vma_defragmentation_move.html
@@ -75,69 +75,32 @@ $(function() {
|
VmaDefragmentationMoveOperation | operation |
- | Operation to be performed on the allocation by vmaEndDefragmentationPass(). Default value is VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY. You can modify it. More...
|
+ | Operation to be performed on the allocation by vmaEndDefragmentationPass(). Default value is VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY. You can modify it. More...
|
|
VmaAllocation | srcAllocation |
| Allocation that should be moved. More...
|
|
-VkDeviceMemory | dstMemory |
- | Destination memory block where the allocation should be moved. More...
|
- |
-VkDeviceSize | dstOffset |
- | Destination offset where the allocation should be moved. More...
|
- |
-void * | internalData |
- | Internal data used by VMA. Do not use or modify! More...
|
- |
+VmaAllocation | dstTmpAllocation |
+ | Temporary allocation pointing to destination memory that will replace srcAllocation . More...
|
+ |
Single move of an allocation to be done for defragmentation.
-
-◆ dstMemory
+
+◆ dstTmpAllocation
- VkDeviceMemory VmaDefragmentationMove::dstMemory |
+ VmaAllocation VmaDefragmentationMove::dstTmpAllocation |
-
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!
+
Temporary allocation pointing to destination memory that will replace srcAllocation
.
+
- Warning
- Do not store this allocation in your data structures! It exists only temporarily, for the duration of the defragmentation pass, to be used for binding new buffer/image to the destination memory using e.g. vmaBindBufferMemory(). vmaEndDefragmentationPass() will destroy it and make
srcAllocation
point to this memory.
@@ -153,7 +116,7 @@ Public Attributes
diff --git a/docs/html/struct_vma_defragmentation_pass_move_info.html b/docs/html/struct_vma_defragmentation_pass_move_info.html
index ea8a5a6..91d3950 100644
--- a/docs/html/struct_vma_defragmentation_pass_move_info.html
+++ b/docs/html/struct_vma_defragmentation_pass_move_info.html
@@ -117,13 +117,13 @@ Public Attributes
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.
+- 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 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.
diff --git a/docs/html/virtual_allocator.html b/docs/html/virtual_allocator.html
index 4df5f65..f233ca2 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:1492
-VkDeviceSize size
Total size of the virtual block.
Definition: vk_mem_alloc.h:1498
+Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().
Definition: vk_mem_alloc.h:1493
+VkDeviceSize size
Total size of the virtual block.
Definition: vk_mem_alloc.h:1499
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:1513
-VkDeviceSize size
Size of the allocation.
Definition: vk_mem_alloc.h:1518
+Parameters of created virtual allocation to be passed to vmaVirtualAllocate().
Definition: vk_mem_alloc.h:1514
+VkDeviceSize size
Size of the allocation.
Definition: vk_mem_alloc.h:1519
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:1536
-void * pUserData
Custom pointer associated with the allocation.
Definition: vk_mem_alloc.h:1551
+Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().
Definition: vk_mem_alloc.h:1537
+void * pUserData
Custom pointer associated with the allocation.
Definition: vk_mem_alloc.h:1552
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:1523
+VkDeviceSize alignment
Required alignment of the allocation. Optional.
Definition: vk_mem_alloc.h:1524
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
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index b246f71..56d06c0 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -735,11 +735,11 @@ typedef VkFlags VmaDefragmentationFlags;
/// Operation performed on single defragmentation move. See structure #VmaDefragmentationMove.
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().
+ /// Buffer/image has been recreated at `dstTmpAllocation`, 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.
+ /// Set this value if you cannot move the allocation. New place reserved at `dstTmpAllocation` 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`.
+ /// Set this value if you decide to abandon the allocation and you destroyed the buffer/image. New place reserved at `dstTmpAllocation` will be freed, along with `srcAllocation`, which will be destroyed.
VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY = 2,
} VmaDefragmentationMoveOperation;
@@ -1425,12 +1425,13 @@ typedef struct VmaDefragmentationMove
VmaDefragmentationMoveOperation operation;
/// Allocation that should be moved.
VmaAllocation VMA_NOT_NULL srcAllocation;
- /// Destination memory block where the allocation should be moved.
- VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE 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;
+ /** \brief Temporary allocation pointing to destination memory that will replace `srcAllocation`.
+
+ \warning Do not store this allocation in your data structures! It exists only temporarily, for the duration of the defragmentation pass,
+ to be used for binding new buffer/image to the destination memory using e.g. vmaBindBufferMemory().
+ vmaEndDefragmentationPass() will destroy it and make `srcAllocation` point to this memory.
+ */
+ VmaAllocation VMA_NOT_NULL dstTmpAllocation;
} VmaDefragmentationMove;
/** \brief Parameters for incremental defragmentation steps.
@@ -13141,13 +13142,12 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
vector = m_pBlockVectors[vectorIndex];
VMA_ASSERT(vector != VMA_NULL);
}
-
- VmaAllocation dst = reinterpret_cast(move.internalData);
+
switch (move.operation)
{
case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY:
{
- uint8_t mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, dst);
+ uint8_t mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation);
if (mapCount > 0)
{
allocator = vector->m_hAllocator;
@@ -13170,9 +13170,9 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
{
VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
prevCount = vector->GetBlockCount();
- freedBlockSize = dst->GetBlock()->m_pMetadata->GetSize();
+ freedBlockSize = move.dstTmpAllocation->GetBlock()->m_pMetadata->GetSize();
}
- vector->Free(dst, false);
+ vector->Free(move.dstTmpAllocation, false);
{
VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
currentCount = vector->GetBlockCount();
@@ -13185,7 +13185,7 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
{
m_PassStats.bytesMoved -= move.srcAllocation->GetSize();
--m_PassStats.allocationsMoved;
- vector->Free(dst, false);
+ vector->Free(move.dstTmpAllocation, false);
VmaDeviceMemoryBlock* newBlock = move.srcAllocation->GetBlock();
bool notPresent = true;
@@ -13221,9 +13221,9 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
VkDeviceSize dstBlockSize;
{
VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
- dstBlockSize = dst->GetBlock()->m_pMetadata->GetSize();
+ dstBlockSize = move.dstTmpAllocation->GetBlock()->m_pMetadata->GetSize();
}
- vector->Free(dst, false);
+ vector->Free(move.dstTmpAllocation, false);
{
VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
freedBlockSize += dstBlockSize * (currentCount - vector->GetBlockCount());
@@ -13430,8 +13430,7 @@ bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, Vma
case CounterStatus::Pass:
break;
}
- VmaAllocation& dst = reinterpret_cast(moveData.move.internalData);
-
+
VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
if (offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
{
@@ -13453,12 +13452,9 @@ bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, Vma
moveData.flags,
this,
moveData.type,
- &dst) == VK_SUCCESS)
+ &moveData.move.dstTmpAllocation) == VK_SUCCESS)
{
- moveData.move.dstMemory = dst->GetMemory();
- moveData.move.dstOffset = dst->GetOffset();
m_Moves.push_back(moveData.move);
-
if (IncrementCounters(moveData.size))
return true;
}
@@ -13471,8 +13467,6 @@ bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, Vma
bool VmaDefragmentationContext_T::AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector)
{
- VmaAllocation& dst = reinterpret_cast(data.move.internalData);
-
for (; start < end; ++start)
{
VmaDeviceMemoryBlock* dstBlock = vector.GetBlock(start);
@@ -13485,12 +13479,9 @@ bool VmaDefragmentationContext_T::AllocInOtherBlock(size_t start, size_t end, Mo
this,
data.type,
0,
- &dst) == VK_SUCCESS)
+ &data.move.dstTmpAllocation) == VK_SUCCESS)
{
- data.move.dstMemory = dst->GetMemory();
- data.move.dstOffset = dst->GetOffset();
m_Moves.push_back(data.move);
-
if (IncrementCounters(data.size))
return true;
break;
@@ -13603,7 +13594,6 @@ bool VmaDefragmentationContext_T::ComputeDefragmentation_Balanced(VmaBlockVector
{
if (metadata->GetAllocationOffset(request.allocHandle) < offset)
{
- VmaAllocation& dst = reinterpret_cast(moveData.move.internalData);
if (vector.CommitAllocationRequest(
request,
block,
@@ -13611,12 +13601,9 @@ bool VmaDefragmentationContext_T::ComputeDefragmentation_Balanced(VmaBlockVector
moveData.flags,
this,
moveData.type,
- &dst) == VK_SUCCESS)
+ &moveData.move.dstTmpAllocation) == VK_SUCCESS)
{
- moveData.move.dstMemory = dst->GetMemory();
- moveData.move.dstOffset = dst->GetOffset();
m_Moves.push_back(moveData.move);
-
if (IncrementCounters(moveData.size))
return true;
}
@@ -13687,7 +13674,6 @@ bool VmaDefragmentationContext_T::ComputeDefragmentation_Full(VmaBlockVector& ve
{
if (metadata->GetAllocationOffset(request.allocHandle) < offset)
{
- VmaAllocation& dst = reinterpret_cast(moveData.move.internalData);
if (vector.CommitAllocationRequest(
request,
block,
@@ -13695,12 +13681,9 @@ bool VmaDefragmentationContext_T::ComputeDefragmentation_Full(VmaBlockVector& ve
moveData.flags,
this,
moveData.type,
- &dst) == VK_SUCCESS)
+ &moveData.move.dstTmpAllocation) == VK_SUCCESS)
{
- moveData.move.dstMemory = dst->GetMemory();
- moveData.move.dstOffset = dst->GetOffset();
m_Moves.push_back(moveData.move);
-
if (IncrementCounters(moveData.size))
return true;
}
@@ -18282,7 +18265,7 @@ for(;;)
VkImage newImg;
res = vkCreateImage(device, &imgCreateInfo, nullptr, &newImg);
// Check res...
- res = vKBindImageMemory(device, newImg, pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset);
+ res = vmaBindImageMemory(allocator, pMoves[i].dstTmpAllocation, newImg);
// Check res...
// Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place.
@@ -18322,16 +18305,16 @@ In each pass:
1. vmaBeginDefragmentationPass() function call:
- Calculates and returns the list of allocations to be moved in this pass.
Note this can be a time-consuming process.
- - Reserves destination memory for them by creating internal allocations.
- Returns their `VkDeviceMemory` + offset.
+ - Reserves destination memory for them by creating temporary destination allocations
+ that you can query for their `VkDeviceMemory` + offset using vmaGetAllocationInfo().
2. Inside the pass, **you should**:
- Inspect the returned list of allocations to be moved.
- - Create new buffers/images and bind them at the returned destination `VkDeviceMemory` + offset.
+ - Create new buffers/images and bind them at the returned destination temporary allocations.
- Copy data from source to destination resources if necessary.
- Destroy the source buffers/images, but NOT their allocations.
3. vmaEndDefragmentationPass() function call:
- Frees the source memory reserved for the allocations that are moved.
- - Modifies #VmaAllocation objects that are moved to point to the destination reserved memory.
+ - Modifies source #VmaAllocation objects that are moved to point to the destination reserved memory.
- Frees `VkDeviceMemory` blocks that became empty.
Unlike in previous iterations of the defragmentation API, there is no list of "movable" allocations passed as a parameter.
@@ -18356,7 +18339,7 @@ Inside a pass, for each allocation that should be moved:
not the source memory of the allocation, leaving it unchanged.
- If you decide the allocation is unimportant and can be destroyed instead of moved (e.g. it wasn't used for long time),
you can set `pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY.
- - vmaEndDefragmentationPass() will then free both source and destination memory, and will destroy the #VmaAllocation object.
+ - vmaEndDefragmentationPass() will then free both source and destination memory, and will destroy the source #VmaAllocation object.
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.
diff --git a/src/Tests.cpp b/src/Tests.cpp
index 26e0323..e551c1d 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -1442,7 +1442,7 @@ static void ProcessDefragmentationPass(VmaDefragmentationPassMoveInfo& stepInfo)
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);
+ vmaBindImageMemory(g_hAllocator, stepInfo.pMoves[i].dstTmpAllocation, newImage);
allocInfo->m_NewImage = newImage;
// Keep track of our pipeline stages that we need to wait/signal on
@@ -1496,7 +1496,7 @@ static void ProcessDefragmentationPass(VmaDefragmentationPassMoveInfo& stepInfo)
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);
+ vmaBindBufferMemory(g_hAllocator, stepInfo.pMoves[i].dstTmpAllocation, newBuffer);
allocInfo->m_NewBuffer = newBuffer;
// Keep track of our pipeline stages that we need to wait/signal on