From 82731feeb91b845abe58b1c9a0f1d84215e65ffd Mon Sep 17 00:00:00 2001
From: Adam Sawicki <adam.sawicki@amd.com>
Date: Mon, 21 Jun 2021 14:47:37 +0200
Subject: [PATCH] Fixes. Left only new member
 VmaPoolCreateInfo::pMemoryAllocateNext.

---
 include/vk_mem_alloc.h | 57 ++++++++++++------------------------------
 src/VulkanSample.cpp   | 13 ----------
 2 files changed, 16 insertions(+), 54 deletions(-)

diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index 5886059..e25e2a5 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -2494,17 +2494,6 @@ typedef struct VmaAllocatorCreateInfo
     Leaving it initialized to zero is equivalent to `VK_API_VERSION_1_0`.
     */
     uint32_t vulkanApiVersion;
-
-    /** \brief Either null or a pointer to an array of external memory handle types for each Vulkan memory type.
-
-    If not NULL, it must be a pointer to an array of `VkPhysicalDeviceMemoryProperties::memoryTypeCount`
-    elements, defining external memory handle types of particular Vulkan memory type,
-    to be passed using `VkExportMemoryAllocateInfoKHR`.
-
-    Any of the elements may be equal to 0, which means not to use `VkExportMemoryAllocateInfoKHR` on this memory type.\
-    This is also the default in case of `pTypeExternalMemoryHandleTypes` = NULL.
-    */
-    const VkExternalMemoryHandleTypeFlagsKHR* VMA_NULLABLE VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryTypeCount") pTypeExternalMemoryHandleTypes;
 } VmaAllocatorCreateInfo;
 
 /// Creates Allocator object.
@@ -3111,9 +3100,16 @@ typedef struct VmaPoolCreateInfo {
     e.g. when doing interop with OpenGL.
     */
     VkDeviceSize minAllocationAlignment;
-    /** TODO
+    /** \brief Additional `pNext` chain to be attached to `VkMemoryAllocateInfo` used for every allocation made by this pool. Optional.
+    
+    Optional, can be null. If not null, it must point to a `pNext` chain of structures that can be attached to `VkMemoryAllocateInfo`.
+    It can be useful for special needs such as adding `VkExportMemoryAllocateInfoKHR`.
+    Structures pointed by this member must remain alive and unchanged for the whole lifetime of the custom pool.
+
+    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* pMemoryAllocateNext;
+    void* VMA_NULLABLE pMemoryAllocateNext;
 } VmaPoolCreateInfo;
 
 /** \brief Describes parameter of existing #VmaPool.
@@ -8391,10 +8387,6 @@ public:
     */
     uint32_t GetGpuDefragmentationMemoryTypeBits();
 
-    VkExternalMemoryHandleTypeFlagsKHR GetExternalMemoryHandleTypeFlags(uint32_t memTypeIndex) const
-    {
-        return m_TypeExternalMemoryHandleTypes[memTypeIndex];
-    }
 
 private:
     VkDeviceSize m_PreferredLargeHeapBlockSize;
@@ -8402,7 +8394,6 @@ private:
     VkPhysicalDevice m_PhysicalDevice;
     VMA_ATOMIC_UINT32 m_CurrentFrameIndex;
     VMA_ATOMIC_UINT32 m_GpuDefragmentationMemoryTypeBits; // UINT32_MAX means uninitialized.
-    VkExternalMemoryHandleTypeFlagsKHR m_TypeExternalMemoryHandleTypes[VK_MAX_MEMORY_TYPES];
 
     VMA_RW_MUTEX m_PoolsMutex;
     typedef VmaIntrusiveLinkedList<VmaPoolListItemTraits> PoolList;
@@ -12908,7 +12899,7 @@ VmaPool_T::VmaPool_T(
         createInfo.blockSize != 0, // explicitBlockSize
         createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK, // algorithm
         createInfo.priority,
-        VMA_MAX(hAllocator->GetMemoryTypeMinAlignment(createInfo.memoryTypeIndex), createInfo.minAllocationAlignment)),
+        VMA_MAX(hAllocator->GetMemoryTypeMinAlignment(createInfo.memoryTypeIndex), createInfo.minAllocationAlignment),
         createInfo.pMemoryAllocateNext),
     m_Id(0),
     m_Name(VMA_NULL)
@@ -13678,14 +13669,6 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn
     }
 #endif // #if VMA_MEMORY_PRIORITY
 
-    // Attach VkExportMemoryAllocateInfoKHR if necessary.
-    VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR };
-    exportMemoryAllocInfo.handleTypes = m_hAllocator->GetExternalMemoryHandleTypeFlags(m_MemoryTypeIndex);
-    if(exportMemoryAllocInfo.handleTypes != 0)
-    {
-        VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo);
-    }
-
     VkDeviceMemory mem = VK_NULL_HANDLE;
     VkResult res = m_hAllocator->AllocateVulkanMemory(&allocInfo, &mem);
     if(res < 0)
@@ -16130,7 +16113,6 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
     memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors));
     memset(&m_VulkanFunctions, 0, sizeof(m_VulkanFunctions));
 
-    memset(&m_TypeExternalMemoryHandleTypes, 0, sizeof(m_TypeExternalMemoryHandleTypes));
 
     if(pCreateInfo->pDeviceMemoryCallbacks != VMA_NULL)
     {
@@ -16154,11 +16136,6 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
 
     m_GlobalMemoryTypeBits = CalculateGlobalMemoryTypeBits();
 
-    if(pCreateInfo->pTypeExternalMemoryHandleTypes != VMA_NULL)
-    {
-        memcpy(m_TypeExternalMemoryHandleTypes, pCreateInfo->pTypeExternalMemoryHandleTypes,
-            sizeof(VkExternalMemoryHandleTypeFlagsKHR) * GetMemoryTypeCount());
-    }
 
     if(pCreateInfo->pHeapSizeLimit != VMA_NULL)
     {
@@ -16692,14 +16669,6 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
     }
 #endif // #if VMA_MEMORY_PRIORITY
 
-    // Attach VkExportMemoryAllocateInfoKHR if necessary.
-    VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR };
-    exportMemoryAllocInfo.handleTypes = GetExternalMemoryHandleTypeFlags(memTypeIndex);
-    if(exportMemoryAllocInfo.handleTypes != 0)
-    {
-        VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo);
-    }
-
     size_t allocIndex;
     VkResult res = VK_SUCCESS;
     for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
@@ -17355,6 +17324,12 @@ VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPoo
 
     VmaPoolCreateInfo newCreateInfo = *pCreateInfo;
 
+    // Protection against uninitialized new structure member. If garbage data are left there, this pointer dereference would crash.
+    if(pCreateInfo->pMemoryAllocateNext)
+    {
+        VMA_ASSERT(((const VkBaseInStructure*)pCreateInfo->pMemoryAllocateNext)->sType != 0);
+    }
+
     if(newCreateInfo.maxBlockCount == 0)
     {
         newCreateInfo.maxBlockCount = SIZE_MAX;
diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp
index 01dcc80..0d07cfb 100644
--- a/src/VulkanSample.cpp
+++ b/src/VulkanSample.cpp
@@ -1440,19 +1440,6 @@ void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo)
     heapSizeLimit[0] = 512ull * 1024 * 1024;
     outInfo.pHeapSizeLimit = heapSizeLimit.data();
     */
-
-    // External memory test
-    VkPhysicalDeviceMemoryProperties memProps = {};
-    vkGetPhysicalDeviceMemoryProperties(g_hPhysicalDevice, &memProps);
-    static VkExternalMemoryHandleTypeFlagsKHR externalMemoryHandleTypes[VK_MAX_MEMORY_TYPES] = {};
-    for(uint32_t i = 0; i < memProps.memoryTypeCount; ++i)
-    {
-        if(memProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
-        {
-            externalMemoryHandleTypes[i] = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
-        }
-    }
-    outInfo.pTypeExternalMemoryHandleTypes = externalMemoryHandleTypes;
 }
 
 static void PrintPhysicalDeviceProperties(const VkPhysicalDeviceProperties& properties)