Skip to content

Commit 88bf8cb

Browse files
Removed usage of __popcnt
Apparently some old processors don't support this instruction. It's up to the user to provide optimized implementation by defining macro VMA_COUNT_BITS_SET. Fixes #245
1 parent dc3f6bb commit 88bf8cb

1 file changed

Lines changed: 22 additions & 10 deletions

File tree

include/vk_mem_alloc.h

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,11 @@ static void vma_aligned_free(void* VMA_NULLABLE ptr)
26852685
#endif
26862686
#endif
26872687

2688+
#ifndef VMA_COUNT_BITS_SET
2689+
// Returns number of bits set to 1 in (v)
2690+
#define VMA_COUNT_BITS_SET(v) VmaCountBitsSet(v)
2691+
#endif
2692+
26882693
#ifndef VMA_BITSCAN_LSB
26892694
// Scans integer for index of first nonzero value from the Least Significant Bit (LSB). If mask is 0 then returns UINT8_MAX
26902695
#define VMA_BITSCAN_LSB(mask) VmaBitScanLSB(mask)
@@ -3073,22 +3078,29 @@ class VmaAllocationObjectAllocator;
30733078
#endif // _VMA_FORWARD_DECLARATIONS
30743079

30753080

3076-
#ifndef _VMA_FUNCTIONS
3077-
// Returns number of bits set to 1 in (v).
3078-
static inline uint32_t VmaCountBitsSet(uint32_t v)
3079-
{
3080-
#ifdef _MSC_VER
3081+
#ifndef _VMA_FUNCTIONS
3082+
3083+
/*
3084+
Returns number of bits set to 1 in (v).
3085+
3086+
On specific platforms and compilers you can use instrinsics like:
3087+
3088+
Visual Studio:
30813089
return __popcnt(v);
3082-
#elif defined __GNUC__ || defined __clang__
3090+
GCC, Clang:
30833091
return static_cast<uint32_t>(__builtin_popcount(v));
3084-
#else
3092+
3093+
Define macro VMA_COUNT_BITS_SET to provide your optimized implementation.
3094+
But you need to check in runtime whether user's CPU supports these, as some old processors don't.
3095+
*/
3096+
static inline uint32_t VmaCountBitsSet(uint32_t v)
3097+
{
30853098
uint32_t c = v - ((v >> 1) & 0x55555555);
30863099
c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
30873100
c = ((c >> 4) + c) & 0x0F0F0F0F;
30883101
c = ((c >> 8) + c) & 0x00FF00FF;
30893102
c = ((c >> 16) + c) & 0x0000FFFF;
30903103
return c;
3091-
#endif
30923104
}
30933105

30943106
static inline uint8_t VmaBitScanLSB(uint64_t mask)
@@ -14625,8 +14637,8 @@ VkResult VmaAllocator_T::FindMemoryTypeIndex(
1462514637
if((requiredFlags & ~currFlags) == 0)
1462614638
{
1462714639
// Calculate cost as number of bits from preferredFlags not present in this memory type.
14628-
uint32_t currCost = VmaCountBitsSet(preferredFlags & ~currFlags) +
14629-
VmaCountBitsSet(currFlags & notPreferredFlags);
14640+
uint32_t currCost = VMA_COUNT_BITS_SET(preferredFlags & ~currFlags) +
14641+
VMA_COUNT_BITS_SET(currFlags & notPreferredFlags);
1463014642
// Remember memory type with lowest cost.
1463114643
if(currCost < minCost)
1463214644
{

0 commit comments

Comments
 (0)