mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-05 04:10:06 +00:00
Version 2.0.0-alpha.7. Removed VmaAllocatorCreateInfo::preferredSmallHeapBlockSize. VmaBlockVector::Allocate: New algorithm that allocates 1/8, 1/4, 1/2 of preferred block size as first blocks, to save memory.
This commit is contained in:
parent
6ee1560d4d
commit
a82e18346e
Binary file not shown.
@ -189,9 +189,6 @@ $(function() {
|
||||
<li>preferredLargeHeapBlockSize
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
<li>preferredSmallHeapBlockSize
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
<li>pUserData
|
||||
: <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">VmaAllocationCreateInfo</a>
|
||||
, <a class="el" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">VmaAllocationInfo</a>
|
||||
|
@ -189,9 +189,6 @@ $(function() {
|
||||
<li>preferredLargeHeapBlockSize
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
<li>preferredSmallHeapBlockSize
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
<li>pUserData
|
||||
: <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">VmaAllocationCreateInfo</a>
|
||||
, <a class="el" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">VmaAllocationInfo</a>
|
||||
|
@ -62,7 +62,7 @@ $(function() {
|
||||
<div class="title">Vulkan Memory Allocator </div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock"><p><b>Version 2.0.0-alpha.6</b> (2017-11-13)</p>
|
||||
<div class="textblock"><p><b>Version 2.0.0-alpha.7</b> (2018-02-09)</p>
|
||||
<p>Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. <br />
|
||||
License: MIT</p>
|
||||
<p>Documentation of all members: <a class="el" href="vk__mem__alloc_8h.html">vk_mem_alloc.h</a></p>
|
||||
|
@ -12,7 +12,6 @@ var searchData=
|
||||
['pool',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
|
||||
['preferredflags',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
|
||||
['preferredlargeheapblocksize',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
|
||||
['preferredsmallheapblocksize',['preferredSmallHeapBlockSize',['../struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a',1,'VmaAllocatorCreateInfo']]],
|
||||
['puserdata',['pUserData',['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()']]],
|
||||
['pvulkanfunctions',['pVulkanFunctions',['../struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd',1,'VmaAllocatorCreateInfo']]]
|
||||
];
|
||||
|
@ -10,7 +10,6 @@ var searchData=
|
||||
['pool',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
|
||||
['preferredflags',['preferredFlags',['../struct_vma_allocation_create_info.html#a7fe8d81a1ad10b2a2faacacee5b15d6d',1,'VmaAllocationCreateInfo']]],
|
||||
['preferredlargeheapblocksize',['preferredLargeHeapBlockSize',['../struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a',1,'VmaAllocatorCreateInfo']]],
|
||||
['preferredsmallheapblocksize',['preferredSmallHeapBlockSize',['../struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a',1,'VmaAllocatorCreateInfo']]],
|
||||
['puserdata',['pUserData',['../struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19',1,'VmaAllocationCreateInfo::pUserData()'],['../struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13',1,'VmaAllocationInfo::pUserData()']]],
|
||||
['pvulkanfunctions',['pVulkanFunctions',['../struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd',1,'VmaAllocatorCreateInfo']]]
|
||||
];
|
||||
|
@ -73,8 +73,7 @@ $(function() {
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">preferredSmallHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
</table></div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
|
@ -83,11 +83,8 @@ Public Attributes</h2></td></tr>
|
||||
<tr class="memdesc:ad924ddd77b04039c88d0c09b0ffcd500"><td class="mdescLeft"> </td><td class="mdescRight">Vulkan device. <a href="#ad924ddd77b04039c88d0c09b0ffcd500">More...</a><br /></td></tr>
|
||||
<tr class="separator:ad924ddd77b04039c88d0c09b0ffcd500"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a8e4714298e3121cdd8b214a1ae7a637a"><td class="memItemLeft" align="right" valign="top">VkDeviceSize </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td></tr>
|
||||
<tr class="memdesc:a8e4714298e3121cdd8b214a1ae7a637a"><td class="mdescLeft"> </td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps. <a href="#a8e4714298e3121cdd8b214a1ae7a637a">More...</a><br /></td></tr>
|
||||
<tr class="memdesc:a8e4714298e3121cdd8b214a1ae7a637a"><td class="mdescLeft"> </td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps > 1 GiB. <a href="#a8e4714298e3121cdd8b214a1ae7a637a">More...</a><br /></td></tr>
|
||||
<tr class="separator:a8e4714298e3121cdd8b214a1ae7a637a"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:ab435423d84d5ab26e2c347c51771f90a"><td class="memItemLeft" align="right" valign="top">VkDeviceSize </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">preferredSmallHeapBlockSize</a></td></tr>
|
||||
<tr class="memdesc:ab435423d84d5ab26e2c347c51771f90a"><td class="mdescLeft"> </td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from small heaps <= 512 MiB. <a href="#ab435423d84d5ab26e2c347c51771f90a">More...</a><br /></td></tr>
|
||||
<tr class="separator:ab435423d84d5ab26e2c347c51771f90a"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a6e409087e3be55400d0e4ccbe43c608d"><td class="memItemLeft" align="right" valign="top">const VkAllocationCallbacks * </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a></td></tr>
|
||||
<tr class="memdesc:a6e409087e3be55400d0e4ccbe43c608d"><td class="mdescLeft"> </td><td class="mdescRight">Custom CPU memory allocation callbacks. <a href="#a6e409087e3be55400d0e4ccbe43c608d">More...</a><br /></td></tr>
|
||||
<tr class="separator:a6e409087e3be55400d0e4ccbe43c608d"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
@ -246,26 +243,9 @@ Public Attributes</h2></td></tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps. </p>
|
||||
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps > 1 GiB. </p>
|
||||
<p>Set to 0 to use default, which is currently 256 MiB. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="ab435423d84d5ab26e2c347c51771f90a"></a>
|
||||
<h2 class="memtitle"><span class="permalink"><a href="#ab435423d84d5ab26e2c347c51771f90a">◆ </a></span>preferredSmallHeapBlockSize</h2>
|
||||
|
||||
<div class="memitem">
|
||||
<div class="memproto">
|
||||
<table class="memname">
|
||||
<tr>
|
||||
<td class="memname">VkDeviceSize VmaAllocatorCreateInfo::preferredSmallHeapBlockSize</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from small heaps <= 512 MiB. </p>
|
||||
<p>Set to 0 to use default, which is currently 64 MiB. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="a3dc197be3227da7338b1643f70db36bd"></a>
|
||||
|
File diff suppressed because one or more lines are too long
@ -29,7 +29,7 @@ extern "C" {
|
||||
|
||||
/** \mainpage Vulkan Memory Allocator
|
||||
|
||||
<b>Version 2.0.0-alpha.6</b> (2017-11-13)
|
||||
<b>Version 2.0.0-alpha.7</b> (2018-02-09)
|
||||
|
||||
Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. \n
|
||||
License: MIT
|
||||
@ -784,12 +784,9 @@ typedef struct VmaAllocatorCreateInfo
|
||||
/// Vulkan device.
|
||||
/** It must be valid throughout whole lifetime of created allocator. */
|
||||
VkDevice device;
|
||||
/// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps.
|
||||
/// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps > 1 GiB.
|
||||
/** Set to 0 to use default, which is currently 256 MiB. */
|
||||
VkDeviceSize preferredLargeHeapBlockSize;
|
||||
/// Preferred size of a single `VkDeviceMemory` block to be allocated from small heaps <= 512 MiB.
|
||||
/** Set to 0 to use default, which is currently 64 MiB. */
|
||||
VkDeviceSize preferredSmallHeapBlockSize;
|
||||
/// Custom CPU memory allocation callbacks.
|
||||
/** Optional, can be null. When specified, will also be used for all CPU-side memory allocations. */
|
||||
const VkAllocationCallbacks* pAllocationCallbacks;
|
||||
@ -1858,17 +1855,12 @@ If providing your own implementation, you need to implement a subset of std::ato
|
||||
|
||||
#ifndef VMA_SMALL_HEAP_MAX_SIZE
|
||||
/// Maximum size of a memory heap in Vulkan to consider it "small".
|
||||
#define VMA_SMALL_HEAP_MAX_SIZE (512 * 1024 * 1024)
|
||||
#define VMA_SMALL_HEAP_MAX_SIZE (1024ull * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE
|
||||
/// Default size of a block allocated as single VkDeviceMemory from a "large" heap.
|
||||
#define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE
|
||||
/// Default size of a block allocated as single VkDeviceMemory from a "small" heap.
|
||||
#define VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE (64 * 1024 * 1024)
|
||||
#define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
static const uint32_t VMA_FRAME_INDEX_LOST = UINT32_MAX;
|
||||
@ -3660,6 +3652,8 @@ private:
|
||||
bool m_HasEmptyBlock;
|
||||
VmaDefragmentator* m_pDefragmentator;
|
||||
|
||||
size_t CalcMaxBlockSize() const;
|
||||
|
||||
// Finds and removes given block from vector.
|
||||
void Remove(VmaDeviceMemoryBlock* pBlock);
|
||||
|
||||
@ -3929,7 +3923,6 @@ struct VmaAllocator_T
|
||||
|
||||
private:
|
||||
VkDeviceSize m_PreferredLargeHeapBlockSize;
|
||||
VkDeviceSize m_PreferredSmallHeapBlockSize;
|
||||
|
||||
VkPhysicalDevice m_PhysicalDevice;
|
||||
VMA_ATOMIC_UINT32 m_CurrentFrameIndex;
|
||||
@ -5959,30 +5952,49 @@ VkResult VmaBlockVector::Allocate(
|
||||
// 2. Try to create new block.
|
||||
if(canCreateNewBlock)
|
||||
{
|
||||
// 2.1. Start with full preferredBlockSize.
|
||||
VkDeviceSize blockSize = m_PreferredBlockSize;
|
||||
size_t newBlockIndex = 0;
|
||||
VkResult res = CreateBlock(blockSize, &newBlockIndex);
|
||||
// Calculate optimal size for new block.
|
||||
VkDeviceSize newBlockSize = m_PreferredBlockSize;
|
||||
uint32_t newBlockSizeShift = 0;
|
||||
const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;
|
||||
|
||||
// Allocating blocks of other sizes is allowed only in default pools.
|
||||
// In custom pools block size is fixed.
|
||||
if(res < 0 && m_IsCustomPool == false)
|
||||
if(m_IsCustomPool == false)
|
||||
{
|
||||
// 2.2. Try half the size.
|
||||
blockSize /= 2;
|
||||
if(blockSize >= vkMemReq.size)
|
||||
// Allocate 1/8, 1/4, 1/2 as first blocks.
|
||||
const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize();
|
||||
for(uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i)
|
||||
{
|
||||
res = CreateBlock(blockSize, &newBlockIndex);
|
||||
if(res < 0)
|
||||
const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;
|
||||
if(smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= vkMemReq.size * 2)
|
||||
{
|
||||
// 2.3. Try quarter the size.
|
||||
blockSize /= 2;
|
||||
if(blockSize >= vkMemReq.size)
|
||||
{
|
||||
res = CreateBlock(blockSize, &newBlockIndex);
|
||||
newBlockSize = smallerNewBlockSize;
|
||||
++newBlockSizeShift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t newBlockIndex = 0;
|
||||
VkResult res = CreateBlock(newBlockSize, &newBlockIndex);
|
||||
// Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.
|
||||
if(m_IsCustomPool == false)
|
||||
{
|
||||
while(res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX)
|
||||
{
|
||||
const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;
|
||||
if(smallerNewBlockSize >= vkMemReq.size)
|
||||
{
|
||||
newBlockSize = smallerNewBlockSize;
|
||||
++newBlockSizeShift;
|
||||
res = CreateBlock(newBlockSize, &newBlockIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex];
|
||||
@ -6183,6 +6195,20 @@ void VmaBlockVector::Free(
|
||||
}
|
||||
}
|
||||
|
||||
size_t VmaBlockVector::CalcMaxBlockSize() const
|
||||
{
|
||||
size_t result = 0;
|
||||
for(size_t i = m_Blocks.size(); i--; )
|
||||
{
|
||||
result = VMA_MAX(result, m_Blocks[i]->m_Metadata.GetSize());
|
||||
if(result >= m_PreferredBlockSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock)
|
||||
{
|
||||
for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)
|
||||
@ -6707,7 +6733,6 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
||||
m_AllocationCallbacks(pCreateInfo->pAllocationCallbacks ?
|
||||
*pCreateInfo->pAllocationCallbacks : VmaEmptyAllocationCallbacks),
|
||||
m_PreferredLargeHeapBlockSize(0),
|
||||
m_PreferredSmallHeapBlockSize(0),
|
||||
m_PhysicalDevice(pCreateInfo->physicalDevice),
|
||||
m_CurrentFrameIndex(0),
|
||||
m_Pools(VmaStlAllocator<VmaPool>(GetAllocationCallbacks()))
|
||||
@ -6739,8 +6764,6 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
||||
|
||||
m_PreferredLargeHeapBlockSize = (pCreateInfo->preferredLargeHeapBlockSize != 0) ?
|
||||
pCreateInfo->preferredLargeHeapBlockSize : static_cast<VkDeviceSize>(VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);
|
||||
m_PreferredSmallHeapBlockSize = (pCreateInfo->preferredSmallHeapBlockSize != 0) ?
|
||||
pCreateInfo->preferredSmallHeapBlockSize : static_cast<VkDeviceSize>(VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE);
|
||||
|
||||
if(pCreateInfo->pHeapSizeLimit != VMA_NULL)
|
||||
{
|
||||
@ -6866,10 +6889,8 @@ VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)
|
||||
{
|
||||
const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);
|
||||
const VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size;
|
||||
const bool isSmallHeap = heapSize <= VMA_SMALL_HEAP_MAX_SIZE ||
|
||||
// HOST_CACHED memory type is treated as small despite it has full size of CPU memory heap, because we usually don't use much of it.
|
||||
(m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0;
|
||||
return isSmallHeap ? m_PreferredSmallHeapBlockSize : m_PreferredLargeHeapBlockSize;
|
||||
const bool isSmallHeap = heapSize <= VMA_SMALL_HEAP_MAX_SIZE;
|
||||
return isSmallHeap ? (heapSize / 8) : m_PreferredLargeHeapBlockSize;
|
||||
}
|
||||
|
||||
VkResult VmaAllocator_T::AllocateMemoryOfType(
|
||||
|
Loading…
Reference in New Issue
Block a user