mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-11-26 16:34:35 +00:00
Added VmaAllocatorCreateInfo::flags, VmaAllocatorFlags, VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT.
This commit is contained in:
parent
f30ee85a15
commit
31341608f4
@ -143,8 +143,19 @@ Vulkan, as well as used by the library itself to make any CPU-side allocations.
|
|||||||
|
|
||||||
\section thread_safety Thread safety
|
\section thread_safety Thread safety
|
||||||
|
|
||||||
All calls to functions that take VmaAllocator as first parameter are safe to
|
- The library has no global state, so separate VmaAllocator objects can be used
|
||||||
call from multiple threads simultaneously, synchronized internally when needed.
|
independently.
|
||||||
|
- By default, all calls to functions that take VmaAllocator as first parameter
|
||||||
|
are safe to call from multiple threads simultaneously because they are
|
||||||
|
synchronized internally when needed.
|
||||||
|
- When the allocator is created with VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT
|
||||||
|
flag, calls to functions that take such VmaAllocator object must be
|
||||||
|
synchronized externally.
|
||||||
|
- Access to a VmaAllocation object must be externally synchronized. For example,
|
||||||
|
you must not call vmaGetAllocationInfo() and vmaDefragment() from different
|
||||||
|
threads at the same time if you pass the same VmaAllocation object to these
|
||||||
|
functions.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
@ -181,9 +192,23 @@ typedef struct VmaDeviceMemoryCallbacks {
|
|||||||
PFN_vmaFreeDeviceMemoryFunction pfnFree;
|
PFN_vmaFreeDeviceMemoryFunction pfnFree;
|
||||||
} VmaDeviceMemoryCallbacks;
|
} VmaDeviceMemoryCallbacks;
|
||||||
|
|
||||||
|
/// Flags for created VmaAllocator.
|
||||||
|
typedef enum VmaAllocatorFlagBits {
|
||||||
|
/** \brief Allocator and all objects created from it will not be synchronized internally, so you must guarantee they are used from only one thread at a time or synchronized externally by you.
|
||||||
|
|
||||||
|
Using this flag may increase performance because internal mutexes are not used.
|
||||||
|
*/
|
||||||
|
VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001,
|
||||||
|
|
||||||
|
VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
|
} VmaAllocatorFlagBits;
|
||||||
|
typedef VkFlags VmaAllocatorFlags;
|
||||||
|
|
||||||
/// Description of a Allocator to be created.
|
/// Description of a Allocator to be created.
|
||||||
typedef struct VmaAllocatorCreateInfo
|
typedef struct VmaAllocatorCreateInfo
|
||||||
{
|
{
|
||||||
|
/// Flags for created allocator. Use VmaAllocatorFlagBits enum.
|
||||||
|
VmaAllocatorFlags flags;
|
||||||
/// Vulkan physical device.
|
/// Vulkan physical device.
|
||||||
/** It must be valid throughout whole lifetime of created Allocator. */
|
/** It must be valid throughout whole lifetime of created Allocator. */
|
||||||
VkPhysicalDevice physicalDevice;
|
VkPhysicalDevice physicalDevice;
|
||||||
@ -1046,11 +1071,25 @@ static inline bool VmaIsBufferImageGranularityConflict(
|
|||||||
struct VmaMutexLock
|
struct VmaMutexLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VmaMutexLock(VMA_MUTEX& mutex) : m_Mutex(mutex) { mutex.Lock(); }
|
VmaMutexLock(VMA_MUTEX& mutex, bool useMutex) :
|
||||||
~VmaMutexLock() { m_Mutex.Unlock(); }
|
m_pMutex(useMutex ? &mutex : VMA_NULL)
|
||||||
|
{
|
||||||
|
if(m_pMutex)
|
||||||
|
{
|
||||||
|
m_pMutex->Lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~VmaMutexLock()
|
||||||
|
{
|
||||||
|
if(m_pMutex)
|
||||||
|
{
|
||||||
|
m_pMutex->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMA_MUTEX& m_Mutex;
|
VMA_MUTEX* m_pMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if VMA_DEBUG_GLOBAL_MUTEX
|
#if VMA_DEBUG_GLOBAL_MUTEX
|
||||||
@ -2380,6 +2419,7 @@ private:
|
|||||||
// Main allocator object.
|
// Main allocator object.
|
||||||
struct VmaAllocator_T
|
struct VmaAllocator_T
|
||||||
{
|
{
|
||||||
|
bool m_UseMutex;
|
||||||
VkDevice m_hDevice;
|
VkDevice m_hDevice;
|
||||||
bool m_AllocationCallbacksSpecified;
|
bool m_AllocationCallbacksSpecified;
|
||||||
VkAllocationCallbacks m_AllocationCallbacks;
|
VkAllocationCallbacks m_AllocationCallbacks;
|
||||||
@ -3837,6 +3877,7 @@ bool VmaDefragmentator::MoveMakesSense(
|
|||||||
// VmaAllocator_T
|
// VmaAllocator_T
|
||||||
|
|
||||||
VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
||||||
|
m_UseMutex((pCreateInfo->flags & VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT) == 0),
|
||||||
m_PhysicalDevice(pCreateInfo->physicalDevice),
|
m_PhysicalDevice(pCreateInfo->physicalDevice),
|
||||||
m_hDevice(pCreateInfo->device),
|
m_hDevice(pCreateInfo->device),
|
||||||
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
|
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
|
||||||
@ -3945,7 +3986,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
|
|||||||
{
|
{
|
||||||
uint32_t blockVectorType = VmaMemoryRequirementFlagsToBlockVectorType(vmaMemReq.flags);
|
uint32_t blockVectorType = VmaMemoryRequirementFlagsToBlockVectorType(vmaMemReq.flags);
|
||||||
|
|
||||||
VmaMutexLock lock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock lock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
VmaBlockVector* const blockVector = m_pBlockVectors[memTypeIndex][blockVectorType];
|
VmaBlockVector* const blockVector = m_pBlockVectors[memTypeIndex][blockVectorType];
|
||||||
VMA_ASSERT(blockVector);
|
VMA_ASSERT(blockVector);
|
||||||
|
|
||||||
@ -4142,7 +4183,7 @@ VkResult VmaAllocator_T::AllocateOwnMemory(
|
|||||||
|
|
||||||
// Register it in m_pOwnAllocations.
|
// Register it in m_pOwnAllocations.
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex]);
|
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||||
AllocationVectorType* pOwnAllocations = m_pOwnAllocations[memTypeIndex][map ? VMA_BLOCK_VECTOR_TYPE_MAPPED : VMA_BLOCK_VECTOR_TYPE_UNMAPPED];
|
AllocationVectorType* pOwnAllocations = m_pOwnAllocations[memTypeIndex][map ? VMA_BLOCK_VECTOR_TYPE_MAPPED : VMA_BLOCK_VECTOR_TYPE_UNMAPPED];
|
||||||
VMA_ASSERT(pOwnAllocations);
|
VMA_ASSERT(pOwnAllocations);
|
||||||
VmaAllocation* const pOwnAllocationsBeg = pOwnAllocations->data();
|
VmaAllocation* const pOwnAllocationsBeg = pOwnAllocations->data();
|
||||||
@ -4227,7 +4268,7 @@ void VmaAllocator_T::FreeMemory(const VmaAllocation allocation)
|
|||||||
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
|
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
|
||||||
const VMA_BLOCK_VECTOR_TYPE blockVectorType = allocation->GetBlockVectorType();
|
const VMA_BLOCK_VECTOR_TYPE blockVectorType = allocation->GetBlockVectorType();
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock lock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
|
|
||||||
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex][blockVectorType];
|
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex][blockVectorType];
|
||||||
VmaBlock* pBlock = allocation->GetBlock();
|
VmaBlock* pBlock = allocation->GetBlock();
|
||||||
@ -4280,7 +4321,7 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats)
|
|||||||
|
|
||||||
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
||||||
{
|
{
|
||||||
VmaMutexLock allocationsLock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock allocationsLock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
const uint32_t heapIndex = m_MemProps.memoryTypes[memTypeIndex].heapIndex;
|
const uint32_t heapIndex = m_MemProps.memoryTypes[memTypeIndex].heapIndex;
|
||||||
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
|
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
|
||||||
{
|
{
|
||||||
@ -4313,7 +4354,7 @@ void VmaAllocator_T::UnmapPersistentlyMappedMemory()
|
|||||||
{
|
{
|
||||||
// Process OwnAllocations.
|
// Process OwnAllocations.
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex]);
|
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||||
AllocationVectorType* pOwnAllocationsVector = m_pOwnAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
AllocationVectorType* pOwnAllocationsVector = m_pOwnAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
||||||
for(size_t ownAllocIndex = pOwnAllocationsVector->size(); ownAllocIndex--; )
|
for(size_t ownAllocIndex = pOwnAllocationsVector->size(); ownAllocIndex--; )
|
||||||
{
|
{
|
||||||
@ -4324,7 +4365,7 @@ void VmaAllocator_T::UnmapPersistentlyMappedMemory()
|
|||||||
|
|
||||||
// Process normal Allocations.
|
// Process normal Allocations.
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock lock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
||||||
pBlockVector->UnmapPersistentlyMappedMemory();
|
pBlockVector->UnmapPersistentlyMappedMemory();
|
||||||
}
|
}
|
||||||
@ -4350,7 +4391,7 @@ VkResult VmaAllocator_T::MapPersistentlyMappedMemory()
|
|||||||
{
|
{
|
||||||
// Process OwnAllocations.
|
// Process OwnAllocations.
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex]);
|
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||||
AllocationVectorType* pAllocationsVector = m_pOwnAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
AllocationVectorType* pAllocationsVector = m_pOwnAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
||||||
for(size_t ownAllocIndex = 0, ownAllocCount = pAllocationsVector->size(); ownAllocIndex < ownAllocCount; ++ownAllocIndex)
|
for(size_t ownAllocIndex = 0, ownAllocCount = pAllocationsVector->size(); ownAllocIndex < ownAllocCount; ++ownAllocIndex)
|
||||||
{
|
{
|
||||||
@ -4361,7 +4402,7 @@ VkResult VmaAllocator_T::MapPersistentlyMappedMemory()
|
|||||||
|
|
||||||
// Process normal Allocations.
|
// Process normal Allocations.
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock lock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
|
||||||
VkResult localResult = pBlockVector->MapPersistentlyMappedMemory();
|
VkResult localResult = pBlockVector->MapPersistentlyMappedMemory();
|
||||||
if(localResult != VK_SUCCESS)
|
if(localResult != VK_SUCCESS)
|
||||||
@ -4459,7 +4500,7 @@ VkResult VmaAllocator_T::Defragment(
|
|||||||
// Only HOST_VISIBLE memory types can be defragmented.
|
// Only HOST_VISIBLE memory types can be defragmented.
|
||||||
if((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
|
if((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock lock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
|
|
||||||
for(uint32_t blockVectorType = 0;
|
for(uint32_t blockVectorType = 0;
|
||||||
(blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT) && (result == VK_SUCCESS);
|
(blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT) && (result == VK_SUCCESS);
|
||||||
@ -4538,7 +4579,7 @@ void VmaAllocator_T::FreeOwnMemory(VmaAllocation allocation)
|
|||||||
|
|
||||||
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
|
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex]);
|
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||||
AllocationVectorType* const pOwnAllocations = m_pOwnAllocations[memTypeIndex][allocation->GetBlockVectorType()];
|
AllocationVectorType* const pOwnAllocations = m_pOwnAllocations[memTypeIndex][allocation->GetBlockVectorType()];
|
||||||
VMA_ASSERT(pOwnAllocations);
|
VMA_ASSERT(pOwnAllocations);
|
||||||
VmaAllocation* const pOwnAllocationsBeg = pOwnAllocations->data();
|
VmaAllocation* const pOwnAllocationsBeg = pOwnAllocations->data();
|
||||||
@ -4586,7 +4627,7 @@ void VmaAllocator_T::PrintDetailedMap(VmaStringBuilder& sb)
|
|||||||
bool ownAllocationsStarted = false;
|
bool ownAllocationsStarted = false;
|
||||||
for(size_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
for(size_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
||||||
{
|
{
|
||||||
VmaMutexLock ownAllocationsLock(m_OwnAllocationsMutex[memTypeIndex]);
|
VmaMutexLock ownAllocationsLock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
|
||||||
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
|
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
|
||||||
{
|
{
|
||||||
AllocationVectorType* const pOwnAllocVector = m_pOwnAllocations[memTypeIndex][blockVectorType];
|
AllocationVectorType* const pOwnAllocVector = m_pOwnAllocations[memTypeIndex][blockVectorType];
|
||||||
@ -4631,7 +4672,7 @@ void VmaAllocator_T::PrintDetailedMap(VmaStringBuilder& sb)
|
|||||||
bool allocationsStarted = false;
|
bool allocationsStarted = false;
|
||||||
for(size_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
for(size_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
||||||
{
|
{
|
||||||
VmaMutexLock globalAllocationsLock(m_BlocksMutex[memTypeIndex]);
|
VmaMutexLock globalAllocationsLock(m_BlocksMutex[memTypeIndex], m_UseMutex);
|
||||||
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
|
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
|
||||||
{
|
{
|
||||||
if(m_pBlockVectors[memTypeIndex][blockVectorType]->IsEmpty() == false)
|
if(m_pBlockVectors[memTypeIndex][blockVectorType]->IsEmpty() == false)
|
||||||
|
Loading…
Reference in New Issue
Block a user