Changed "CONFIGURATION SECTION" to contain #ifndef so you can define these macros before including this header, not necessarily change them in the file. (Cherry pick from v1)

This commit is contained in:
Adam Sawicki 2017-07-04 15:52:30 +02:00
parent b0425876ec
commit 2a22d61297

View File

@ -122,15 +122,11 @@ When you want to create a buffer or image:
\section configuration Configuration
Set VMA_STATS_STRING_ENABLED macro in vk_mem_alloc.h to 0 or 1 to disable/enable
compilation of code for dumping internal allocator state to string in JSON
format.
Please check "CONFIGURATION SECTION" below to find macros and other definitions
that you can change to connect the library to your own implementation of basic
facilities like assert, min and max functions, mutex etc. C++ STL is used by
default, but changing these allows you to get rid of any STL usage if you want,
as many game developers tend to do.
Please check "CONFIGURATION SECTION" in the code to find macros that you can define
before each #include of this file or change directly in this file to provide
your own implementation of basic facilities like assert, min and max functions,
mutex etc. C++ STL is used by default, but changing these allows you to get rid
of any STL usage if you want, as many game developers tend to do.
\section custom_memory_allocator Custom memory allocator
@ -685,10 +681,12 @@ void vmaDestroyImage(
/*******************************************************************************
CONFIGURATION SECTION
Change these definitions depending on your environment.
Define some of these macros before each #include of this header or change them
here if you need other then default behavior depending on your environment.
*/
#define VMA_USE_STL_CONTAINERS 0
// Define this macro to 1 to make the library use STL containers instead of its own implementation.
//#define VMA_USE_STL_CONTAINERS 1
/* Set this macro to 1 to make the library including and using STL containers:
std::pair, std::vector, std::list, std::unordered_map.
@ -726,38 +724,67 @@ remove them if not needed.
#include <malloc.h> // for aligned_alloc()
#endif
#ifdef _DEBUG
// Normal assert to check for programmer's errors, especially in Debug configuration.
#ifndef VMA_ASSERT
#ifdef _DEBUG
#define VMA_ASSERT(expr) assert(expr)
// Assert that will be called very often, like inside data structures e.g. operator[].
// Making it non-empty can make program slow.
#define VMA_HEAVY_ASSERT(expr) //VMA_ASSERT(expr)
#else
#define VMA_ASSERT(expr)
#endif
#endif
// Assert that will be called very often, like inside data structures e.g. operator[].
// Making it non-empty can make program slow.
#ifndef VMA_HEAVY_ASSERT
#ifdef _DEBUG
#define VMA_HEAVY_ASSERT(expr) //VMA_ASSERT(expr)
#else
#define VMA_HEAVY_ASSERT(expr)
#endif
// Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.
#define VMA_NULL nullptr
#define VMA_ALIGN_OF(type) (__alignof(type))
#if defined(_WIN32)
#define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (_aligned_malloc((size), (alignment)))
#define VMA_SYSTEM_FREE(ptr) _aligned_free(ptr)
#else
#define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (aligned_alloc((alignment), (size) ))
#define VMA_SYSTEM_FREE(ptr) free(ptr)
#endif
#ifndef VMA_NULL
// Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.
#define VMA_NULL nullptr
#endif
#ifndef VMA_ALIGN_OF
#define VMA_ALIGN_OF(type) (__alignof(type))
#endif
#ifndef VMA_SYSTEM_ALIGNED_MALLOC
#if defined(_WIN32)
#define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (_aligned_malloc((size), (alignment)))
#else
#define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (aligned_alloc((alignment), (size) ))
#endif
#endif
#ifndef VMA_SYSTEM_FREE
#if defined(_WIN32)
#define VMA_SYSTEM_FREE(ptr) _aligned_free(ptr)
#else
#define VMA_SYSTEM_FREE(ptr) free(ptr)
#endif
#endif
#ifndef VMA_MIN
#define VMA_MIN(v1, v2) (std::min((v1), (v2)))
#endif
#ifndef VMA_MAX
#define VMA_MAX(v1, v2) (std::max((v1), (v2)))
#endif
#ifndef VMA_SWAP
#define VMA_SWAP(v1, v2) std::swap((v1), (v2))
#endif
// You can just comment this out to use internal sorting implementation.
//#define VMA_SORT(beg, end, cmp) std::sort(beg, end, cmp)
#ifndef VMA_SORT
#define VMA_SORT(beg, end, cmp) std::sort(beg, end, cmp)
#endif
#ifndef VMA_DEBUG_LOG
#define VMA_DEBUG_LOG(format, ...)
/*
#define VMA_DEBUG_LOG(format, ...) do { \
@ -765,9 +792,10 @@ remove them if not needed.
printf("\n"); \
} while(false)
*/
#endif
// Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString.
#if VMA_STATS_STRING_ENABLED
static inline void VmaUint32ToStr(char* outStr, size_t strLen, uint32_t num)
{
_ultoa_s(num, outStr, strLen, 10);
@ -776,9 +804,9 @@ static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num)
{
_ui64toa_s(num, outStr, strLen, 10);
}
#endif
#endif // #if VMA_STATS_STRING_ENABLED
#ifndef VMA_MUTEX
class VmaMutex
{
public:
@ -789,57 +817,79 @@ public:
private:
std::mutex m_Mutex;
};
#define VMA_MUTEX VmaMutex
#endif
/*
#ifndef VMA_BEST_FIT
/**
Main parameter for function assessing how good is a free suballocation for a new
allocation request.
- Set to true to use Best-Fit algorithm - prefer smaller blocks, as close to the
- Set to 1 to use Best-Fit algorithm - prefer smaller blocks, as close to the
size of requested allocations as possible.
- Set to false to use Worst-Fit algorithm - prefer larger blocks, as large as
- Set to 0 to use Worst-Fit algorithm - prefer larger blocks, as large as
possible.
Experiments in special testing environment showed that Best-Fit algorithm is
better.
*/
static const bool VMA_BEST_FIT = true;
#define VMA_BEST_FIT (1)
#endif
/*
#ifndef VMA_DEBUG_ALWAYS_OWN_MEMORY
/**
Every object will have its own allocation.
Enable for debugging purposes only.
Define to 1 for debugging purposes only.
*/
static const bool VMA_DEBUG_ALWAYS_OWN_MEMORY = false;
#define VMA_DEBUG_ALWAYS_OWN_MEMORY (0)
#endif
/*
#ifndef VMA_DEBUG_ALIGNMENT
/**
Minimum alignment of all suballocations, in bytes.
Set to more than 1 for debugging purposes only. Must be power of two.
*/
static const VkDeviceSize VMA_DEBUG_ALIGNMENT = 1;
#define VMA_DEBUG_ALIGNMENT (1)
#endif
/*
#ifndef VMA_DEBUG_MARGIN
/**
Minimum margin between suballocations, in bytes.
Set nonzero for debugging purposes only.
*/
static const VkDeviceSize VMA_DEBUG_MARGIN = 0;
#define VMA_DEBUG_MARGIN (0)
#endif
/*
#ifndef VMA_DEBUG_GLOBAL_MUTEX
/**
Set this to 1 for debugging purposes only, to enable single mutex protecting all
entry calls to the library. Can be useful for debugging multithreading issues.
*/
#define VMA_DEBUG_GLOBAL_MUTEX 0
#define VMA_DEBUG_GLOBAL_MUTEX (0)
#endif
/*
#ifndef VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY
/**
Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity.
Set to more than 1 for debugging purposes only. Must be power of two.
*/
static const VkDeviceSize VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY = 1;
#define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)
#endif
// Maximum size of a memory heap in Vulkan to consider it "small".
static const VkDeviceSize VMA_SMALL_HEAP_MAX_SIZE = 512 * 1024 * 1024;
// Default size of a block allocated as single VkDeviceMemory from a "large" heap.
static const VkDeviceSize VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE = 256 * 1024 * 1024;
// Default size of a block allocated as single VkDeviceMemory from a "small" heap.
static const VkDeviceSize VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE = 64 * 1024 * 1024;
#ifndef VMA_SMALL_HEAP_MAX_SIZE
/// Maximum size of a memory heap in Vulkan to consider it "small".
#define VMA_SMALL_HEAP_MAX_SIZE (512 * 1024 * 1024)
#endif
#ifndef VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE
/// Default size of a block allocated as single VkDeviceMemory from a "large" heap.
#define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256 * 1024 * 1024)
#endif
#ifndef VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE
/// Default size of a block allocated as single VkDeviceMemory from a "small" heap.
#define VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE (64 * 1024 * 1024)
#endif
/*******************************************************************************
END OF CONFIGURATION
@ -989,15 +1039,15 @@ static inline bool VmaIsBufferImageGranularityConflict(
struct VmaMutexLock
{
public:
VmaMutexLock(VmaMutex& mutex) : m_Mutex(mutex) { mutex.Lock(); }
VmaMutexLock(VMA_MUTEX& mutex) : m_Mutex(mutex) { mutex.Lock(); }
~VmaMutexLock() { m_Mutex.Unlock(); }
private:
VmaMutex& m_Mutex;
VMA_MUTEX& m_Mutex;
};
#if VMA_DEBUG_GLOBAL_MUTEX
static VmaMutex gDebugGlobalMutex;
static VMA_MUTEX gDebugGlobalMutex;
#define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex);
#else
#define VMA_DEBUG_GLOBAL_MUTEX_LOCK
@ -2341,12 +2391,12 @@ struct VmaAllocator_T
hysteresis to avoid pessimistic case of alternating creation and destruction
of a VkDeviceMemory. */
bool m_HasEmptyBlock[VK_MAX_MEMORY_TYPES];
VmaMutex m_BlocksMutex[VK_MAX_MEMORY_TYPES];
VMA_MUTEX m_BlocksMutex[VK_MAX_MEMORY_TYPES];
// Each vector is sorted by memory (handle value).
typedef VmaVector< VmaAllocation, VmaStlAllocator<VmaAllocation> > AllocationVectorType;
AllocationVectorType* m_pOwnAllocations[VK_MAX_MEMORY_TYPES][VMA_BLOCK_VECTOR_TYPE_COUNT];
VmaMutex m_OwnAllocationsMutex[VK_MAX_MEMORY_TYPES];
VMA_MUTEX m_OwnAllocationsMutex[VK_MAX_MEMORY_TYPES];
VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo);
~VmaAllocator_T();
@ -2361,7 +2411,7 @@ struct VmaAllocator_T
VkDeviceSize GetBufferImageGranularity() const
{
return VMA_MAX(
VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,
static_cast<VkDeviceSize>(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY),
m_PhysicalDeviceProperties.limits.bufferImageGranularity);
}
@ -2914,7 +2964,7 @@ bool VmaBlock::CheckAllocation(
*pOffset += VMA_DEBUG_MARGIN;
// Apply alignment.
const VkDeviceSize alignment = VMA_MAX(allocAlignment, VMA_DEBUG_ALIGNMENT);
const VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast<VkDeviceSize>(VMA_DEBUG_ALIGNMENT));
*pOffset = VmaAlignUp(*pOffset, alignment);
// Check previous suballocations for BufferImageGranularity conflicts.
@ -3828,9 +3878,9 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
}
m_PreferredLargeHeapBlockSize = (pCreateInfo->preferredLargeHeapBlockSize != 0) ?
pCreateInfo->preferredLargeHeapBlockSize : VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE;
pCreateInfo->preferredLargeHeapBlockSize : static_cast<VkDeviceSize>(VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);
m_PreferredSmallHeapBlockSize = (pCreateInfo->preferredSmallHeapBlockSize != 0) ?
pCreateInfo->preferredSmallHeapBlockSize : VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE;
pCreateInfo->preferredSmallHeapBlockSize : static_cast<VkDeviceSize>(VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE);
vkGetPhysicalDeviceProperties(m_PhysicalDevice, &m_PhysicalDeviceProperties);
vkGetPhysicalDeviceMemoryProperties(m_PhysicalDevice, &m_MemProps);