mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-05 12:20:07 +00:00
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:
parent
b0425876ec
commit
2a22d61297
@ -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.
|
||||
@ -697,21 +695,21 @@ Set it to 0 or undefined to make the library using its own implementation of
|
||||
the containers.
|
||||
*/
|
||||
#if VMA_USE_STL_CONTAINERS
|
||||
#define VMA_USE_STL_VECTOR 1
|
||||
#define VMA_USE_STL_UNORDERED_MAP 1
|
||||
#define VMA_USE_STL_LIST 1
|
||||
#define VMA_USE_STL_VECTOR 1
|
||||
#define VMA_USE_STL_UNORDERED_MAP 1
|
||||
#define VMA_USE_STL_LIST 1
|
||||
#endif
|
||||
|
||||
#if VMA_USE_STL_VECTOR
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#if VMA_USE_STL_UNORDERED_MAP
|
||||
#include <unordered_map>
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
|
||||
#if VMA_USE_STL_LIST
|
||||
#include <list>
|
||||
#include <list>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -726,120 +724,172 @@ 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.
|
||||
#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)
|
||||
#define VMA_HEAVY_ASSERT(expr)
|
||||
// Normal assert to check for programmer's errors, especially in Debug configuration.
|
||||
#ifndef VMA_ASSERT
|
||||
#ifdef _DEBUG
|
||||
#define VMA_ASSERT(expr) assert(expr)
|
||||
#else
|
||||
#define VMA_ASSERT(expr)
|
||||
#endif
|
||||
#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)
|
||||
// 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
|
||||
#endif
|
||||
|
||||
#define VMA_MIN(v1, v2) (std::min((v1), (v2)))
|
||||
#define VMA_MAX(v1, v2) (std::max((v1), (v2)))
|
||||
#define VMA_SWAP(v1, v2) std::swap((v1), (v2))
|
||||
#ifndef VMA_NULL
|
||||
// Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.
|
||||
#define VMA_NULL nullptr
|
||||
#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_ALIGN_OF
|
||||
#define VMA_ALIGN_OF(type) (__alignof(type))
|
||||
#endif
|
||||
|
||||
#define VMA_DEBUG_LOG(format, ...)
|
||||
/*
|
||||
#define VMA_DEBUG_LOG(format, ...) do { \
|
||||
printf(format, __VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
} while(false)
|
||||
*/
|
||||
#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
|
||||
|
||||
#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 { \
|
||||
printf(format, __VA_ARGS__); \
|
||||
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);
|
||||
}
|
||||
static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num)
|
||||
{
|
||||
_ui64toa_s(num, outStr, strLen, 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void VmaUint32ToStr(char* outStr, size_t strLen, uint32_t num)
|
||||
{
|
||||
_ultoa_s(num, outStr, strLen, 10);
|
||||
}
|
||||
static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num)
|
||||
{
|
||||
_ui64toa_s(num, outStr, strLen, 10);
|
||||
}
|
||||
#ifndef VMA_MUTEX
|
||||
class VmaMutex
|
||||
{
|
||||
public:
|
||||
VmaMutex() { }
|
||||
~VmaMutex() { }
|
||||
void Lock() { m_Mutex.lock(); }
|
||||
void Unlock() { m_Mutex.unlock(); }
|
||||
private:
|
||||
std::mutex m_Mutex;
|
||||
};
|
||||
#define VMA_MUTEX VmaMutex
|
||||
#endif
|
||||
|
||||
#endif // #if VMA_STATS_STRING_ENABLED
|
||||
#ifndef VMA_BEST_FIT
|
||||
/**
|
||||
Main parameter for function assessing how good is a free suballocation for a new
|
||||
allocation request.
|
||||
|
||||
class VmaMutex
|
||||
{
|
||||
public:
|
||||
VmaMutex() { }
|
||||
~VmaMutex() { }
|
||||
void Lock() { m_Mutex.lock(); }
|
||||
void Unlock() { m_Mutex.unlock(); }
|
||||
private:
|
||||
std::mutex m_Mutex;
|
||||
};
|
||||
- Set to 1 to use Best-Fit algorithm - prefer smaller blocks, as close to the
|
||||
size of requested allocations as possible.
|
||||
- Set to 0 to use Worst-Fit algorithm - prefer larger blocks, as large as
|
||||
possible.
|
||||
|
||||
/*
|
||||
Main parameter for function assessing how good is a free suballocation for a new
|
||||
allocation request.
|
||||
Experiments in special testing environment showed that Best-Fit algorithm is
|
||||
better.
|
||||
*/
|
||||
#define VMA_BEST_FIT (1)
|
||||
#endif
|
||||
|
||||
- Set to true 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
|
||||
possible.
|
||||
#ifndef VMA_DEBUG_ALWAYS_OWN_MEMORY
|
||||
/**
|
||||
Every object will have its own allocation.
|
||||
Define to 1 for debugging purposes only.
|
||||
*/
|
||||
#define VMA_DEBUG_ALWAYS_OWN_MEMORY (0)
|
||||
#endif
|
||||
|
||||
Experiments in special testing environment showed that Best-Fit algorithm is
|
||||
better.
|
||||
*/
|
||||
static const bool VMA_BEST_FIT = true;
|
||||
#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.
|
||||
*/
|
||||
#define VMA_DEBUG_ALIGNMENT (1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Every object will have its own allocation.
|
||||
Enable for debugging purposes only.
|
||||
*/
|
||||
static const bool VMA_DEBUG_ALWAYS_OWN_MEMORY = false;
|
||||
#ifndef VMA_DEBUG_MARGIN
|
||||
/**
|
||||
Minimum margin between suballocations, in bytes.
|
||||
Set nonzero for debugging purposes only.
|
||||
*/
|
||||
#define VMA_DEBUG_MARGIN (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
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;
|
||||
#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)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Minimum margin between suballocations, in bytes.
|
||||
Set nonzero for debugging purposes only.
|
||||
*/
|
||||
static const VkDeviceSize VMA_DEBUG_MARGIN = 0;
|
||||
#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.
|
||||
*/
|
||||
#define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
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
|
||||
#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
|
||||
|
||||
/*
|
||||
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;
|
||||
#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
|
||||
|
||||
// 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_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);
|
||||
|
Loading…
Reference in New Issue
Block a user