packages feed

VulkanMemoryAllocator 0.10.5.1 → 0.11

raw patch · 5 files changed

+210/−95 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- VulkanMemoryAllocator: instance GHC.Classes.Eq VulkanMemoryAllocator.DefragmentationInfo
+ VulkanMemoryAllocator: [$sel:breakCallbackUserData:DefragmentationInfo] :: DefragmentationInfo -> Ptr ()
+ VulkanMemoryAllocator: [$sel:pfnBreakCallback:DefragmentationInfo] :: DefragmentationInfo -> PFN_vmaCheckDefragmentationBreakFunction
+ VulkanMemoryAllocator: type FN_vmaCheckDefragmentationBreakFunction = ("pUserData" ::: Ptr ()) -> IO Bool32
+ VulkanMemoryAllocator: type PFN_vmaCheckDefragmentationBreakFunction = FunPtr FN_vmaCheckDefragmentationBreakFunction
- VulkanMemoryAllocator: DefragmentationInfo :: DefragmentationFlags -> Pool -> DeviceSize -> Word32 -> DefragmentationInfo
+ VulkanMemoryAllocator: DefragmentationInfo :: DefragmentationFlags -> Pool -> DeviceSize -> Word32 -> PFN_vmaCheckDefragmentationBreakFunction -> Ptr () -> DefragmentationInfo

Files

VulkanMemoryAllocator.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           VulkanMemoryAllocator-version:        0.10.5.1+version:        0.11 synopsis:       Bindings to the VulkanMemoryAllocator library category:       Graphics homepage:       https://github.com/expipiplus1/vulkan#readme
VulkanMemoryAllocator/include/vk_mem_alloc.h view
@@ -126,9 +126,7 @@ extern "C" { #endif -#ifndef VULKAN_H_-    #include <vulkan/vulkan.h>-#endif+#include <vulkan/vulkan.h>  #if !defined(VMA_VULKAN_VERSION)     #if defined(VK_VERSION_1_3)@@ -234,6 +232,12 @@     #define VMA_CALL_POST #endif +// Define this macro to decorate pNext pointers with an attribute specifying the Vulkan+// structure that will be extended via the pNext chain.+#ifndef VMA_EXTENDS_VK_STRUCT+    #define VMA_EXTENDS_VK_STRUCT(vkStruct)+#endif+ // Define this macro to decorate pointers with an attribute specifying the // length of the array they point to if they are not null. //@@ -1319,7 +1323,7 @@     Please note that some structures, e.g. `VkMemoryPriorityAllocateInfoEXT`, `VkMemoryDedicatedAllocateInfoKHR`,     can be attached automatically by this library when using other, more convenient of its features.     */-    void* VMA_NULLABLE pMemoryAllocateNext;+    void* VMA_NULLABLE VMA_EXTENDS_VK_STRUCT(VkMemoryAllocateInfo) pMemoryAllocateNext; } VmaPoolCreateInfo;  /** @} */@@ -1389,6 +1393,12 @@     const char* VMA_NULLABLE pName; } VmaAllocationInfo; +/** Callback function called during vmaBeginDefragmentation() to check custom criterion about ending current defragmentation pass.++Should return true if the defragmentation needs to stop current pass.+*/+typedef VkBool32 (VKAPI_PTR* PFN_vmaCheckDefragmentationBreakFunction)(void* VMA_NULLABLE pUserData);+ /** \brief Parameters for defragmentation.  To be used with function vmaBeginDefragmentation().@@ -1412,6 +1422,13 @@     `0` means no limit.     */     uint32_t maxAllocationsPerPass;+    /** \brief Optional custom callback for stopping vmaBeginDefragmentation().++    Have to return true for breaking current defragmentation pass.+    */+    PFN_vmaCheckDefragmentationBreakFunction VMA_NULLABLE pfnBreakCallback;+    /// \brief Optional data to pass to custom callback for stopping pass of defragmentation.+    void* VMA_NULLABLE pBreakCallbackUserData; } VmaDefragmentationInfo;  /// Single move of an allocation to be done for defragmentation.@@ -2227,7 +2244,7 @@     VmaAllocation VMA_NOT_NULL allocation,     VkDeviceSize allocationLocalOffset,     VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer,-    const void* VMA_NULLABLE pNext);+    const void* VMA_NULLABLE VMA_EXTENDS_VK_STRUCT(VkBindBufferMemoryInfoKHR) pNext);  /** \brief Binds image to allocation. @@ -2264,7 +2281,7 @@     VmaAllocation VMA_NOT_NULL allocation,     VkDeviceSize allocationLocalOffset,     VkImage VMA_NOT_NULL_NON_DISPATCHABLE image,-    const void* VMA_NULLABLE pNext);+    const void* VMA_NULLABLE VMA_EXTENDS_VK_STRUCT(VkBindImageMemoryInfoKHR) pNext);  /** \brief Creates a new `VkBuffer`, allocates and binds memory for it. @@ -2607,13 +2624,25 @@ #include <utility> #include <type_traits> +#if !defined(VMA_CPP20)+    #if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20+        #define VMA_CPP20 1+    #else+        #define VMA_CPP20 0+    #endif+#endif+ #ifdef _MSC_VER     #include <intrin.h> // For functions like __popcnt, _BitScanForward etc. #endif-#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20+#if VMA_CPP20     #include <bit> // For std::popcount #endif +#if VMA_STATS_STRING_ENABLED+    #include <cstdio> // For snprintf+#endif+ /******************************************************************************* CONFIGURATION SECTION @@ -2647,8 +2676,7 @@ #endif  #ifndef VMA_USE_STL_SHARED_MUTEX-    // Compiler conforms to C++17.-    #if __cplusplus >= 201703L+    #if __cplusplus >= 201703L || _MSVC_LANG >= 201703L // C++17         #define VMA_USE_STL_SHARED_MUTEX 1     // Visual studio defines __cplusplus properly only when passed additional parameter: /Zc:__cplusplus     // Otherwise it is always 199711L, despite shared_mutex works since Visual Studio 2015 Update 2.@@ -2693,6 +2721,14 @@    #define VMA_NULL   nullptr #endif +#ifndef VMA_FALLTHROUGH+    #if __cplusplus >= 201703L || _MSVC_LANG >= 201703L // C++17+        #define VMA_FALLTHROUGH [[fallthrough]]+    #else+        #define VMA_FALLTHROUGH+    #endif+#endif+ // Normal assert to check for programmer's errors, especially in Debug configuration. #ifndef VMA_ASSERT    #ifdef NDEBUG@@ -2769,7 +2805,7 @@ {     return _aligned_malloc(size, alignment); }-#elif __cplusplus >= 201703L // Compiler conforms to C++17.+#elif __cplusplus >= 201703L || _MSVC_LANG >= 201703L // C++17 static void* vma_aligned_alloc(size_t alignment, size_t size) {     return aligned_alloc(alignment, size);@@ -2795,7 +2831,7 @@ #endif  #ifndef VMA_ALIGN_OF-   #define VMA_ALIGN_OF(type)       (__alignof(type))+   #define VMA_ALIGN_OF(type)       (alignof(type)) #endif  #ifndef VMA_SYSTEM_ALIGNED_MALLOC@@ -2856,6 +2892,21 @@     #define VMA_DEBUG_LOG(str)   VMA_DEBUG_LOG_FORMAT("%s", (str)) #endif +#ifndef VMA_CLASS_NO_COPY+    #define VMA_CLASS_NO_COPY(className) \+        private: \+            className(const className&) = delete; \+            className& operator=(const className&) = delete;+#endif+#ifndef VMA_CLASS_NO_COPY_NO_MOVE+    #define VMA_CLASS_NO_COPY_NO_MOVE(className) \+        private: \+            className(const className&) = delete; \+            className(className&&) = delete; \+            className& operator=(const className&) = delete; \+            className& operator=(className&&) = delete;+#endif+ // Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString. #if VMA_STATS_STRING_ENABLED     static inline void VmaUint32ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint32_t num)@@ -2875,7 +2926,9 @@ #ifndef VMA_MUTEX     class VmaMutex     {+    VMA_CLASS_NO_COPY_NO_MOVE(VmaMutex)     public:+        VmaMutex() { }         void Lock() { m_Mutex.lock(); }         void Unlock() { m_Mutex.unlock(); }         bool TryLock() { return m_Mutex.try_lock(); }@@ -3041,13 +3094,6 @@     #define VMA_MAPPING_HYSTERESIS_ENABLED 1 #endif -#ifndef VMA_CLASS_NO_COPY-    #define VMA_CLASS_NO_COPY(className) \-        private: \-            className(const className&) = delete; \-            className& operator=(const className&) = delete;-#endif- #define VMA_VALIDATE(cond) do { if(!(cond)) { \         VMA_ASSERT(0 && "Validation failed: " #cond); \         return false; \@@ -3225,7 +3271,7 @@ */ static inline uint32_t VmaCountBitsSet(uint32_t v) {-#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20+#if VMA_CPP20     return std::popcount(v); #else     uint32_t c = v - ((v >> 1) & 0x55555555);@@ -3540,7 +3586,7 @@ template <typename CmpLess, typename IterT, typename KeyT> static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT& key, const CmpLess& cmp) {-    size_t down = 0, up = (end - beg);+    size_t down = 0, up = size_t(end - beg);     while (down < up)     {         const size_t mid = down + (up - down) / 2;  // Overflow-safe midpoint calculation@@ -3656,7 +3702,7 @@             return false;         }         // This relies on values of VK_IMAGE_USAGE_TRANSFER* being the same VK_BUFFER_IMAGE_TRANSFER*.-        const bool deviceAccess = (bufImgUsage & ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) != 0;+        const bool deviceAccess = (bufImgUsage & ~static_cast<VkFlags>(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) != 0;         const bool hostAccessSequentialWrite = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT) != 0;         const bool hostAccessRandom = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) != 0;         const bool hostAccessAllowTransferInstead = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT) != 0;@@ -3666,18 +3712,21 @@         // CPU random access - e.g. a buffer written to or transferred from GPU to read back on CPU.         if(hostAccessRandom)         {-            if(!isIntegratedGPU && deviceAccess && hostAccessAllowTransferInstead && !preferHost)+            // Prefer cached. Cannot require it, because some platforms don't have it (e.g. Raspberry Pi - see #362)!+            outPreferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;++            if (!isIntegratedGPU && deviceAccess && hostAccessAllowTransferInstead && !preferHost)             {                 // Nice if it will end up in HOST_VISIBLE, but more importantly prefer DEVICE_LOCAL.                 // Omitting HOST_VISIBLE here is intentional.                 // In case there is DEVICE_LOCAL | HOST_VISIBLE | HOST_CACHED, it will pick that one.                 // Otherwise, this will give same weight to DEVICE_LOCAL as HOST_VISIBLE | HOST_CACHED and select the former if occurs first on the list.-                outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;+                outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;             }             else             {-                // Always CPU memory, cached.-                outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;+                // Always CPU memory.+                outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;             }         }         // CPU sequential write - may be CPU or host-visible GPU memory, uncached and write-combined.@@ -3716,19 +3765,18 @@         // No CPU access         else         {-            // GPU access, no CPU access (e.g. a color attachment image) - prefer GPU memory-            if(deviceAccess)-            {-                // ...unless there is a clear preference from the user not to do so.-                if(preferHost)-                    outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;-                else-                    outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;-            }+            // if(deviceAccess)+            //+            // GPU access, no CPU access (e.g. a color attachment image) - prefer GPU memory,+            // unless there is a clear preference from the user not to do so.+            //+            // else:+            //             // No direct GPU access, no CPU access, just transfers.             // It may be staging copy intended for e.g. preserving image for next frame (then better GPU memory) or             // a "swap file" copy to free some GPU memory (then better CPU memory).             // Up to the user to decide. If no preferece, assume the former and choose GPU memory.+             if(preferHost)                 outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;             else@@ -3947,7 +3995,7 @@ // Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope). struct VmaMutexLock {-    VMA_CLASS_NO_COPY(VmaMutexLock)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaMutexLock) public:     VmaMutexLock(VMA_MUTEX& mutex, bool useMutex = true) :         m_pMutex(useMutex ? &mutex : VMA_NULL)@@ -3963,7 +4011,7 @@ // Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for reading. struct VmaMutexLockRead {-    VMA_CLASS_NO_COPY(VmaMutexLockRead)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaMutexLockRead) public:     VmaMutexLockRead(VMA_RW_MUTEX& mutex, bool useMutex) :         m_pMutex(useMutex ? &mutex : VMA_NULL)@@ -3979,7 +4027,7 @@ // Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for writing. struct VmaMutexLockWrite {-    VMA_CLASS_NO_COPY(VmaMutexLockWrite)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaMutexLockWrite) public:     VmaMutexLockWrite(VMA_RW_MUTEX& mutex, bool useMutex)         : m_pMutex(useMutex ? &mutex : VMA_NULL)@@ -4002,11 +4050,11 @@  #ifndef _VMA_ATOMIC_TRANSACTIONAL_INCREMENT // An object that increments given atomic but decrements it back in the destructor unless Commit() is called.-template<typename T>+template<typename AtomicT> struct AtomicTransactionalIncrement { public:-    typedef std::atomic<T> AtomicT;+    using T = decltype(AtomicT().load());      ~AtomicTransactionalIncrement()     {@@ -4434,7 +4482,7 @@ template<typename T> class VmaPoolAllocator {-    VMA_CLASS_NO_COPY(VmaPoolAllocator)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaPoolAllocator) public:     VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity);     ~VmaPoolAllocator();@@ -4567,7 +4615,7 @@ template<typename T> class VmaRawList {-    VMA_CLASS_NO_COPY(VmaRawList)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaRawList) public:     typedef VmaListItem<T> ItemType; @@ -4830,7 +4878,7 @@ template<typename T, typename AllocatorT> class VmaList {-    VMA_CLASS_NO_COPY(VmaList)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaList) public:     class reverse_iterator;     class const_iterator;@@ -5422,7 +5470,7 @@     char* p = &buf[10];     do     {-        *--p = '0' + (num % 10);+        *--p = '0' + (char)(num % 10);         num /= 10;     } while (num);     Add(p);@@ -5435,7 +5483,7 @@     char* p = &buf[20];     do     {-        *--p = '0' + (num % 10);+        *--p = '0' + (char)(num % 10);         num /= 10;     } while (num);     Add(p);@@ -5457,7 +5505,7 @@ */ class VmaJsonWriter {-    VMA_CLASS_NO_COPY(VmaJsonWriter)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaJsonWriter) public:     // sb - string builder to write the document to. Must remain alive for the whole lifetime of this object.     VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb);@@ -5649,7 +5697,6 @@             break;         default:             VMA_ASSERT(0 && "Character not currently supported.");-            break;         }     } }@@ -5796,7 +5843,7 @@  class VmaMappingHysteresis {-    VMA_CLASS_NO_COPY(VmaMappingHysteresis)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaMappingHysteresis) public:     VmaMappingHysteresis() = default; @@ -5903,7 +5950,7 @@ */ class VmaDeviceMemoryBlock {-    VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaDeviceMemoryBlock) public:     VmaBlockMetadata* m_pMetadata; @@ -6126,6 +6173,7 @@ */ class VmaDedicatedAllocationList {+    VMA_CLASS_NO_COPY_NO_MOVE(VmaDedicatedAllocationList) public:     VmaDedicatedAllocationList() {}     ~VmaDedicatedAllocationList();@@ -6311,6 +6359,7 @@ */ class VmaBlockMetadata {+    VMA_CLASS_NO_COPY_NO_MOVE(VmaBlockMetadata) public:     // pAllocationCallbacks, if not null, must be owned externally - alive and unchanged for the whole lifetime of this object.     VmaBlockMetadata(const VkAllocationCallbacks* pAllocationCallbacks,@@ -6377,7 +6426,7 @@ protected:     const VkAllocationCallbacks* GetAllocationCallbacks() const { return m_pAllocationCallbacks; }     VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; }-    VkDeviceSize GetDebugMargin() const { return IsVirtual() ? 0 : VMA_DEBUG_MARGIN; }+    VkDeviceSize GetDebugMargin() const { return VkDeviceSize(IsVirtual() ? 0 : VMA_DEBUG_MARGIN); }      void DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size, void* userData) const; #if VMA_STATS_STRING_ENABLED@@ -6751,7 +6800,7 @@ {     friend class VmaDefragmentationAlgorithm_Generic;     friend class VmaDefragmentationAlgorithm_Fast;-    VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaBlockMetadata_Generic) public:     VmaBlockMetadata_Generic(const VkAllocationCallbacks* pAllocationCallbacks,         VkDeviceSize bufferImageGranularity, bool isVirtual);@@ -7590,7 +7639,7 @@ */ class VmaBlockMetadata_Linear : public VmaBlockMetadata {-    VMA_CLASS_NO_COPY(VmaBlockMetadata_Linear)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaBlockMetadata_Linear) public:     VmaBlockMetadata_Linear(const VkAllocationCallbacks* pAllocationCallbacks,         VkDeviceSize bufferImageGranularity, bool isVirtual);@@ -9209,7 +9258,7 @@ */ class VmaBlockMetadata_Buddy : public VmaBlockMetadata {-    VMA_CLASS_NO_COPY(VmaBlockMetadata_Buddy)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaBlockMetadata_Buddy) public:     VmaBlockMetadata_Buddy(const VkAllocationCallbacks* pAllocationCallbacks,         VkDeviceSize bufferImageGranularity, bool isVirtual);@@ -9908,7 +9957,7 @@ // VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT for fastest alloc time possible. class VmaBlockMetadata_TLSF : public VmaBlockMetadata {-    VMA_CLASS_NO_COPY(VmaBlockMetadata_TLSF)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaBlockMetadata_TLSF) public:     VmaBlockMetadata_TLSF(const VkAllocationCallbacks* pAllocationCallbacks,         VkDeviceSize bufferImageGranularity, bool isVirtual);@@ -10070,7 +10119,7 @@     else         m_ListsCount += 4; -    m_MemoryClasses = memoryClass + 2;+    m_MemoryClasses = memoryClass + uint8_t(2);     memset(m_InnerIsFreeBitmap, 0, MAX_MEMORY_CLASSES * sizeof(uint32_t));      m_FreeList = vma_new_array(GetAllocationCallbacks(), Block*, m_ListsCount);@@ -10263,7 +10312,7 @@      // Round up to the next block     VkDeviceSize sizeForNextList = allocSize;-    VkDeviceSize smallSizeStep = SMALL_BUFFER_SIZE / (IsVirtual() ? 1 << SECOND_LEVEL_INDEX : 4);+    VkDeviceSize smallSizeStep = VkDeviceSize(SMALL_BUFFER_SIZE / (IsVirtual() ? 1 << SECOND_LEVEL_INDEX : 4));     if (allocSize > SMALL_BUFFER_SIZE)     {         sizeForNextList += (1ULL << (VMA_BITSCAN_MSB(allocSize) - SECOND_LEVEL_INDEX));@@ -10273,8 +10322,8 @@     else         sizeForNextList += smallSizeStep; -    uint32_t nextListIndex = 0;-    uint32_t prevListIndex = 0;+    uint32_t nextListIndex = m_ListsCount;+    uint32_t prevListIndex = m_ListsCount;     Block* nextListBlock = VMA_NULL;     Block* prevListBlock = VMA_NULL; @@ -10672,7 +10721,7 @@ uint8_t VmaBlockMetadata_TLSF::SizeToMemoryClass(VkDeviceSize size) const {     if (size > SMALL_BUFFER_SIZE)-        return VMA_BITSCAN_MSB(size) - MEMORY_CLASS_SHIFT;+        return uint8_t(VMA_BITSCAN_MSB(size) - MEMORY_CLASS_SHIFT);     return 0; } @@ -10847,7 +10896,7 @@ class VmaBlockVector {     friend struct VmaDefragmentationContext_T;-    VMA_CLASS_NO_COPY(VmaBlockVector)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaBlockVector) public:     VmaBlockVector(         VmaAllocator hAllocator,@@ -10966,7 +11015,7 @@ #ifndef _VMA_DEFRAGMENTATION_CONTEXT struct VmaDefragmentationContext_T {-    VMA_CLASS_NO_COPY(VmaDefragmentationContext_T)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaDefragmentationContext_T) public:     VmaDefragmentationContext_T(         VmaAllocator hAllocator,@@ -11016,6 +11065,8 @@      const VkDeviceSize m_MaxPassBytes;     const uint32_t m_MaxPassAllocations;+    const PFN_vmaCheckDefragmentationBreakFunction m_BreakCallback;+    void* m_BreakCallbackUserData;      VmaStlAllocator<VmaDefragmentationMove> m_MoveAllocator;     VmaVector<VmaDefragmentationMove, VmaStlAllocator<VmaDefragmentationMove>> m_Moves;@@ -11053,7 +11104,7 @@ struct VmaPool_T {     friend struct VmaPoolListItemTraits;-    VMA_CLASS_NO_COPY(VmaPool_T)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaPool_T) public:     VmaBlockVector m_BlockVector;     VmaDedicatedAllocationList m_DedicatedAllocations;@@ -11095,6 +11146,9 @@ #ifndef _VMA_CURRENT_BUDGET_DATA struct VmaCurrentBudgetData {+    VMA_CLASS_NO_COPY_NO_MOVE(VmaCurrentBudgetData)+public:+     VMA_ATOMIC_UINT32 m_BlockCount[VK_MAX_MEMORY_HEAPS];     VMA_ATOMIC_UINT32 m_AllocationCount[VK_MAX_MEMORY_HEAPS];     VMA_ATOMIC_UINT64 m_BlockBytes[VK_MAX_MEMORY_HEAPS];@@ -11163,7 +11217,7 @@ */ class VmaAllocationObjectAllocator {-    VMA_CLASS_NO_COPY(VmaAllocationObjectAllocator)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaAllocationObjectAllocator) public:     VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks)         : m_Allocator(pAllocationCallbacks, 1024) {}@@ -11193,7 +11247,7 @@ #ifndef _VMA_VIRTUAL_BLOCK_T struct VmaVirtualBlock_T {-    VMA_CLASS_NO_COPY(VmaVirtualBlock_T)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaVirtualBlock_T) public:     const bool m_AllocationCallbacksSpecified;     const VkAllocationCallbacks m_AllocationCallbacks;@@ -11333,7 +11387,7 @@ // Main allocator object. struct VmaAllocator_T {-    VMA_CLASS_NO_COPY(VmaAllocator_T)+    VMA_CLASS_NO_COPY_NO_MOVE(VmaAllocator_T) public:     bool m_UseMutex;     uint32_t m_VulkanApiVersion;@@ -12943,6 +12997,8 @@     const VmaDefragmentationInfo& info)     : m_MaxPassBytes(info.maxBytesPerPass == 0 ? VK_WHOLE_SIZE : info.maxBytesPerPass),     m_MaxPassAllocations(info.maxAllocationsPerPass == 0 ? UINT32_MAX : info.maxAllocationsPerPass),+    m_BreakCallback(info.pfnBreakCallback),+    m_BreakCallbackUserData(info.pBreakCallbackUserData),     m_MoveAllocator(hAllocator->GetAllocationCallbacks()),     m_Moves(m_MoveAllocator) {@@ -13197,29 +13253,24 @@             m_PassStats.bytesFreed += freedBlockSize;         } -        switch (m_Algorithm)-        {-        case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:+        if(m_Algorithm == VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT &&+            m_AlgorithmState != VMA_NULL)         {-            if (m_AlgorithmState != VMA_NULL)+            // Avoid unnecessary tries to allocate when new free block is available+            StateExtensive& state = reinterpret_cast<StateExtensive*>(m_AlgorithmState)[vectorIndex];+            if (state.firstFreeBlock != SIZE_MAX)             {-                // Avoid unnecessary tries to allocate when new free block is available-                StateExtensive& state = reinterpret_cast<StateExtensive*>(m_AlgorithmState)[vectorIndex];-                if (state.firstFreeBlock != SIZE_MAX)+                const size_t diff = prevCount - currentCount;+                if (state.firstFreeBlock >= diff)                 {-                    const size_t diff = prevCount - currentCount;-                    if (state.firstFreeBlock >= diff)-                    {-                        state.firstFreeBlock -= diff;-                        if (state.firstFreeBlock != 0)-                            state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty();-                    }-                    else-                        state.firstFreeBlock = 0;+                    state.firstFreeBlock -= diff;+                    if (state.firstFreeBlock != 0)+                        state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty();                 }+                else+                    state.firstFreeBlock = 0;             }         }-        }     }     moveInfo.moveCount = 0;     moveInfo.pMoves = VMA_NULL;@@ -13343,6 +13394,10 @@  VmaDefragmentationContext_T::CounterStatus VmaDefragmentationContext_T::CheckCounters(VkDeviceSize bytes) {+    // Check custom criteria if exists+    if (m_BreakCallback && m_BreakCallback(m_BreakCallbackUserData))+        return CounterStatus::End;+     // Ignore allocation if will exceed max size for copy     if (m_PassStats.bytesMoved + bytes > m_MaxPassBytes)     {@@ -13351,6 +13406,8 @@         else             return CounterStatus::End;     }+    else+        m_IgnoredAllocs = 0;     return CounterStatus::Pass; } @@ -13360,8 +13417,8 @@     // Early return when max found     if (++m_PassStats.allocationsMoved >= m_MaxPassAllocations || m_PassStats.bytesMoved >= m_MaxPassBytes)     {-        VMA_ASSERT(m_PassStats.allocationsMoved == m_MaxPassAllocations ||-            m_PassStats.bytesMoved == m_MaxPassBytes && "Exceeded maximal pass threshold!");+        VMA_ASSERT((m_PassStats.allocationsMoved == m_MaxPassAllocations ||+            m_PassStats.bytesMoved == m_MaxPassBytes) && "Exceeded maximal pass threshold!");         return true;     }     return false;@@ -13710,7 +13767,7 @@             {                 // Full clear performed already                 if (prevMoveCount != m_Moves.size() && freeMetadata->GetNextAllocation(handle) == VK_NULL_HANDLE)-                    reinterpret_cast<size_t*>(m_AlgorithmState)[index] = last;+                    vectorState.firstFreeBlock = last;                 return true;             }         }@@ -13780,6 +13837,7 @@         }         else             break;+        VMA_FALLTHROUGH; // Fallthrough     }     case StateExtensive::Operation::MoveBuffers:     {@@ -13804,6 +13862,7 @@         }         else             break;+        VMA_FALLTHROUGH; // Fallthrough     }     case StateExtensive::Operation::MoveAll:     {@@ -14201,6 +14260,12 @@         m_VulkanFunctions.vkGetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2)vkGetImageMemoryRequirements2;         m_VulkanFunctions.vkBindBufferMemory2KHR = (PFN_vkBindBufferMemory2)vkBindBufferMemory2;         m_VulkanFunctions.vkBindImageMemory2KHR = (PFN_vkBindImageMemory2)vkBindImageMemory2;+    }+#endif++#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000+    if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))+    {         m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2)vkGetPhysicalDeviceMemoryProperties2;     } #endif@@ -14253,7 +14318,7 @@     VMA_COPY_IF_NOT_NULL(vkBindImageMemory2KHR); #endif -#if VMA_MEMORY_BUDGET+#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000     VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties2KHR); #endif @@ -14308,8 +14373,18 @@         VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements2KHR, PFN_vkGetImageMemoryRequirements2, "vkGetImageMemoryRequirements2");         VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory2KHR, PFN_vkBindBufferMemory2, "vkBindBufferMemory2");         VMA_FETCH_DEVICE_FUNC(vkBindImageMemory2KHR, PFN_vkBindImageMemory2, "vkBindImageMemory2");+    }+#endif++#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000+    if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))+    {         VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2");     }+    else if(m_UseExtMemoryBudget)+    {+        VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2KHR");+    } #endif  #if VMA_DEDICATED_ALLOCATION@@ -14328,9 +14403,13 @@     } #endif // #if VMA_BIND_MEMORY2 -#if VMA_MEMORY_BUDGET-    if(m_UseExtMemoryBudget)+#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000+    if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))     {+        VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2");+    }+    else if(m_UseExtMemoryBudget)+    {         VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR");     } #endif // #if VMA_MEMORY_BUDGET@@ -15374,7 +15453,7 @@  VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory) {-    AtomicTransactionalIncrement<uint32_t> deviceMemoryCountIncrement;+    AtomicTransactionalIncrement<VMA_ATOMIC_UINT32> deviceMemoryCountIncrement;     const uint64_t prevDeviceMemoryCount = deviceMemoryCountIncrement.Increment(&m_DeviceMemoryCount); #if VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT     if(prevDeviceMemoryCount >= m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount)@@ -15531,6 +15610,7 @@             }             return res;         }+        VMA_FALLTHROUGH; // Fallthrough     case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:         return hAllocation->DedicatedAllocMap(this, ppData);     default:@@ -18165,6 +18245,12 @@ vkDestroyImage(allocator, img1, nullptr); \endcode +VMA also provides convenience functions that create a buffer or image and bind it to memory+represented by an existing #VmaAllocation:+vmaCreateAliasingBuffer(), vmaCreateAliasingBuffer2(),+vmaCreateAliasingImage(), vmaCreateAliasingImage2().+Versions with "2" offer additional parameter `allocationLocalOffset`.+ Remember that using resources that alias in memory requires proper synchronization. You need to issue a memory barrier to make sure commands that use `img1` and `img2` don't overlap on GPU timeline.@@ -19162,6 +19248,7 @@      // [Executed in runtime]:     memcpy(stagingAllocInfo.pMappedData, myData, myDataSize);+    vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);     //vkCmdPipelineBarrier: VK_ACCESS_HOST_WRITE_BIT --> VK_ACCESS_TRANSFER_READ_BIT     VkBufferCopy bufCopy = {         0, // srcOffset
changelog.md view
@@ -2,6 +2,9 @@  ## WIP +## [0.11] - 2023-10-17+- Bump VMA+ ## [0.10.5.1] - 2023-10-17 - Raise upper bound on `vulkan` 
package.yaml view
@@ -1,5 +1,5 @@ name: VulkanMemoryAllocator-version: "0.10.5.1"+version: "0.11" synopsis: Bindings to the VulkanMemoryAllocator library category: Graphics maintainer: Ellie Hermaszewska <live.long.and.prosper@monoid.al>
src/VulkanMemoryAllocator.hs view
@@ -175,6 +175,8 @@                               , AllocationCreateInfo(..)                               , PoolCreateInfo(..)                               , AllocationInfo(..)+                              , PFN_vmaCheckDefragmentationBreakFunction+                              , FN_vmaCheckDefragmentationBreakFunction                               , DefragmentationInfo(..)                               , DefragmentationMove(..)                               , DefragmentationPassMoveInfo(..)@@ -5545,6 +5547,11 @@            Nothing  +type FN_vmaCheckDefragmentationBreakFunction = ("pUserData" ::: Ptr ()) -> IO Bool32+-- No documentation found for TopLevel "PFN_vmaCheckDefragmentationBreakFunction"+type PFN_vmaCheckDefragmentationBreakFunction = FunPtr FN_vmaCheckDefragmentationBreakFunction++ -- | VmaDefragmentationInfo -- -- Parameters for defragmentation.@@ -5567,22 +5574,31 @@     --     -- @0@ means no limit.     maxAllocationsPerPass :: Word32+  , -- | Optional custom callback for stopping 'beginDefragmentation'.+    --+    -- Have to return true for breaking current defragmentation pass.+    pfnBreakCallback :: PFN_vmaCheckDefragmentationBreakFunction+  , -- | Optional data to pass to custom callback for stopping pass of+    -- defragmentation.+    breakCallbackUserData :: Ptr ()   }-  deriving (Typeable, Eq)+  deriving (Typeable) #if defined(GENERIC_INSTANCES) deriving instance Generic (DefragmentationInfo) #endif deriving instance Show DefragmentationInfo  instance ToCStruct DefragmentationInfo where-  withCStruct x f = allocaBytes 32 $ \p -> pokeCStruct p x (f p)+  withCStruct x f = allocaBytes 48 $ \p -> pokeCStruct p x (f p)   pokeCStruct p DefragmentationInfo{..} f = do     poke ((p `plusPtr` 0 :: Ptr DefragmentationFlags)) (flags)     poke ((p `plusPtr` 8 :: Ptr Pool)) (pool)     poke ((p `plusPtr` 16 :: Ptr DeviceSize)) (maxBytesPerPass)     poke ((p `plusPtr` 24 :: Ptr Word32)) (maxAllocationsPerPass)+    poke ((p `plusPtr` 32 :: Ptr PFN_vmaCheckDefragmentationBreakFunction)) (pfnBreakCallback)+    poke ((p `plusPtr` 40 :: Ptr (Ptr ()))) (breakCallbackUserData)     f-  cStructSize = 32+  cStructSize = 48   cStructAlignment = 8   pokeZeroCStruct p f = do     poke ((p `plusPtr` 0 :: Ptr DefragmentationFlags)) (zero)@@ -5596,17 +5612,26 @@     pool <- peek @Pool ((p `plusPtr` 8 :: Ptr Pool))     maxBytesPerPass <- peek @DeviceSize ((p `plusPtr` 16 :: Ptr DeviceSize))     maxAllocationsPerPass <- peek @Word32 ((p `plusPtr` 24 :: Ptr Word32))+    pfnBreakCallback <- peek @PFN_vmaCheckDefragmentationBreakFunction ((p `plusPtr` 32 :: Ptr PFN_vmaCheckDefragmentationBreakFunction))+    pBreakCallbackUserData <- peek @(Ptr ()) ((p `plusPtr` 40 :: Ptr (Ptr ())))     pure $ DefragmentationInfo-             flags pool maxBytesPerPass maxAllocationsPerPass+             flags+             pool+             maxBytesPerPass+             maxAllocationsPerPass+             pfnBreakCallback+             pBreakCallbackUserData  instance Storable DefragmentationInfo where-  sizeOf ~_ = 32+  sizeOf ~_ = 48   alignment ~_ = 8   peek = peekCStruct   poke ptr poked = pokeCStruct ptr poked (pure ())  instance Zero DefragmentationInfo where   zero = DefragmentationInfo+           zero+           zero            zero            zero            zero