mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-11-27 00:44:35 +00:00
Added macro VMA_VALIDATE to simplify validation methods. Implemented proper calculation of VmaBlockMetadata_Buddy::GetAllocationCount.
This commit is contained in:
parent
ca5db0b8a5
commit
8796504f62
@ -16,7 +16,7 @@ macros if you want to configure the library and then include its header to
|
|||||||
include all public interface declarations. Example:
|
include all public interface declarations. Example:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define VMA_HEAVY_ASSERT(expr) assert(expr)
|
#define VMA_HEAVY_ASSERT(expr) assert(expr)
|
||||||
//#define VMA_USE_STL_CONTAINERS 1
|
//#define VMA_USE_STL_CONTAINERS 1
|
||||||
//#define VMA_DEDICATED_ALLOCATION 0
|
//#define VMA_DEDICATED_ALLOCATION 0
|
||||||
//#define VMA_DEBUG_MARGIN 16
|
//#define VMA_DEBUG_MARGIN 16
|
||||||
|
@ -4670,6 +4670,11 @@ private:
|
|||||||
VkDeviceSize m_Size;
|
VkDeviceSize m_Size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define VMA_VALIDATE(cond) do { if(!(cond)) { \
|
||||||
|
VMA_ASSERT(0 && "Validation failed: " ## #cond); \
|
||||||
|
return false; \
|
||||||
|
} } while(false)
|
||||||
|
|
||||||
class VmaBlockMetadata_Generic : public VmaBlockMetadata
|
class VmaBlockMetadata_Generic : public VmaBlockMetadata
|
||||||
{
|
{
|
||||||
VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic)
|
VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic)
|
||||||
@ -4950,7 +4955,7 @@ public:
|
|||||||
virtual void Init(VkDeviceSize size);
|
virtual void Init(VkDeviceSize size);
|
||||||
|
|
||||||
virtual bool Validate() const;
|
virtual bool Validate() const;
|
||||||
virtual size_t GetAllocationCount() const;
|
virtual size_t GetAllocationCount() const { return m_AllocationCount; }
|
||||||
virtual VkDeviceSize GetSumFreeSize() const;
|
virtual VkDeviceSize GetSumFreeSize() const;
|
||||||
virtual VkDeviceSize GetUnusedRangeSizeMax() const;
|
virtual VkDeviceSize GetUnusedRangeSizeMax() const;
|
||||||
virtual bool IsEmpty() const { return m_Root->type == Node::TYPE_FREE; }
|
virtual bool IsEmpty() const { return m_Root->type == Node::TYPE_FREE; }
|
||||||
@ -4981,7 +4986,7 @@ public:
|
|||||||
|
|
||||||
virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);
|
virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);
|
||||||
|
|
||||||
virtual VkResult CheckCorruption(const void* pBlockData);
|
virtual VkResult CheckCorruption(const void* pBlockData) { return VK_ERROR_FEATURE_NOT_PRESENT; }
|
||||||
|
|
||||||
virtual void Alloc(
|
virtual void Alloc(
|
||||||
const VmaAllocationRequest& request,
|
const VmaAllocationRequest& request,
|
||||||
@ -4996,6 +5001,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
static const size_t MAX_LEVELS = 30; // TODO
|
static const size_t MAX_LEVELS = 30; // TODO
|
||||||
|
|
||||||
|
struct ValidationContext
|
||||||
|
{
|
||||||
|
size_t calculatedAllocationCount;
|
||||||
|
|
||||||
|
ValidationContext() :
|
||||||
|
calculatedAllocationCount(0) { }
|
||||||
|
};
|
||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
VkDeviceSize offset;
|
VkDeviceSize offset;
|
||||||
@ -5032,9 +5045,11 @@ private:
|
|||||||
Node* front;
|
Node* front;
|
||||||
Node* back;
|
Node* back;
|
||||||
} m_FreeList[MAX_LEVELS];
|
} m_FreeList[MAX_LEVELS];
|
||||||
|
// Number of nodes in the tree with type == TYPE_ALLOCATION.
|
||||||
|
size_t m_AllocationCount;
|
||||||
|
|
||||||
void DeleteNode(Node* node);
|
void DeleteNode(Node* node);
|
||||||
bool ValidateNode(const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const;
|
bool ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const;
|
||||||
uint32_t AllocSizeToLevel(VkDeviceSize allocSize) const;
|
uint32_t AllocSizeToLevel(VkDeviceSize allocSize) const;
|
||||||
VkDeviceSize LevelToNodeSize(uint32_t level) const;
|
VkDeviceSize LevelToNodeSize(uint32_t level) const;
|
||||||
// Alloc passed just for validation. Can be null.
|
// Alloc passed just for validation. Can be null.
|
||||||
@ -6580,10 +6595,7 @@ void VmaBlockMetadata_Generic::Init(VkDeviceSize size)
|
|||||||
|
|
||||||
bool VmaBlockMetadata_Generic::Validate() const
|
bool VmaBlockMetadata_Generic::Validate() const
|
||||||
{
|
{
|
||||||
if(m_Suballocations.empty())
|
VMA_VALIDATE(!m_Suballocations.empty());
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expected offset of new suballocation as calculated from previous ones.
|
// Expected offset of new suballocation as calculated from previous ones.
|
||||||
VkDeviceSize calculatedOffset = 0;
|
VkDeviceSize calculatedOffset = 0;
|
||||||
@ -6604,22 +6616,13 @@ bool VmaBlockMetadata_Generic::Validate() const
|
|||||||
const VmaSuballocation& subAlloc = *suballocItem;
|
const VmaSuballocation& subAlloc = *suballocItem;
|
||||||
|
|
||||||
// Actual offset of this suballocation doesn't match expected one.
|
// Actual offset of this suballocation doesn't match expected one.
|
||||||
if(subAlloc.offset != calculatedOffset)
|
VMA_VALIDATE(subAlloc.offset == calculatedOffset);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
||||||
// Two adjacent free suballocations are invalid. They should be merged.
|
// Two adjacent free suballocations are invalid. They should be merged.
|
||||||
if(prevFree && currFree)
|
VMA_VALIDATE(!prevFree || !currFree);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currFree != (subAlloc.hAllocation == VK_NULL_HANDLE))
|
VMA_VALIDATE(currFree == (subAlloc.hAllocation == VK_NULL_HANDLE));
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currFree)
|
if(currFree)
|
||||||
{
|
{
|
||||||
@ -6631,27 +6634,15 @@ bool VmaBlockMetadata_Generic::Validate() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Margin required between allocations - every free space must be at least that large.
|
// Margin required between allocations - every free space must be at least that large.
|
||||||
if(subAlloc.size < VMA_DEBUG_MARGIN)
|
VMA_VALIDATE(subAlloc.size >= VMA_DEBUG_MARGIN);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(subAlloc.hAllocation->GetOffset() != subAlloc.offset)
|
VMA_VALIDATE(subAlloc.hAllocation->GetOffset() == subAlloc.offset);
|
||||||
{
|
VMA_VALIDATE(subAlloc.hAllocation->GetSize() == subAlloc.size);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(subAlloc.hAllocation->GetSize() != subAlloc.size)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Margin required between allocations - previous allocation must be free.
|
// Margin required between allocations - previous allocation must be free.
|
||||||
if(VMA_DEBUG_MARGIN > 0 && !prevFree)
|
VMA_VALIDATE(VMA_DEBUG_MARGIN == 0 || prevFree);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculatedOffset += subAlloc.size;
|
calculatedOffset += subAlloc.size;
|
||||||
@ -6660,10 +6651,7 @@ bool VmaBlockMetadata_Generic::Validate() const
|
|||||||
|
|
||||||
// Number of free suballocations registered in m_FreeSuballocationsBySize doesn't
|
// Number of free suballocations registered in m_FreeSuballocationsBySize doesn't
|
||||||
// match expected one.
|
// match expected one.
|
||||||
if(m_FreeSuballocationsBySize.size() != freeSuballocationsToRegister)
|
VMA_VALIDATE(m_FreeSuballocationsBySize.size() == freeSuballocationsToRegister);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDeviceSize lastSize = 0;
|
VkDeviceSize lastSize = 0;
|
||||||
for(size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i)
|
for(size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i)
|
||||||
@ -6671,27 +6659,18 @@ bool VmaBlockMetadata_Generic::Validate() const
|
|||||||
VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i];
|
VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i];
|
||||||
|
|
||||||
// Only free suballocations can be registered in m_FreeSuballocationsBySize.
|
// Only free suballocations can be registered in m_FreeSuballocationsBySize.
|
||||||
if(suballocItem->type != VMA_SUBALLOCATION_TYPE_FREE)
|
VMA_VALIDATE(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// They must be sorted by size ascending.
|
// They must be sorted by size ascending.
|
||||||
if(suballocItem->size < lastSize)
|
VMA_VALIDATE(suballocItem->size >= lastSize);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastSize = suballocItem->size;
|
lastSize = suballocItem->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if totals match calculacted values.
|
// Check if totals match calculacted values.
|
||||||
if(!ValidateFreeSuballocationList() ||
|
VMA_VALIDATE(ValidateFreeSuballocationList());
|
||||||
(calculatedOffset != GetSize()) ||
|
VMA_VALIDATE(calculatedOffset == GetSize());
|
||||||
(calculatedSumFreeSize != m_SumFreeSize) ||
|
VMA_VALIDATE(calculatedSumFreeSize == m_SumFreeSize);
|
||||||
(calculatedFreeCount != m_FreeCount))
|
VMA_VALIDATE(calculatedFreeCount == m_FreeCount);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -7101,22 +7080,9 @@ bool VmaBlockMetadata_Generic::ValidateFreeSuballocationList() const
|
|||||||
{
|
{
|
||||||
const VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i];
|
const VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i];
|
||||||
|
|
||||||
if(it->type != VMA_SUBALLOCATION_TYPE_FREE)
|
VMA_VALIDATE(it->type == VMA_SUBALLOCATION_TYPE_FREE);
|
||||||
{
|
VMA_VALIDATE(it->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER);
|
||||||
VMA_ASSERT(0);
|
VMA_VALIDATE(it->size >= lastSize);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(it->size < VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER)
|
|
||||||
{
|
|
||||||
VMA_ASSERT(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(it->size < lastSize)
|
|
||||||
{
|
|
||||||
VMA_ASSERT(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastSize = it->size;
|
lastSize = it->size;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -7551,45 +7517,26 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
|
const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
|
||||||
const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
|
const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
|
||||||
|
|
||||||
if(suballocations2nd.empty() != (m_2ndVectorMode == SECOND_VECTOR_EMPTY))
|
VMA_VALIDATE(suballocations2nd.empty() == (m_2ndVectorMode == SECOND_VECTOR_EMPTY));
|
||||||
{
|
VMA_VALIDATE(!suballocations1st.empty() ||
|
||||||
return false;
|
suballocations2nd.empty() ||
|
||||||
}
|
m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER);
|
||||||
if(suballocations1st.empty() && !suballocations2nd.empty() &&
|
|
||||||
m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!suballocations1st.empty())
|
if(!suballocations1st.empty())
|
||||||
{
|
{
|
||||||
// Null item at the beginning should be accounted into m_1stNullItemsBeginCount.
|
// Null item at the beginning should be accounted into m_1stNullItemsBeginCount.
|
||||||
if(suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE)
|
VMA_VALIDATE(suballocations1st[m_1stNullItemsBeginCount].hAllocation != VK_NULL_HANDLE);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Null item at the end should be just pop_back().
|
// Null item at the end should be just pop_back().
|
||||||
if(suballocations1st.back().hAllocation == VK_NULL_HANDLE)
|
VMA_VALIDATE(suballocations1st.back().hAllocation != VK_NULL_HANDLE);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!suballocations2nd.empty())
|
if(!suballocations2nd.empty())
|
||||||
{
|
{
|
||||||
// Null item at the end should be just pop_back().
|
// Null item at the end should be just pop_back().
|
||||||
if(suballocations2nd.back().hAllocation == VK_NULL_HANDLE)
|
VMA_VALIDATE(suballocations2nd.back().hAllocation != VK_NULL_HANDLE);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount > suballocations1st.size())
|
VMA_VALIDATE(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount <= suballocations1st.size());
|
||||||
{
|
VMA_VALIDATE(m_2ndNullItemsCount <= suballocations2nd.size());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(m_2ndNullItemsCount > suballocations2nd.size())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDeviceSize sumUsedSize = 0;
|
VkDeviceSize sumUsedSize = 0;
|
||||||
const size_t suballoc1stCount = suballocations1st.size();
|
const size_t suballoc1stCount = suballocations1st.size();
|
||||||
@ -7604,25 +7551,13 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
const VmaSuballocation& suballoc = suballocations2nd[i];
|
const VmaSuballocation& suballoc = suballocations2nd[i];
|
||||||
const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
||||||
|
|
||||||
if(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))
|
VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE));
|
||||||
{
|
VMA_VALIDATE(suballoc.offset >= offset);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(suballoc.offset < offset)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!currFree)
|
if(!currFree)
|
||||||
{
|
{
|
||||||
if(suballoc.hAllocation->GetOffset() != suballoc.offset)
|
VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset);
|
||||||
{
|
VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(suballoc.hAllocation->GetSize() != suballoc.size)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sumUsedSize += suballoc.size;
|
sumUsedSize += suballoc.size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7633,20 +7568,14 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;
|
offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nullItem2ndCount != m_2ndNullItemsCount)
|
VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < m_1stNullItemsBeginCount; ++i)
|
for(size_t i = 0; i < m_1stNullItemsBeginCount; ++i)
|
||||||
{
|
{
|
||||||
const VmaSuballocation& suballoc = suballocations1st[i];
|
const VmaSuballocation& suballoc = suballocations1st[i];
|
||||||
if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE ||
|
VMA_VALIDATE(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE &&
|
||||||
suballoc.hAllocation != VK_NULL_HANDLE)
|
suballoc.hAllocation == VK_NULL_HANDLE);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nullItem1stCount = m_1stNullItemsBeginCount;
|
size_t nullItem1stCount = m_1stNullItemsBeginCount;
|
||||||
@ -7656,29 +7585,14 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
const VmaSuballocation& suballoc = suballocations1st[i];
|
const VmaSuballocation& suballoc = suballocations1st[i];
|
||||||
const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
||||||
|
|
||||||
if(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))
|
VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE));
|
||||||
{
|
VMA_VALIDATE(suballoc.offset >= offset);
|
||||||
return false;
|
VMA_VALIDATE(i >= m_1stNullItemsBeginCount || currFree);
|
||||||
}
|
|
||||||
if(suballoc.offset < offset)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(i < m_1stNullItemsBeginCount && !currFree)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!currFree)
|
if(!currFree)
|
||||||
{
|
{
|
||||||
if(suballoc.hAllocation->GetOffset() != suballoc.offset)
|
VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset);
|
||||||
{
|
VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(suballoc.hAllocation->GetSize() != suballoc.size)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sumUsedSize += suballoc.size;
|
sumUsedSize += suballoc.size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7688,10 +7602,7 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
|
|
||||||
offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;
|
offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;
|
||||||
}
|
}
|
||||||
if(nullItem1stCount != m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount)
|
VMA_VALIDATE(nullItem1stCount == m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
|
if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
|
||||||
{
|
{
|
||||||
@ -7702,25 +7613,13 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
const VmaSuballocation& suballoc = suballocations2nd[i];
|
const VmaSuballocation& suballoc = suballocations2nd[i];
|
||||||
const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
|
||||||
|
|
||||||
if(currFree != (suballoc.hAllocation == VK_NULL_HANDLE))
|
VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE));
|
||||||
{
|
VMA_VALIDATE(suballoc.offset >= offset);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(suballoc.offset < offset)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!currFree)
|
if(!currFree)
|
||||||
{
|
{
|
||||||
if(suballoc.hAllocation->GetOffset() != suballoc.offset)
|
VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset);
|
||||||
{
|
VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(suballoc.hAllocation->GetSize() != suballoc.size)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sumUsedSize += suballoc.size;
|
sumUsedSize += suballoc.size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7731,20 +7630,11 @@ bool VmaBlockMetadata_Linear::Validate() const
|
|||||||
offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;
|
offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nullItem2ndCount != m_2ndNullItemsCount)
|
VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset > GetSize())
|
VMA_VALIDATE(offset <= GetSize());
|
||||||
{
|
VMA_VALIDATE(m_SumFreeSize == GetSize() - sumUsedSize);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(m_SumFreeSize != GetSize() - sumUsedSize)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -9278,7 +9168,8 @@ void VmaBlockMetadata_Linear::CleanupAfterFree()
|
|||||||
// class VmaBlockMetadata_Buddy
|
// class VmaBlockMetadata_Buddy
|
||||||
|
|
||||||
VmaBlockMetadata_Buddy::VmaBlockMetadata_Buddy(VmaAllocator hAllocator) :
|
VmaBlockMetadata_Buddy::VmaBlockMetadata_Buddy(VmaAllocator hAllocator) :
|
||||||
m_Root(VMA_NULL)
|
m_Root(VMA_NULL),
|
||||||
|
m_AllocationCount(0)
|
||||||
{
|
{
|
||||||
memset(m_FreeList, 0, sizeof(m_FreeList));
|
memset(m_FreeList, 0, sizeof(m_FreeList));
|
||||||
}
|
}
|
||||||
@ -9305,42 +9196,32 @@ void VmaBlockMetadata_Buddy::Init(VkDeviceSize size)
|
|||||||
bool VmaBlockMetadata_Buddy::Validate() const
|
bool VmaBlockMetadata_Buddy::Validate() const
|
||||||
{
|
{
|
||||||
// Validate tree.
|
// Validate tree.
|
||||||
if(!ValidateNode(VMA_NULL, m_Root, 0, GetSize()))
|
ValidationContext ctx;
|
||||||
|
if(!ValidateNode(ctx, VMA_NULL, m_Root, 0, GetSize()))
|
||||||
{
|
{
|
||||||
return false;
|
VMA_VALIDATE(false && "ValidateNode failed.");
|
||||||
}
|
}
|
||||||
|
VMA_VALIDATE(m_AllocationCount == ctx.calculatedAllocationCount);
|
||||||
|
|
||||||
// Validate free node lists.
|
// Validate free node lists.
|
||||||
for(uint32_t level = 0; level < MAX_LEVELS; ++level)
|
for(uint32_t level = 0; level < MAX_LEVELS; ++level)
|
||||||
{
|
{
|
||||||
if(m_FreeList[level].front != VMA_NULL &&
|
VMA_VALIDATE(m_FreeList[level].front == VMA_NULL ||
|
||||||
m_FreeList[level].front->free.prev != VMA_NULL)
|
m_FreeList[level].front->free.prev == VMA_NULL);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Node* node = m_FreeList[level].front;
|
for(Node* node = m_FreeList[level].front;
|
||||||
node != VMA_NULL;
|
node != VMA_NULL;
|
||||||
node = node->free.next)
|
node = node->free.next)
|
||||||
{
|
{
|
||||||
if(node->type != Node::TYPE_FREE)
|
VMA_VALIDATE(node->type == Node::TYPE_FREE);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node->free.next == VMA_NULL)
|
if(node->free.next == VMA_NULL)
|
||||||
{
|
{
|
||||||
if(m_FreeList[level].back != node)
|
VMA_VALIDATE(m_FreeList[level].back == node);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(node->free.next->free.prev != node)
|
VMA_VALIDATE(node->free.next->free.prev == node);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9348,11 +9229,6 @@ bool VmaBlockMetadata_Buddy::Validate() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t VmaBlockMetadata_Buddy::GetAllocationCount() const
|
|
||||||
{
|
|
||||||
return 0; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDeviceSize VmaBlockMetadata_Buddy::GetSumFreeSize() const
|
VkDeviceSize VmaBlockMetadata_Buddy::GetSumFreeSize() const
|
||||||
{
|
{
|
||||||
return 0; // TODO
|
return 0; // TODO
|
||||||
@ -9453,11 +9329,6 @@ uint32_t VmaBlockMetadata_Buddy::MakeAllocationsLost(uint32_t currentFrameIndex,
|
|||||||
return 0; // TODO
|
return 0; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult VmaBlockMetadata_Buddy::CheckCorruption(const void* pBlockData)
|
|
||||||
{
|
|
||||||
return VK_SUCCESS; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void VmaBlockMetadata_Buddy::Alloc(
|
void VmaBlockMetadata_Buddy::Alloc(
|
||||||
const VmaAllocationRequest& request,
|
const VmaAllocationRequest& request,
|
||||||
VmaSuballocationType type,
|
VmaSuballocationType type,
|
||||||
@ -9514,6 +9385,8 @@ void VmaBlockMetadata_Buddy::Alloc(
|
|||||||
// Convert to allocation node.
|
// Convert to allocation node.
|
||||||
currNode->type = Node::TYPE_ALLOCATION;
|
currNode->type = Node::TYPE_ALLOCATION;
|
||||||
currNode->allocation.alloc = hAllocation;
|
currNode->allocation.alloc = hAllocation;
|
||||||
|
|
||||||
|
++m_AllocationCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VmaBlockMetadata_Buddy::DeleteNode(Node* node)
|
void VmaBlockMetadata_Buddy::DeleteNode(Node* node)
|
||||||
@ -9527,56 +9400,36 @@ void VmaBlockMetadata_Buddy::DeleteNode(Node* node)
|
|||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VmaBlockMetadata_Buddy::ValidateNode(const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const
|
bool VmaBlockMetadata_Buddy::ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const
|
||||||
{
|
{
|
||||||
if(curr->parent != parent)
|
VMA_VALIDATE(curr->parent == parent);
|
||||||
{
|
VMA_VALIDATE((curr->buddy == VMA_NULL) == (parent == VMA_NULL));
|
||||||
return false;
|
VMA_VALIDATE(curr->buddy == VMA_NULL || curr->buddy->buddy == curr);
|
||||||
}
|
|
||||||
if((curr->buddy == VMA_NULL) != (parent == VMA_NULL))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(curr->buddy != VMA_NULL && curr->buddy->buddy != curr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch(curr->type)
|
switch(curr->type)
|
||||||
{
|
{
|
||||||
case Node::TYPE_FREE:
|
case Node::TYPE_FREE:
|
||||||
// curr->free.prev, next are validated separately.
|
// curr->free.prev, next are validated separately.
|
||||||
break;
|
break;
|
||||||
case Node::TYPE_ALLOCATION:
|
case Node::TYPE_ALLOCATION:
|
||||||
if(curr->allocation.alloc == VK_NULL_HANDLE)
|
++ctx.calculatedAllocationCount;
|
||||||
{
|
VMA_VALIDATE(curr->allocation.alloc != VK_NULL_HANDLE);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Node::TYPE_SPLIT:
|
case Node::TYPE_SPLIT:
|
||||||
{
|
{
|
||||||
const uint32_t childrenLevel = level + 1;
|
const uint32_t childrenLevel = level + 1;
|
||||||
const VkDeviceSize childrenLevelNodeSize = levelNodeSize / 2;
|
const VkDeviceSize childrenLevelNodeSize = levelNodeSize / 2;
|
||||||
const Node* const leftChild = curr->split.leftChild;
|
const Node* const leftChild = curr->split.leftChild;
|
||||||
if(leftChild == VMA_NULL)
|
VMA_VALIDATE(leftChild != VMA_NULL);
|
||||||
|
VMA_VALIDATE(leftChild->offset == curr->offset);
|
||||||
|
if(!ValidateNode(ctx, curr, leftChild, childrenLevel, childrenLevelNodeSize))
|
||||||
{
|
{
|
||||||
return false;
|
VMA_VALIDATE(false && "ValidateNode for left child failed.");
|
||||||
}
|
|
||||||
if(leftChild->offset != curr->offset)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!ValidateNode(curr, leftChild, childrenLevel, childrenLevelNodeSize))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
const Node* const rightChild = leftChild->buddy;
|
const Node* const rightChild = leftChild->buddy;
|
||||||
if(rightChild->offset != curr->offset + levelNodeSize)
|
VMA_VALIDATE(rightChild->offset == curr->offset + childrenLevelNodeSize);
|
||||||
|
if(!ValidateNode(ctx, curr, rightChild, childrenLevel, childrenLevelNodeSize))
|
||||||
{
|
{
|
||||||
return false;
|
VMA_VALIDATE(false && "ValidateNode for right child failed.");
|
||||||
}
|
|
||||||
if(!ValidateNode(curr, rightChild, childrenLevel, childrenLevelNodeSize))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -9639,6 +9492,8 @@ void VmaBlockMetadata_Buddy::FreeAtOffset(VmaAllocation alloc, VkDeviceSize offs
|
|||||||
VMA_ASSERT(node != VMA_NULL && node->type == Node::TYPE_ALLOCATION);
|
VMA_ASSERT(node != VMA_NULL && node->type == Node::TYPE_ALLOCATION);
|
||||||
VMA_ASSERT(alloc == VK_NULL_HANDLE || node->allocation.alloc == alloc);
|
VMA_ASSERT(alloc == VK_NULL_HANDLE || node->allocation.alloc == alloc);
|
||||||
|
|
||||||
|
--m_AllocationCount;
|
||||||
|
|
||||||
node->type = Node::TYPE_FREE;
|
node->type = Node::TYPE_FREE;
|
||||||
|
|
||||||
// Join free nodes if possible.
|
// Join free nodes if possible.
|
||||||
@ -9828,11 +9683,8 @@ void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator)
|
|||||||
|
|
||||||
bool VmaDeviceMemoryBlock::Validate() const
|
bool VmaDeviceMemoryBlock::Validate() const
|
||||||
{
|
{
|
||||||
if((m_hMemory == VK_NULL_HANDLE) ||
|
VMA_VALIDATE((m_hMemory != VK_NULL_HANDLE) &&
|
||||||
(m_pMetadata->GetSize() == 0))
|
(m_pMetadata->GetSize() != 0));
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_pMetadata->Validate();
|
return m_pMetadata->Validate();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user