Skip to content

Commit 9933c5c

Browse files
VmaBlockMetadata_Buddy: Added respecting of allocation alignment.
1 parent a01d458 commit 9933c5c

2 files changed

Lines changed: 44 additions & 11 deletions

File tree

src/Tests.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4168,6 +4168,23 @@ static void BasicTestBuddyAllocator()
41684168
assert(res == VK_SUCCESS);
41694169
bufInfo.push_back(newBufInfo);
41704170

4171+
// Test some small allocation with alignment requirement.
4172+
{
4173+
VkMemoryRequirements memReq;
4174+
memReq.alignment = 256;
4175+
memReq.memoryTypeBits = UINT32_MAX;
4176+
memReq.size = 32;
4177+
4178+
newBufInfo.Buffer = VK_NULL_HANDLE;
4179+
res = vmaAllocateMemory(g_hAllocator, &memReq, &allocCreateInfo,
4180+
&newBufInfo.Allocation, &allocInfo);
4181+
assert(res == VK_SUCCESS);
4182+
assert(allocInfo.offset % memReq.alignment == 0);
4183+
bufInfo.push_back(newBufInfo);
4184+
}
4185+
4186+
//SaveAllocatorStatsToFile(L"TEST.json");
4187+
41714188
VmaPoolStats stats = {};
41724189
vmaGetPoolStats(g_hAllocator, pool, &stats);
41734190
int DBG = 0; // Set breakpoint here to inspect `stats`.

src/vk_mem_alloc.h

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9400,14 +9400,19 @@ bool VmaBlockMetadata_Buddy::CreateAllocationRequest(
94009400
const uint32_t targetLevel = AllocSizeToLevel(allocSize);
94019401
for(uint32_t level = targetLevel + 1; level--; )
94029402
{
9403-
if(m_FreeList[level].front != VMA_NULL)
9403+
for(Node* freeNode = m_FreeList[level].front;
9404+
freeNode != VMA_NULL;
9405+
freeNode = freeNode->free.next)
94049406
{
9405-
pAllocationRequest->offset = m_FreeList[level].front->offset;
9406-
pAllocationRequest->sumFreeSize = LevelToNodeSize(level);
9407-
pAllocationRequest->sumItemSize = 0;
9408-
pAllocationRequest->itemsToMakeLostCount = 0;
9409-
pAllocationRequest->customData = (void*)(uintptr_t)level;
9410-
return true;
9407+
if(freeNode->offset % allocAlignment == 0)
9408+
{
9409+
pAllocationRequest->offset = freeNode->offset;
9410+
pAllocationRequest->sumFreeSize = LevelToNodeSize(level);
9411+
pAllocationRequest->sumItemSize = 0;
9412+
pAllocationRequest->itemsToMakeLostCount = 0;
9413+
pAllocationRequest->customData = (void*)(uintptr_t)level;
9414+
return true;
9415+
}
94119416
}
94129417
}
94139418

@@ -9444,10 +9449,14 @@ void VmaBlockMetadata_Buddy::Alloc(
94449449
{
94459450
const uint32_t targetLevel = AllocSizeToLevel(allocSize);
94469451
uint32_t currLevel = (uint32_t)(uintptr_t)request.customData;
9447-
VMA_ASSERT(m_FreeList[currLevel].front != VMA_NULL);
9452+
94489453
Node* currNode = m_FreeList[currLevel].front;
9449-
VMA_ASSERT(currNode->type == Node::TYPE_FREE);
9450-
VMA_ASSERT(currNode->offset == request.offset);
9454+
VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
9455+
while(currNode->offset != request.offset)
9456+
{
9457+
currNode = currNode->free.next;
9458+
VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
9459+
}
94519460

94529461
// Go down, splitting free nodes.
94539462
while(currLevel < targetLevel)
@@ -9484,10 +9493,17 @@ void VmaBlockMetadata_Buddy::Alloc(
94849493
//m_SumFreeSize -= LevelToNodeSize(currLevel) % 2; // Useful only when level node sizes can be non power of 2.
94859494
++currLevel;
94869495
currNode = m_FreeList[currLevel].front;
9496+
9497+
/*
9498+
We can be sure that currNode, as left child of node previously split,
9499+
also fullfills the alignment requirement.
9500+
*/
94879501
}
94889502

94899503
// Remove from free list.
9490-
VMA_ASSERT(currLevel == targetLevel && currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
9504+
VMA_ASSERT(currLevel == targetLevel &&
9505+
currNode != VMA_NULL &&
9506+
currNode->type == Node::TYPE_FREE);
94919507
RemoveFromFreeList(currLevel, currNode);
94929508

94939509
// Convert to allocation node.

0 commit comments

Comments
 (0)