Merge branch 'sparse_binding_example' into v2.2
# Conflicts: # docs/html/vk__mem__alloc_8h_source.html # src/Tests.cpp # src/VmaReplay/VmaReplay.cpp # src/VulkanSample.cpp # src/vk_mem_alloc.h
This commit is contained in:
commit
71db590d7d
15 changed files with 1501 additions and 132 deletions
|
@ -2484,7 +2484,7 @@ typedef struct VmaAllocationInfo {
|
|||
@param[out] pAllocation Handle to allocated memory.
|
||||
@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
|
||||
|
||||
You should free the memory using vmaFreeMemory().
|
||||
You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
|
||||
|
||||
It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(),
|
||||
vmaCreateBuffer(), vmaCreateImage() instead whenever possible.
|
||||
|
@ -2496,6 +2496,33 @@ VkResult vmaAllocateMemory(
|
|||
VmaAllocation* pAllocation,
|
||||
VmaAllocationInfo* pAllocationInfo);
|
||||
|
||||
/** \brief General purpose memory allocation for multiple allocation objects at once.
|
||||
|
||||
@param allocator Allocator object.
|
||||
@param pVkMemoryRequirements Memory requirements for each allocation.
|
||||
@param pCreateInfo Creation parameters for each alloction.
|
||||
@param allocationCount Number of allocations to make.
|
||||
@param[out] pAllocations Pointer to array that will be filled with handles to created allocations.
|
||||
@param[out] pAlocationInfo Optional. Pointer to array that will be filled with parameters of created allocations.
|
||||
|
||||
You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
|
||||
|
||||
Word "pages" is just a suggestion to use this function to allocate pieces of memory needed for sparse binding.
|
||||
It is just a general purpose allocation function able to make multiple allocations at once.
|
||||
It may be internally optimized to be more efficient than calling vmaAllocateMemory() `allocationCount` times.
|
||||
|
||||
All allocations are made using same parameters. All of them are created out of the same memory pool and type.
|
||||
If any allocation fails, all allocations already made within this function call are also freed, so that when
|
||||
returned result is not `VK_SUCCESS`, `pAllocation` array is always entirely filled with `VK_NULL_HANDLE`.
|
||||
*/
|
||||
VkResult vmaAllocateMemoryPages(
|
||||
VmaAllocator allocator,
|
||||
const VkMemoryRequirements* pVkMemoryRequirements,
|
||||
const VmaAllocationCreateInfo* pCreateInfo,
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations,
|
||||
VmaAllocationInfo* pAllocationInfo);
|
||||
|
||||
/**
|
||||
@param[out] pAllocation Handle to allocated memory.
|
||||
@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
|
||||
|
@ -2517,11 +2544,29 @@ VkResult vmaAllocateMemoryForImage(
|
|||
VmaAllocation* pAllocation,
|
||||
VmaAllocationInfo* pAllocationInfo);
|
||||
|
||||
/// Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage().
|
||||
/** \brief Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage().
|
||||
|
||||
Passing `VK_NULL_HANDLE` as `allocation` is valid. Such function call is just skipped.
|
||||
*/
|
||||
void vmaFreeMemory(
|
||||
VmaAllocator allocator,
|
||||
VmaAllocation allocation);
|
||||
|
||||
/** \brief Frees memory and destroys multiple allocations.
|
||||
|
||||
Word "pages" is just a suggestion to use this function to free pieces of memory used for sparse binding.
|
||||
It is just a general purpose function to free memory and destroy allocations made using e.g. vmaAllocateMemory(),
|
||||
vmaAllocateMemoryPages() and other functions.
|
||||
It may be internally optimized to be more efficient than calling vmaFreeMemory() `allocationCount` times.
|
||||
|
||||
Allocations in `pAllocations` array can come from any memory pools and types.
|
||||
Passing `VK_NULL_HANDLE` as elements of `pAllocations` array is valid. Such entries are just skipped.
|
||||
*/
|
||||
void vmaFreeMemoryPages(
|
||||
VmaAllocator allocator,
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations);
|
||||
|
||||
/** \brief Tries to resize an allocation in place, if there is enough free memory after it.
|
||||
|
||||
Tries to change allocation's size without moving or reallocating it.
|
||||
|
@ -5764,7 +5809,8 @@ public:
|
|||
VkDeviceSize alignment,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
VmaSuballocationType suballocType,
|
||||
VmaAllocation* pAllocation);
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations);
|
||||
|
||||
void Free(
|
||||
VmaAllocation hAllocation);
|
||||
|
@ -5831,6 +5877,15 @@ private:
|
|||
// after this call.
|
||||
void IncrementallySortBlocks();
|
||||
|
||||
VkResult AllocatePage(
|
||||
VmaPool hCurrentPool,
|
||||
uint32_t currentFrameIndex,
|
||||
VkDeviceSize size,
|
||||
VkDeviceSize alignment,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
VmaSuballocationType suballocType,
|
||||
VmaAllocation* pAllocation);
|
||||
|
||||
// To be used only without CAN_MAKE_OTHER_LOST flag.
|
||||
VkResult AllocateFromBlock(
|
||||
VmaDeviceMemoryBlock* pBlock,
|
||||
|
@ -6347,6 +6402,11 @@ public:
|
|||
const VkMemoryRequirements& vkMemReq,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
VmaAllocation allocation);
|
||||
void RecordAllocateMemoryPages(uint32_t frameIndex,
|
||||
const VkMemoryRequirements& vkMemReq,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
uint64_t allocationCount,
|
||||
const VmaAllocation* pAllocations);
|
||||
void RecordAllocateMemoryForBuffer(uint32_t frameIndex,
|
||||
const VkMemoryRequirements& vkMemReq,
|
||||
bool requiresDedicatedAllocation,
|
||||
|
@ -6361,6 +6421,9 @@ public:
|
|||
VmaAllocation allocation);
|
||||
void RecordFreeMemory(uint32_t frameIndex,
|
||||
VmaAllocation allocation);
|
||||
void RecordFreeMemoryPages(uint32_t frameIndex,
|
||||
uint64_t allocationCount,
|
||||
const VmaAllocation* pAllocations);
|
||||
void RecordResizeAllocation(
|
||||
uint32_t frameIndex,
|
||||
VmaAllocation allocation,
|
||||
|
@ -6443,6 +6506,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void PrintPointerList(uint64_t count, const VmaAllocation* pItems);
|
||||
void Flush();
|
||||
};
|
||||
|
||||
|
@ -6546,10 +6610,13 @@ public:
|
|||
VkImage dedicatedImage,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
VmaSuballocationType suballocType,
|
||||
VmaAllocation* pAllocation);
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations);
|
||||
|
||||
// Main deallocation function.
|
||||
void FreeMemory(const VmaAllocation allocation);
|
||||
void FreeMemory(
|
||||
size_t allocationCount,
|
||||
const VmaAllocation* pAllocations);
|
||||
|
||||
VkResult ResizeAllocation(
|
||||
const VmaAllocation alloc,
|
||||
|
@ -6632,9 +6699,21 @@ private:
|
|||
const VmaAllocationCreateInfo& createInfo,
|
||||
uint32_t memTypeIndex,
|
||||
VmaSuballocationType suballocType,
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations);
|
||||
|
||||
// Helper function only to be used inside AllocateDedicatedMemory.
|
||||
VkResult AllocateDedicatedMemoryPage(
|
||||
VkDeviceSize size,
|
||||
VmaSuballocationType suballocType,
|
||||
uint32_t memTypeIndex,
|
||||
const VkMemoryAllocateInfo& allocInfo,
|
||||
bool map,
|
||||
bool isUserDataString,
|
||||
void* pUserData,
|
||||
VmaAllocation* pAllocation);
|
||||
|
||||
// Allocates and registers new VkDeviceMemory specifically for single allocation.
|
||||
// Allocates and registers new VkDeviceMemory specifically for dedicated allocations.
|
||||
VkResult AllocateDedicatedMemory(
|
||||
VkDeviceSize size,
|
||||
VmaSuballocationType suballocType,
|
||||
|
@ -6644,7 +6723,8 @@ private:
|
|||
void* pUserData,
|
||||
VkBuffer dedicatedBuffer,
|
||||
VkImage dedicatedImage,
|
||||
VmaAllocation* pAllocation);
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations);
|
||||
|
||||
// Tries to free pMemory as Dedicated Memory. Returns true if found and freed.
|
||||
void FreeDedicatedMemory(VmaAllocation allocation);
|
||||
|
@ -11225,6 +11305,51 @@ bool VmaBlockVector::IsCorruptionDetectionEnabled() const
|
|||
static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32;
|
||||
|
||||
VkResult VmaBlockVector::Allocate(
|
||||
VmaPool hCurrentPool,
|
||||
uint32_t currentFrameIndex,
|
||||
VkDeviceSize size,
|
||||
VkDeviceSize alignment,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
VmaSuballocationType suballocType,
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations)
|
||||
{
|
||||
size_t allocIndex;
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
{
|
||||
VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex);
|
||||
for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
|
||||
{
|
||||
res = AllocatePage(
|
||||
hCurrentPool,
|
||||
currentFrameIndex,
|
||||
size,
|
||||
alignment,
|
||||
createInfo,
|
||||
suballocType,
|
||||
pAllocations + allocIndex);
|
||||
if(res != VK_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(res != VK_SUCCESS)
|
||||
{
|
||||
// Free all already created allocations.
|
||||
while(allocIndex--)
|
||||
{
|
||||
Free(pAllocations[allocIndex]);
|
||||
}
|
||||
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult VmaBlockVector::AllocatePage(
|
||||
VmaPool hCurrentPool,
|
||||
uint32_t currentFrameIndex,
|
||||
VkDeviceSize size,
|
||||
|
@ -11276,8 +11401,6 @@ VkResult VmaBlockVector::Allocate(
|
|||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
|
||||
VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex);
|
||||
|
||||
/*
|
||||
Under certain condition, this whole section can be skipped for optimization, so
|
||||
we move on directly to trying to allocate with canMakeOtherLost. That's the case
|
||||
|
@ -13371,6 +13494,32 @@ void VmaRecorder::RecordAllocateMemory(uint32_t frameIndex,
|
|||
Flush();
|
||||
}
|
||||
|
||||
void VmaRecorder::RecordAllocateMemoryPages(uint32_t frameIndex,
|
||||
const VkMemoryRequirements& vkMemReq,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
uint64_t allocationCount,
|
||||
const VmaAllocation* pAllocations)
|
||||
{
|
||||
CallParams callParams;
|
||||
GetBasicParams(callParams);
|
||||
|
||||
VmaMutexLock lock(m_FileMutex, m_UseMutex);
|
||||
UserDataString userDataStr(createInfo.flags, createInfo.pUserData);
|
||||
fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryPages,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,", callParams.threadId, callParams.time, frameIndex,
|
||||
vkMemReq.size,
|
||||
vkMemReq.alignment,
|
||||
vkMemReq.memoryTypeBits,
|
||||
createInfo.flags,
|
||||
createInfo.usage,
|
||||
createInfo.requiredFlags,
|
||||
createInfo.preferredFlags,
|
||||
createInfo.memoryTypeBits,
|
||||
createInfo.pool);
|
||||
PrintPointerList(allocationCount, pAllocations);
|
||||
fprintf(m_File, ",%s\n", userDataStr.GetString());
|
||||
Flush();
|
||||
}
|
||||
|
||||
void VmaRecorder::RecordAllocateMemoryForBuffer(uint32_t frameIndex,
|
||||
const VkMemoryRequirements& vkMemReq,
|
||||
bool requiresDedicatedAllocation,
|
||||
|
@ -13441,6 +13590,20 @@ void VmaRecorder::RecordFreeMemory(uint32_t frameIndex,
|
|||
Flush();
|
||||
}
|
||||
|
||||
void VmaRecorder::RecordFreeMemoryPages(uint32_t frameIndex,
|
||||
uint64_t allocationCount,
|
||||
const VmaAllocation* pAllocations)
|
||||
{
|
||||
CallParams callParams;
|
||||
GetBasicParams(callParams);
|
||||
|
||||
VmaMutexLock lock(m_FileMutex, m_UseMutex);
|
||||
fprintf(m_File, "%u,%.3f,%u,vmaFreeMemoryPages,", callParams.threadId, callParams.time, frameIndex);
|
||||
PrintPointerList(allocationCount, pAllocations);
|
||||
fprintf(m_File, "\n");
|
||||
Flush();
|
||||
}
|
||||
|
||||
void VmaRecorder::RecordResizeAllocation(
|
||||
uint32_t frameIndex,
|
||||
VmaAllocation allocation,
|
||||
|
@ -13767,6 +13930,18 @@ void VmaRecorder::GetBasicParams(CallParams& outParams)
|
|||
outParams.time = (double)(counter.QuadPart - m_StartCounter) / (double)m_Freq;
|
||||
}
|
||||
|
||||
void VmaRecorder::PrintPointerList(uint64_t count, const VmaAllocation* pItems)
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
fprintf(m_File, "%p", pItems[0]);
|
||||
for(uint64_t i = 1; i < count; ++i)
|
||||
{
|
||||
fprintf(m_File, " %p", pItems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VmaRecorder::Flush()
|
||||
{
|
||||
if((m_Flags & VMA_RECORD_FLUSH_AFTER_CALL_BIT) != 0)
|
||||
|
@ -14033,10 +14208,11 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
|
|||
const VmaAllocationCreateInfo& createInfo,
|
||||
uint32_t memTypeIndex,
|
||||
VmaSuballocationType suballocType,
|
||||
VmaAllocation* pAllocation)
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations)
|
||||
{
|
||||
VMA_ASSERT(pAllocation != VMA_NULL);
|
||||
VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, Size=%llu", memTypeIndex, vkMemReq.size);
|
||||
VMA_ASSERT(pAllocations != VMA_NULL);
|
||||
VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, AllocationCount=%zu, Size=%llu", memTypeIndex, allocationCount, vkMemReq.size);
|
||||
|
||||
VmaAllocationCreateInfo finalCreateInfo = createInfo;
|
||||
|
||||
|
@ -14081,7 +14257,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
|
|||
finalCreateInfo.pUserData,
|
||||
dedicatedBuffer,
|
||||
dedicatedImage,
|
||||
pAllocation);
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -14093,7 +14270,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
|
|||
alignment,
|
||||
finalCreateInfo,
|
||||
suballocType,
|
||||
pAllocation);
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
return res;
|
||||
|
@ -14115,7 +14293,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
|
|||
finalCreateInfo.pUserData,
|
||||
dedicatedBuffer,
|
||||
dedicatedImage,
|
||||
pAllocation);
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
// Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.
|
||||
|
@ -14141,9 +14320,10 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
|
|||
void* pUserData,
|
||||
VkBuffer dedicatedBuffer,
|
||||
VkImage dedicatedImage,
|
||||
VmaAllocation* pAllocation)
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations)
|
||||
{
|
||||
VMA_ASSERT(pAllocation);
|
||||
VMA_ASSERT(allocationCount > 0 && pAllocations);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
allocInfo.memoryTypeIndex = memTypeIndex;
|
||||
|
@ -14167,7 +14347,80 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
|
|||
}
|
||||
#endif // #if VMA_DEDICATED_ALLOCATION
|
||||
|
||||
// Allocate VkDeviceMemory.
|
||||
size_t allocIndex;
|
||||
VkResult res;
|
||||
for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
|
||||
{
|
||||
res = AllocateDedicatedMemoryPage(
|
||||
size,
|
||||
suballocType,
|
||||
memTypeIndex,
|
||||
allocInfo,
|
||||
map,
|
||||
isUserDataString,
|
||||
pUserData,
|
||||
pAllocations + allocIndex);
|
||||
if(res != VK_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
// Register them in m_pDedicatedAllocations.
|
||||
{
|
||||
VmaMutexLockWrite lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||
AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];
|
||||
VMA_ASSERT(pDedicatedAllocations);
|
||||
for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
|
||||
{
|
||||
VmaVectorInsertSorted<VmaPointerLess>(*pDedicatedAllocations, pAllocations[allocIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
VMA_DEBUG_LOG(" Allocated DedicatedMemory Count=%zu, MemoryTypeIndex=#%u", allocationCount, memTypeIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Free all already created allocations.
|
||||
while(allocIndex--)
|
||||
{
|
||||
VmaAllocation currAlloc = pAllocations[allocIndex];
|
||||
VkDeviceMemory hMemory = currAlloc->GetMemory();
|
||||
|
||||
/*
|
||||
There is no need to call this, because Vulkan spec allows to skip vkUnmapMemory
|
||||
before vkFreeMemory.
|
||||
|
||||
if(currAlloc->GetMappedData() != VMA_NULL)
|
||||
{
|
||||
(*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory);
|
||||
}
|
||||
*/
|
||||
|
||||
FreeVulkanMemory(memTypeIndex, currAlloc->GetSize(), hMemory);
|
||||
|
||||
currAlloc->SetUserData(this, VMA_NULL);
|
||||
vma_delete(this, currAlloc);
|
||||
}
|
||||
|
||||
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
|
||||
VkDeviceSize size,
|
||||
VmaSuballocationType suballocType,
|
||||
uint32_t memTypeIndex,
|
||||
const VkMemoryAllocateInfo& allocInfo,
|
||||
bool map,
|
||||
bool isUserDataString,
|
||||
void* pUserData,
|
||||
VmaAllocation* pAllocation)
|
||||
{
|
||||
VkDeviceMemory hMemory = VK_NULL_HANDLE;
|
||||
VkResult res = AllocateVulkanMemory(&allocInfo, &hMemory);
|
||||
if(res < 0)
|
||||
|
@ -14202,16 +14455,6 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
|
|||
FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
|
||||
}
|
||||
|
||||
// Register it in m_pDedicatedAllocations.
|
||||
{
|
||||
VmaMutexLockWrite lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||
AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];
|
||||
VMA_ASSERT(pDedicatedAllocations);
|
||||
VmaVectorInsertSorted<VmaPointerLess>(*pDedicatedAllocations, *pAllocation);
|
||||
}
|
||||
|
||||
VMA_DEBUG_LOG(" Allocated DedicatedMemory MemoryTypeIndex=#%u", memTypeIndex);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -14287,8 +14530,11 @@ VkResult VmaAllocator_T::AllocateMemory(
|
|||
VkImage dedicatedImage,
|
||||
const VmaAllocationCreateInfo& createInfo,
|
||||
VmaSuballocationType suballocType,
|
||||
VmaAllocation* pAllocation)
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations)
|
||||
{
|
||||
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
|
||||
|
||||
VMA_ASSERT(VmaIsPow2(vkMemReq.alignment));
|
||||
|
||||
if(vkMemReq.size == 0)
|
||||
|
@ -14339,7 +14585,8 @@ VkResult VmaAllocator_T::AllocateMemory(
|
|||
alignmentForPool,
|
||||
createInfo,
|
||||
suballocType,
|
||||
pAllocation);
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -14362,7 +14609,8 @@ VkResult VmaAllocator_T::AllocateMemory(
|
|||
createInfo,
|
||||
memTypeIndex,
|
||||
suballocType,
|
||||
pAllocation);
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
// Succeeded on first try.
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
|
@ -14392,7 +14640,8 @@ VkResult VmaAllocator_T::AllocateMemory(
|
|||
createInfo,
|
||||
memTypeIndex,
|
||||
suballocType,
|
||||
pAllocation);
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
// Allocation from this alternative memory type succeeded.
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
|
@ -14415,45 +14664,55 @@ VkResult VmaAllocator_T::AllocateMemory(
|
|||
}
|
||||
}
|
||||
|
||||
void VmaAllocator_T::FreeMemory(const VmaAllocation allocation)
|
||||
void VmaAllocator_T::FreeMemory(
|
||||
size_t allocationCount,
|
||||
const VmaAllocation* pAllocations)
|
||||
{
|
||||
VMA_ASSERT(allocation);
|
||||
VMA_ASSERT(pAllocations);
|
||||
|
||||
if(TouchAllocation(allocation))
|
||||
for(size_t allocIndex = allocationCount; allocIndex--; )
|
||||
{
|
||||
if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
|
||||
{
|
||||
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
|
||||
}
|
||||
VmaAllocation allocation = pAllocations[allocIndex];
|
||||
|
||||
switch(allocation->GetType())
|
||||
if(allocation != VK_NULL_HANDLE)
|
||||
{
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
|
||||
if(TouchAllocation(allocation))
|
||||
{
|
||||
VmaBlockVector* pBlockVector = VMA_NULL;
|
||||
VmaPool hPool = allocation->GetPool();
|
||||
if(hPool != VK_NULL_HANDLE)
|
||||
if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
|
||||
{
|
||||
pBlockVector = &hPool->m_BlockVector;
|
||||
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
|
||||
}
|
||||
else
|
||||
|
||||
switch(allocation->GetType())
|
||||
{
|
||||
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
|
||||
pBlockVector = m_pBlockVectors[memTypeIndex];
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
|
||||
{
|
||||
VmaBlockVector* pBlockVector = VMA_NULL;
|
||||
VmaPool hPool = allocation->GetPool();
|
||||
if(hPool != VK_NULL_HANDLE)
|
||||
{
|
||||
pBlockVector = &hPool->m_BlockVector;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
|
||||
pBlockVector = m_pBlockVectors[memTypeIndex];
|
||||
}
|
||||
pBlockVector->Free(allocation);
|
||||
}
|
||||
break;
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
|
||||
FreeDedicatedMemory(allocation);
|
||||
break;
|
||||
default:
|
||||
VMA_ASSERT(0);
|
||||
}
|
||||
pBlockVector->Free(allocation);
|
||||
}
|
||||
break;
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
|
||||
FreeDedicatedMemory(allocation);
|
||||
break;
|
||||
default:
|
||||
VMA_ASSERT(0);
|
||||
|
||||
allocation->SetUserData(this, VMA_NULL);
|
||||
vma_delete(this, allocation);
|
||||
}
|
||||
}
|
||||
|
||||
allocation->SetUserData(this, VMA_NULL);
|
||||
vma_delete(this, allocation);
|
||||
}
|
||||
|
||||
VkResult VmaAllocator_T::ResizeAllocation(
|
||||
|
@ -15660,6 +15919,7 @@ VkResult vmaAllocateMemory(
|
|||
VK_NULL_HANDLE, // dedicatedImage
|
||||
*pCreateInfo,
|
||||
VMA_SUBALLOCATION_TYPE_UNKNOWN,
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
|
@ -15681,6 +15941,59 @@ VkResult vmaAllocateMemory(
|
|||
return result;
|
||||
}
|
||||
|
||||
VkResult vmaAllocateMemoryPages(
|
||||
VmaAllocator allocator,
|
||||
const VkMemoryRequirements* pVkMemoryRequirements,
|
||||
const VmaAllocationCreateInfo* pCreateInfo,
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations,
|
||||
VmaAllocationInfo* pAllocationInfo)
|
||||
{
|
||||
if(allocationCount == 0)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VMA_ASSERT(allocator && pVkMemoryRequirements && pCreateInfo && pAllocations);
|
||||
|
||||
VMA_DEBUG_LOG("vmaAllocateMemoryPages");
|
||||
|
||||
VMA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
VkResult result = allocator->AllocateMemory(
|
||||
*pVkMemoryRequirements,
|
||||
false, // requiresDedicatedAllocation
|
||||
false, // prefersDedicatedAllocation
|
||||
VK_NULL_HANDLE, // dedicatedBuffer
|
||||
VK_NULL_HANDLE, // dedicatedImage
|
||||
*pCreateInfo,
|
||||
VMA_SUBALLOCATION_TYPE_UNKNOWN,
|
||||
allocationCount,
|
||||
pAllocations);
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
if(allocator->GetRecorder() != VMA_NULL)
|
||||
{
|
||||
allocator->GetRecorder()->RecordAllocateMemoryPages(
|
||||
allocator->GetCurrentFrameIndex(),
|
||||
*pVkMemoryRequirements,
|
||||
*pCreateInfo,
|
||||
(uint64_t)allocationCount,
|
||||
pAllocations);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS)
|
||||
{
|
||||
for(size_t i = 0; i < allocationCount; ++i)
|
||||
{
|
||||
allocator->GetAllocationInfo(pAllocations[i], pAllocationInfo + i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult vmaAllocateMemoryForBuffer(
|
||||
VmaAllocator allocator,
|
||||
VkBuffer buffer,
|
||||
|
@ -15709,6 +16022,7 @@ VkResult vmaAllocateMemoryForBuffer(
|
|||
VK_NULL_HANDLE, // dedicatedImage
|
||||
*pCreateInfo,
|
||||
VMA_SUBALLOCATION_TYPE_BUFFER,
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
|
@ -15759,6 +16073,7 @@ VkResult vmaAllocateMemoryForImage(
|
|||
image, // dedicatedImage
|
||||
*pCreateInfo,
|
||||
VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
|
@ -15806,7 +16121,38 @@ void vmaFreeMemory(
|
|||
}
|
||||
#endif
|
||||
|
||||
allocator->FreeMemory(allocation);
|
||||
allocator->FreeMemory(
|
||||
1, // allocationCount
|
||||
&allocation);
|
||||
}
|
||||
|
||||
void vmaFreeMemoryPages(
|
||||
VmaAllocator allocator,
|
||||
size_t allocationCount,
|
||||
VmaAllocation* pAllocations)
|
||||
{
|
||||
if(allocationCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VMA_ASSERT(allocator);
|
||||
|
||||
VMA_DEBUG_LOG("vmaFreeMemoryPages");
|
||||
|
||||
VMA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
if(allocator->GetRecorder() != VMA_NULL)
|
||||
{
|
||||
allocator->GetRecorder()->RecordFreeMemoryPages(
|
||||
allocator->GetCurrentFrameIndex(),
|
||||
(uint64_t)allocationCount,
|
||||
pAllocations);
|
||||
}
|
||||
#endif
|
||||
|
||||
allocator->FreeMemory(allocationCount, pAllocations);
|
||||
}
|
||||
|
||||
VkResult vmaResizeAllocation(
|
||||
|
@ -16201,6 +16547,7 @@ VkResult vmaCreateBuffer(
|
|||
VK_NULL_HANDLE, // dedicatedImage
|
||||
*pAllocationCreateInfo,
|
||||
VMA_SUBALLOCATION_TYPE_BUFFER,
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
|
@ -16231,7 +16578,9 @@ VkResult vmaCreateBuffer(
|
|||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
allocator->FreeMemory(*pAllocation);
|
||||
allocator->FreeMemory(
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
*pAllocation = VK_NULL_HANDLE;
|
||||
(*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
|
||||
*pBuffer = VK_NULL_HANDLE;
|
||||
|
@ -16276,7 +16625,9 @@ void vmaDestroyBuffer(
|
|||
|
||||
if(allocation != VK_NULL_HANDLE)
|
||||
{
|
||||
allocator->FreeMemory(allocation);
|
||||
allocator->FreeMemory(
|
||||
1, // allocationCount
|
||||
&allocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16333,6 +16684,7 @@ VkResult vmaCreateImage(
|
|||
*pImage, // dedicatedImage
|
||||
*pAllocationCreateInfo,
|
||||
suballocType,
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
|
||||
#if VMA_RECORDING_ENABLED
|
||||
|
@ -16363,7 +16715,9 @@ VkResult vmaCreateImage(
|
|||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
allocator->FreeMemory(*pAllocation);
|
||||
allocator->FreeMemory(
|
||||
1, // allocationCount
|
||||
pAllocation);
|
||||
*pAllocation = VK_NULL_HANDLE;
|
||||
(*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
|
||||
*pImage = VK_NULL_HANDLE;
|
||||
|
@ -16407,7 +16761,9 @@ void vmaDestroyImage(
|
|||
}
|
||||
if(allocation != VK_NULL_HANDLE)
|
||||
{
|
||||
allocator->FreeMemory(allocation);
|
||||
allocator->FreeMemory(
|
||||
1, // allocationCount
|
||||
&allocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue