Merge branch 'master' into feature-custom-alignment
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index 47f79db..ce73d6c 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -3987,6 +3987,17 @@
     VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation,

     VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);

 

+/** \brief TODO

+*/

+VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(

+    VmaAllocator VMA_NOT_NULL allocator,

+    const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,

+    const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,

+    VkDeviceSize minAlignment,

+    VkBuffer VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pBuffer,

+    VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation,

+    VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);

+

 /** \brief Destroys Vulkan buffer and frees allocated memory.

 

 This is just a convenience function equivalent to:

@@ -19494,6 +19505,108 @@
     return res;

 }

 

+VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(

+    VmaAllocator allocator,

+    const VkBufferCreateInfo* pBufferCreateInfo,

+    const VmaAllocationCreateInfo* pAllocationCreateInfo,

+    VkDeviceSize minAlignment,

+    VkBuffer* pBuffer,

+    VmaAllocation* pAllocation,

+    VmaAllocationInfo* pAllocationInfo)

+{

+    VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && VmaIsPow2(minAlignment) && pBuffer && pAllocation);

+

+    if(pBufferCreateInfo->size == 0)

+    {

+        return VK_ERROR_VALIDATION_FAILED_EXT;

+    }

+    if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&

+        !allocator->m_UseKhrBufferDeviceAddress)

+    {

+        VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");

+        return VK_ERROR_VALIDATION_FAILED_EXT;

+    }

+

+    VMA_DEBUG_LOG("vmaCreateBufferWithAlignment");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    *pBuffer = VK_NULL_HANDLE;

+    *pAllocation = VK_NULL_HANDLE;

+

+    // 1. Create VkBuffer.

+    VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)(

+        allocator->m_hDevice,

+        pBufferCreateInfo,

+        allocator->GetAllocationCallbacks(),

+        pBuffer);

+    if(res >= 0)

+    {

+        // 2. vkGetBufferMemoryRequirements.

+        VkMemoryRequirements vkMemReq = {};

+        bool requiresDedicatedAllocation = false;

+        bool prefersDedicatedAllocation  = false;

+        allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq,

+            requiresDedicatedAllocation, prefersDedicatedAllocation);

+

+        // 2a. Include minAlignment

+        vkMemReq.alignment = VMA_MAX(vkMemReq.alignment, minAlignment);

+

+        // 3. Allocate memory using allocator.

+        res = allocator->AllocateMemory(

+            vkMemReq,

+            requiresDedicatedAllocation,

+            prefersDedicatedAllocation,

+            *pBuffer, // dedicatedBuffer

+            pBufferCreateInfo->usage, // dedicatedBufferUsage

+            VK_NULL_HANDLE, // dedicatedImage

+            *pAllocationCreateInfo,

+            VMA_SUBALLOCATION_TYPE_BUFFER,

+            1, // allocationCount

+            pAllocation);

+

+#if VMA_RECORDING_ENABLED

+        if(allocator->GetRecorder() != VMA_NULL)

+        {

+            VMA_ASSERT(0 && "Not implemented.");

+        }

+#endif

+

+        if(res >= 0)

+        {

+            // 3. Bind buffer with memory.

+            if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)

+            {

+                res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL);

+            }

+            if(res >= 0)

+            {

+                // All steps succeeded.

+                #if VMA_STATS_STRING_ENABLED

+                    (*pAllocation)->InitBufferImageUsage(pBufferCreateInfo->usage);

+                #endif

+                if(pAllocationInfo != VMA_NULL)

+                {

+                    allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);

+                }

+

+                return VK_SUCCESS;

+            }

+            allocator->FreeMemory(

+                1, // allocationCount

+                pAllocation);

+            *pAllocation = VK_NULL_HANDLE;

+            (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());

+            *pBuffer = VK_NULL_HANDLE;

+            return res;

+        }

+        (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());

+        *pBuffer = VK_NULL_HANDLE;

+        return res;

+    }

+    return res;

+}

+

 VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer(

     VmaAllocator allocator,

     VkBuffer buffer,