mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-05 12:20:07 +00:00
Next small step: moved split logic from VmaBlockMetadata_Buddy::CreateAllocationRequest to VmaBlockMetadata_Buddy::Alloc.
This commit is contained in:
parent
a83793a63e
commit
bf1a931a2d
@ -4927,6 +4927,9 @@ private:
|
|||||||
void CleanupAfterFree();
|
void CleanupAfterFree();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Level 0 has block size = GetSize(). Level 1 has block size = GetSize() / 2 and so on...
|
||||||
|
*/
|
||||||
class VmaBlockMetadata_Buddy : public VmaBlockMetadata
|
class VmaBlockMetadata_Buddy : public VmaBlockMetadata
|
||||||
{
|
{
|
||||||
VMA_CLASS_NO_COPY(VmaBlockMetadata_Buddy)
|
VMA_CLASS_NO_COPY(VmaBlockMetadata_Buddy)
|
||||||
@ -9380,72 +9383,20 @@ bool VmaBlockMetadata_Buddy::CreateAllocationRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t targetLevel = AllocSizeToLevel(allocSize);
|
const uint32_t targetLevel = AllocSizeToLevel(allocSize);
|
||||||
|
for(uint32_t level = targetLevel + 1; level--; )
|
||||||
// No free node with intended size.
|
|
||||||
if(m_FreeList[targetLevel] == VMA_NULL)
|
|
||||||
{
|
{
|
||||||
// Go up until we find free node with larget size.
|
if(m_FreeList[level] != VMA_NULL)
|
||||||
uint32_t level = targetLevel;
|
|
||||||
while(m_FreeList[level] == VMA_NULL)
|
|
||||||
{
|
{
|
||||||
if(level == 0)
|
pAllocationRequest->offset = m_FreeList[level]->offset;
|
||||||
{
|
pAllocationRequest->sumFreeSize = LevelToNodeSize(level);
|
||||||
return false;
|
pAllocationRequest->sumItemSize = 0;
|
||||||
}
|
pAllocationRequest->itemsToMakeLostCount = 0;
|
||||||
--level;
|
pAllocationRequest->customData = (void*)(uintptr_t)level;
|
||||||
}
|
return true;
|
||||||
|
|
||||||
// Go down, splitting free nodes.
|
|
||||||
while(level < targetLevel)
|
|
||||||
{
|
|
||||||
// Get first free node at current level.
|
|
||||||
Node* node = m_FreeList[level];
|
|
||||||
// Remove it from list of free nodes at this level.
|
|
||||||
m_FreeList[level] = node->free.nextFree;
|
|
||||||
|
|
||||||
const uint32_t childrenLevel = level + 1;
|
|
||||||
|
|
||||||
// Create two free sub-nodes.
|
|
||||||
Node* leftChild = new Node();
|
|
||||||
Node* rightChild = new Node();
|
|
||||||
|
|
||||||
leftChild->offset = node->offset;
|
|
||||||
leftChild->type = Node::TYPE_FREE;
|
|
||||||
leftChild->parent = node;
|
|
||||||
leftChild->buddy = rightChild;
|
|
||||||
leftChild->free.nextFree = VMA_NULL;
|
|
||||||
|
|
||||||
rightChild->offset = node->offset + LevelToNodeSize(childrenLevel);
|
|
||||||
rightChild->type = Node::TYPE_FREE;
|
|
||||||
rightChild->parent = node;
|
|
||||||
rightChild->buddy = leftChild;
|
|
||||||
rightChild->free.nextFree = VMA_NULL;
|
|
||||||
|
|
||||||
// Convert current node to split type.
|
|
||||||
node->type = Node::TYPE_SPLIT;
|
|
||||||
node->split.leftChild = leftChild;
|
|
||||||
|
|
||||||
// Add child nodes to free list.
|
|
||||||
leftChild->free.nextFree = m_FreeList[childrenLevel];
|
|
||||||
m_FreeList[childrenLevel] = leftChild;
|
|
||||||
|
|
||||||
rightChild->free.nextFree = m_FreeList[childrenLevel];
|
|
||||||
m_FreeList[childrenLevel] = rightChild;
|
|
||||||
|
|
||||||
++level;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* freeNode = m_FreeList[targetLevel];
|
return false;
|
||||||
VMA_ASSERT(freeNode != VMA_NULL);
|
|
||||||
|
|
||||||
pAllocationRequest->offset = freeNode->offset;
|
|
||||||
// TODO
|
|
||||||
pAllocationRequest->sumFreeSize = 0;
|
|
||||||
pAllocationRequest->sumItemSize = 0;
|
|
||||||
pAllocationRequest->itemsToMakeLostCount = 0;
|
|
||||||
pAllocationRequest->customData = (void*)(uintptr_t)targetLevel;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VmaBlockMetadata_Buddy::MakeRequestedAllocationsLost(
|
bool VmaBlockMetadata_Buddy::MakeRequestedAllocationsLost(
|
||||||
@ -9473,17 +9424,60 @@ void VmaBlockMetadata_Buddy::Alloc(
|
|||||||
bool upperAddress,
|
bool upperAddress,
|
||||||
VmaAllocation hAllocation)
|
VmaAllocation hAllocation)
|
||||||
{
|
{
|
||||||
const uint32_t targetLevel = (uint32_t)(uintptr_t)request.customData;
|
const uint32_t targetLevel = AllocSizeToLevel(allocSize);
|
||||||
VMA_ASSERT(m_FreeList[targetLevel] != VMA_NULL);
|
uint32_t currLevel = (uint32_t)(uintptr_t)request.customData;
|
||||||
Node* node = m_FreeList[targetLevel];
|
VMA_ASSERT(m_FreeList[currLevel] != VMA_NULL);
|
||||||
VMA_ASSERT(node->type == Node::TYPE_FREE);
|
Node* currNode = m_FreeList[currLevel];
|
||||||
|
VMA_ASSERT(currNode->type == Node::TYPE_FREE);
|
||||||
|
VMA_ASSERT(currNode->offset == request.offset);
|
||||||
|
|
||||||
|
// Go down, splitting free nodes.
|
||||||
|
while(currLevel < targetLevel)
|
||||||
|
{
|
||||||
|
// currNode is already first free node at currLevel.
|
||||||
|
// Remove it from list of free nodes at this currLevel.
|
||||||
|
m_FreeList[currLevel] = currNode->free.nextFree;
|
||||||
|
|
||||||
|
const uint32_t childrenLevel = currLevel + 1;
|
||||||
|
|
||||||
|
// Create two free sub-nodes.
|
||||||
|
Node* leftChild = new Node();
|
||||||
|
Node* rightChild = new Node();
|
||||||
|
|
||||||
|
leftChild->offset = currNode->offset;
|
||||||
|
leftChild->type = Node::TYPE_FREE;
|
||||||
|
leftChild->parent = currNode;
|
||||||
|
leftChild->buddy = rightChild;
|
||||||
|
leftChild->free.nextFree = VMA_NULL;
|
||||||
|
|
||||||
|
rightChild->offset = currNode->offset + LevelToNodeSize(childrenLevel);
|
||||||
|
rightChild->type = Node::TYPE_FREE;
|
||||||
|
rightChild->parent = currNode;
|
||||||
|
rightChild->buddy = leftChild;
|
||||||
|
rightChild->free.nextFree = VMA_NULL;
|
||||||
|
|
||||||
|
// Convert current currNode to split type.
|
||||||
|
currNode->type = Node::TYPE_SPLIT;
|
||||||
|
currNode->split.leftChild = leftChild;
|
||||||
|
|
||||||
|
// Add child nodes to free list.
|
||||||
|
rightChild->free.nextFree = m_FreeList[childrenLevel];
|
||||||
|
m_FreeList[childrenLevel] = rightChild;
|
||||||
|
|
||||||
|
leftChild->free.nextFree = m_FreeList[childrenLevel];
|
||||||
|
m_FreeList[childrenLevel] = leftChild;
|
||||||
|
|
||||||
|
++currLevel;
|
||||||
|
currNode = m_FreeList[currLevel];
|
||||||
|
}
|
||||||
|
|
||||||
// Remove from free list.
|
// Remove from free list.
|
||||||
m_FreeList[targetLevel] = node->free.nextFree;
|
VMA_ASSERT(currLevel == targetLevel && currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
|
||||||
|
m_FreeList[targetLevel] = currNode->free.nextFree;
|
||||||
|
|
||||||
// Convert to allocation node.
|
// Convert to allocation node.
|
||||||
node->type = Node::TYPE_ALLOCATION;
|
currNode->type = Node::TYPE_ALLOCATION;
|
||||||
node->allocation.alloc = hAllocation;
|
currNode->allocation.alloc = hAllocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VmaBlockMetadata_Buddy::Free(const VmaAllocation allocation)
|
void VmaBlockMetadata_Buddy::Free(const VmaAllocation allocation)
|
||||||
|
Loading…
Reference in New Issue
Block a user