Fix for VmaBitScan functions in GCC and Clang. Fixed debug margin for generic algorithm.

Hopefully helps for #231.
Code by @medranSolus
This commit is contained in:
Adam Sawicki 2022-02-08 10:50:10 +01:00
parent ed2a72153e
commit bb29254253
2 changed files with 40 additions and 6 deletions

View File

@ -3108,7 +3108,7 @@ static inline uint8_t VmaBitScanLSB(uint32_t mask)
return static_cast<uint8_t>(pos); return static_cast<uint8_t>(pos);
return UINT8_MAX; return UINT8_MAX;
#elif defined __GNUC__ || defined __clang__ #elif defined __GNUC__ || defined __clang__
return static_cast<uint8_t>(__builtin_ffsl(mask)) - 1U; return static_cast<uint8_t>(__builtin_ffs(mask)) - 1U;
#else #else
uint8_t pos = 0; uint8_t pos = 0;
uint32_t bit = 1; uint32_t bit = 1;
@ -3130,10 +3130,10 @@ static inline uint8_t VmaBitScanMSB(uint64_t mask)
return static_cast<uint8_t>(pos); return static_cast<uint8_t>(pos);
#elif defined __GNUC__ || defined __clang__ #elif defined __GNUC__ || defined __clang__
if (mask) if (mask)
return static_cast<uint8_t>(__builtin_clzll(mask)); return 63 - static_cast<uint8_t>(__builtin_clzll(mask));
#else #else
uint8_t pos = 63; uint8_t pos = 63;
uint64_t bit = 1u << 63; uint64_t bit = 1ULL << 63;
do do
{ {
if (mask & bit) if (mask & bit)
@ -3152,10 +3152,10 @@ static inline uint8_t VmaBitScanMSB(uint32_t mask)
return static_cast<uint8_t>(pos); return static_cast<uint8_t>(pos);
#elif defined __GNUC__ || defined __clang__ #elif defined __GNUC__ || defined __clang__
if (mask) if (mask)
return static_cast<uint8_t>(__builtin_clzl(mask)); return 31 - static_cast<uint8_t>(__builtin_clz(mask));
#else #else
uint8_t pos = 31; uint8_t pos = 31;
uint32_t bit = 1 << 31; uint32_t bit = 1UL << 31;
do do
{ {
if (mask & bit) if (mask & bit)
@ -6961,7 +6961,7 @@ bool VmaBlockMetadata_Generic::CheckAllocation(
} }
// Start from offset equal to beginning of this suballocation. // Start from offset equal to beginning of this suballocation.
VkDeviceSize offset = suballoc.offset; VkDeviceSize offset = suballoc.offset + (suballocItem == m_Suballocations.cbegin() ? 0 : GetDebugMargin());
// Apply debugMargin from the end of previous alloc. // Apply debugMargin from the end of previous alloc.
if (debugMargin > 0) if (debugMargin > 0)
@ -10341,6 +10341,7 @@ void VmaBlockMetadata_TLSF::InsertFreeBlock(Block* block)
uint8_t memClass = SizeToMemoryClass(block->size); uint8_t memClass = SizeToMemoryClass(block->size);
uint16_t secondIndex = SizeToSecondIndex(block->size, memClass); uint16_t secondIndex = SizeToSecondIndex(block->size, memClass);
uint32_t index = GetListIndex(memClass, secondIndex); uint32_t index = GetListIndex(memClass, secondIndex);
VMA_ASSERT(index < m_ListsCount);
block->PrevFree() = VMA_NULL; block->PrevFree() = VMA_NULL;
block->NextFree() = m_FreeList[index]; block->NextFree() = m_FreeList[index];
m_FreeList[index] = block; m_FreeList[index] = block;

View File

@ -6667,6 +6667,38 @@ static void PerformPoolTests(FILE* file)
} }
} }
static void BasicTestTLSF()
{
wprintf(L"Basic test TLSF\n");
VmaVirtualBlock block;
VmaVirtualBlockCreateInfo blockInfo = {};
blockInfo.flags = VMA_VIRTUAL_BLOCK_CREATE_TLSF_ALGORITHM_BIT;
blockInfo.size = 50331648;
vmaCreateVirtualBlock(&blockInfo, &block);
VmaVirtualAllocationCreateInfo info = {};
info.alignment = 2;
VmaVirtualAllocation allocation[3] = {};
info.size = 576;
vmaVirtualAllocate(block, &info, allocation + 0, nullptr);
info.size = 648;
vmaVirtualAllocate(block, &info, allocation + 1, nullptr);
vmaVirtualFree(block, allocation[0]);
info.size = 720;
vmaVirtualAllocate(block, &info, allocation + 2, nullptr);
vmaVirtualFree(block, allocation[1]);
vmaVirtualFree(block, allocation[2]);
vmaDestroyVirtualBlock(block);
}
static void BasicTestBuddyAllocator() static void BasicTestBuddyAllocator()
{ {
wprintf(L"Basic test buddy allocator\n"); wprintf(L"Basic test buddy allocator\n");
@ -7050,6 +7082,7 @@ void Test()
ManuallyTestLinearAllocator(); ManuallyTestLinearAllocator();
TestLinearAllocatorMultiBlock(); TestLinearAllocatorMultiBlock();
BasicTestTLSF();
BasicTestBuddyAllocator(); BasicTestBuddyAllocator();
BasicTestAllocatePages(); BasicTestAllocatePages();