mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-11-26 00:24:35 +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.
This commit is contained in:
parent
86ccd63a98
commit
8bc1a7df83
@ -137,8 +137,7 @@ vmaCreateBuffer(allocator, &bufferInfo, &memReq, &buffer, nullptr, n
|
||||
<pre class="fragment">vmaDestroyBuffer(allocator, buffer);
|
||||
</pre><h1><a class="anchor" id="configuration"></a>
|
||||
Configuration</h1>
|
||||
<p>Set VMA_STATS_STRING_ENABLED macro in <a class="el" href="vk__mem__alloc_8h.html">vk_mem_alloc.h</a> to 0 or 1 to disable/enable compilation of code for dumping internal allocator state to string in JSON format.</p>
|
||||
<p>Please check "CONFIGURATION" section in vk_mem_alloc.cpp file 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.</p>
|
||||
<p>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.</p>
|
||||
<h1><a class="anchor" id="custom_memory_allocator"></a>
|
||||
Custom memory allocator</h1>
|
||||
<p>You can use custom memory allocator by filling optional member <a class="el" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d" title="Custom allocation callbacks. ">VmaAllocatorCreateInfo::pAllocationCallbacks</a>. These functions will be passed to Vulkan, as well as used by the library itself to make any CPU-side allocations.</p>
|
||||
|
File diff suppressed because one or more lines are too long
@ -130,15 +130,11 @@ This function would also free memory bound to it.
|
||||
|
||||
\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 in vk_mem_alloc.cpp file 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
|
||||
|
||||
@ -459,12 +455,14 @@ void vmaDestroyImage(
|
||||
#include <cstdlib>
|
||||
|
||||
/*******************************************************************************
|
||||
CONFIGURATION
|
||||
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.
|
||||
@ -473,21 +471,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
|
||||
|
||||
/*
|
||||
@ -502,117 +500,168 @@ 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
|
||||
|
||||
#define VMA_DEBUG_LOG(format, ...)
|
||||
/*
|
||||
#define VMA_DEBUG_LOG(format, ...) do { \
|
||||
printf(format, __VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
} while(false)
|
||||
*/
|
||||
#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
|
||||
|
||||
#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
|
||||
@ -721,15 +770,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
|
||||
@ -1927,19 +1976,19 @@ struct VmaAllocator_T
|
||||
hysteresis to avoid pessimistic case of alternating creation and destruction
|
||||
of a VkDeviceMemory. */
|
||||
bool m_HasEmptyAllocation[VK_MAX_MEMORY_TYPES];
|
||||
VmaMutex m_AllocationsMutex[VK_MAX_MEMORY_TYPES];
|
||||
VMA_MUTEX m_AllocationsMutex[VK_MAX_MEMORY_TYPES];
|
||||
|
||||
// Each vector is sorted by memory (handle value).
|
||||
typedef VmaVector< VmaOwnAllocation, VmaStlAllocator<VmaOwnAllocation> > OwnAllocationVectorType;
|
||||
OwnAllocationVectorType* m_pOwnAllocations[VK_MAX_MEMORY_TYPES];
|
||||
VmaMutex m_OwnAllocationsMutex[VK_MAX_MEMORY_TYPES];
|
||||
VMA_MUTEX m_OwnAllocationsMutex[VK_MAX_MEMORY_TYPES];
|
||||
|
||||
// Sorted by first (VkBuffer handle value).
|
||||
VMA_MAP_TYPE(VkBuffer, VkMappedMemoryRange) m_BufferToMemoryMap;
|
||||
VmaMutex m_BufferToMemoryMapMutex;
|
||||
VMA_MUTEX m_BufferToMemoryMapMutex;
|
||||
// Sorted by first (VkImage handle value).
|
||||
VMA_MAP_TYPE(VkImage, VkMappedMemoryRange) m_ImageToMemoryMap;
|
||||
VmaMutex m_ImageToMemoryMapMutex;
|
||||
VMA_MUTEX m_ImageToMemoryMapMutex;
|
||||
|
||||
VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo);
|
||||
~VmaAllocator_T();
|
||||
@ -1954,7 +2003,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);
|
||||
}
|
||||
|
||||
@ -2427,7 +2476,7 @@ bool VmaAllocation::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.
|
||||
@ -2902,9 +2951,9 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
||||
memset(&m_pOwnAllocations, 0, sizeof(m_pOwnAllocations));
|
||||
|
||||
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