Fixes after merge for VK_KHR_external_memory_win32 support
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index 808eefc..c9c1b86 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -6273,11 +6273,17 @@
     uint32_t m_MapCount;
     void* m_pMappedData;
 
-    VmaWin32Handle m_Handle; // Win32 handle
+    VmaWin32Handle m_Handle;
 };
 #endif // _VMA_DEVICE_MEMORY_BLOCK
 
 #ifndef _VMA_ALLOCATION_T
+struct VmaAllocationExtraData
+{
+    void* m_pMappedData = VMA_NULL; // Not null means memory is mapped.
+    VmaWin32Handle m_Handle;
+};
+
 struct VmaAllocation_T
 {
     friend struct VmaDedicatedAllocationListItemTraits;
@@ -6310,12 +6316,14 @@
         bool mapped);
     // pMappedData not null means allocation is created with MAPPED flag.
     void InitDedicatedAllocation(
+        VmaAllocator allocator,
         VmaPool hParentPool,
         uint32_t memoryTypeIndex,
         VkDeviceMemory hMemory,
         VmaSuballocationType suballocationType,
         void* pMappedData,
         VkDeviceSize size);
+    void Destroy(VmaAllocator allocator);
 
     ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; }
     VkDeviceSize GetAlignment() const { return m_Alignment; }
@@ -6375,10 +6383,9 @@
     {
         VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
         VkDeviceMemory m_hMemory;
-        void* m_pMappedData; // Not null means memory is mapped.
+        VmaAllocationExtraData* m_ExtraData;
         VmaAllocation_T* m_Prev;
         VmaAllocation_T* m_Next;
-        VmaWin32Handle m_Handle; // Win32 handle
     };
     union
     {
@@ -6401,6 +6408,8 @@
 #if VMA_STATS_STRING_ENABLED
     VmaBufferImageUsage m_BufferImageUsage; // 0 if unknown.
 #endif
+
+    void EnsureExtraData(VmaAllocator hAllocator);
 };
 #endif // _VMA_ALLOCATION_T
 
@@ -10867,6 +10876,7 @@
 }
 
 void VmaAllocation_T::InitDedicatedAllocation(
+    VmaAllocator allocator,
     VmaPool hParentPool,
     uint32_t memoryTypeIndex,
     VkDeviceMemory hMemory,
@@ -10881,16 +10891,29 @@
     m_Size = size;
     m_MemoryTypeIndex = memoryTypeIndex;
     m_SuballocationType = (uint8_t)suballocationType;
-    if(pMappedData != VMA_NULL)
+    m_DedicatedAllocation.m_ExtraData = VMA_NULL;
+    m_DedicatedAllocation.m_hParentPool = hParentPool;
+    m_DedicatedAllocation.m_hMemory = hMemory;
+    m_DedicatedAllocation.m_Prev = VMA_NULL;
+    m_DedicatedAllocation.m_Next = VMA_NULL;
+
+    if (pMappedData != VMA_NULL)
     {
         VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
         m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
+        EnsureExtraData(allocator);
+        m_DedicatedAllocation.m_ExtraData->m_pMappedData = pMappedData;
     }
-    m_DedicatedAllocation.m_hParentPool = hParentPool;
-    m_DedicatedAllocation.m_hMemory = hMemory;
-    m_DedicatedAllocation.m_pMappedData = pMappedData;
-    m_DedicatedAllocation.m_Prev = VMA_NULL;
-    m_DedicatedAllocation.m_Next = VMA_NULL;
+}
+
+void VmaAllocation_T::Destroy(VmaAllocator allocator)
+{
+    FreeName(allocator);
+
+    if (GetType() == ALLOCATION_TYPE_DEDICATED)
+    {
+        vma_delete(allocator, m_DedicatedAllocation.m_ExtraData);
+    }
 }
 
 void VmaAllocation_T::SetName(VmaAllocator hAllocator, const char* pName)
@@ -10995,8 +11018,9 @@
         }
         break;
     case ALLOCATION_TYPE_DEDICATED:
-        VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0 || IsPersistentMap()));
-        return m_DedicatedAllocation.m_pMappedData;
+        VMA_ASSERT((m_DedicatedAllocation.m_ExtraData != VMA_NULL && m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL) ==
+            (m_MapCount != 0 || IsPersistentMap()));
+        return m_DedicatedAllocation.m_ExtraData != VMA_NULL ? m_DedicatedAllocation.m_ExtraData->m_pMappedData : VMA_NULL;
     default:
         VMA_ASSERT(0);
         return VMA_NULL;
@@ -11037,12 +11061,14 @@
     VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);
     VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
 
+    EnsureExtraData(hAllocator);
+
     if (m_MapCount != 0 || IsPersistentMap())
     {
         if (m_MapCount < 0xFF)
         {
-            VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);
-            *ppData = m_DedicatedAllocation.m_pMappedData;
+            VMA_ASSERT(m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL);
+            *ppData = m_DedicatedAllocation.m_ExtraData->m_pMappedData;
             ++m_MapCount;
             return VK_SUCCESS;
         }
@@ -11063,7 +11089,7 @@
             ppData);
         if (result == VK_SUCCESS)
         {
-            m_DedicatedAllocation.m_pMappedData = *ppData;
+            m_DedicatedAllocation.m_ExtraData->m_pMappedData = *ppData;
             m_MapCount = 1;
         }
         return result;
@@ -11079,7 +11105,8 @@
         --m_MapCount;
         if (m_MapCount == 0 && !IsPersistentMap())
         {
-            m_DedicatedAllocation.m_pMappedData = VMA_NULL;
+            VMA_ASSERT(m_DedicatedAllocation.m_ExtraData != VMA_NULL);
+            m_DedicatedAllocation.m_ExtraData->m_pMappedData = VMA_NULL;
             (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(
                 hAllocator->m_hDevice,
                 m_DedicatedAllocation.m_hMemory);
@@ -11118,14 +11145,14 @@
 #if VMA_EXTERNAL_MEMORY_WIN32
 VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
 {
-    // Where do we get this function from?
     auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
     switch (m_Type)
     {
     case ALLOCATION_TYPE_BLOCK:
         return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
     case ALLOCATION_TYPE_DEDICATED:
-        return m_DedicatedAllocation.m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
+        EnsureExtraData(hAllocator);
+        return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
     default:
         VMA_ASSERT(0);
         return VK_ERROR_FEATURE_NOT_PRESENT;
@@ -11134,6 +11161,14 @@
 #endif // VMA_EXTERNAL_MEMORY_WIN32
 #endif // VMA_STATS_STRING_ENABLED
 
+void VmaAllocation_T::EnsureExtraData(VmaAllocator hAllocator)
+{
+    if (m_DedicatedAllocation.m_ExtraData == VMA_NULL)
+    {
+        m_DedicatedAllocation.m_ExtraData = vma_new(hAllocator, VmaAllocationExtraData)();
+    }
+}
+
 void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
 {
     if(m_pName)
@@ -11562,6 +11597,7 @@
     }
 
     m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
+    hAllocation->Destroy(m_hAllocator);
     m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
 }
 
@@ -13705,7 +13741,7 @@
     }
 
     *pAllocation = m_AllocationObjectAllocator.Allocate(isMappingAllowed);
-    (*pAllocation)->InitDedicatedAllocation(pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
+    (*pAllocation)->InitDedicatedAllocation(this, pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
     if (isUserDataString)
         (*pAllocation)->SetName(this, (const char*)pUserData);
     else
@@ -14041,8 +14077,6 @@
                 FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
             }
 
-            allocation->FreeName(this);
-
             switch(allocation->GetType())
             {
             case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
@@ -14726,6 +14760,7 @@
     FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
 
     m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize());
+    allocation->Destroy(this);
     m_AllocationObjectAllocator.Free(allocation);
 
     VMA_DEBUG_LOG_FORMAT("    Freed DedicatedMemory MemoryTypeIndex=%" PRIu32, memTypeIndex);
@@ -16615,7 +16650,7 @@
 VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32HandleKHR(VmaAllocator VMA_NOT_NULL allocator,
     VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
 {
-    VMA_ASSERT(allocator && allocation);
+    VMA_ASSERT(allocator && allocation && pHandle);
     VMA_DEBUG_GLOBAL_MUTEX_LOCK;
     return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
 }
@@ -16753,6 +16788,7 @@
 VK_KHR_buffer_device_address  | #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
 VK_EXT_memory_priority        | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
 VK_AMD_device_coherent_memory | #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
+VK_KHR_external_memory_win32  | #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
 
 Example with fetching pointers to Vulkan functions dynamically:
 
diff --git a/src/Shaders/CMakeLists.txt b/src/Shaders/CMakeLists.txt
index 0998924..56511f9 100644
--- a/src/Shaders/CMakeLists.txt
+++ b/src/Shaders/CMakeLists.txt
@@ -34,7 +34,7 @@
         DEPENDS ${SHADER}
     )
 
-    list(APPEND SPIRV_FILES ${SPIRV})
+    list(APPEND SPIRV_FILES ${SPIRV} ${SPIRV_BIN})
 endforeach()
 
 add_custom_target(VmaSampleShaders ALL DEPENDS ${SPIRV_FILES})
diff --git a/src/Tests.cpp b/src/Tests.cpp
index 853b56a..e82a37e 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -8258,61 +8258,59 @@
 {
 #if VMA_EXTERNAL_MEMORY_WIN32
     wprintf(L"Test Win32 handles\n");
-    constexpr static VkExportMemoryAllocateInfoKHR exportInfo{
+    constexpr static VkExportMemoryAllocateInfoKHR exportMemAllocInfo{
         VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
         nullptr,
         VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
     };
-    constexpr static VkExternalMemoryBufferCreateInfoKHR externalInfo{
+    constexpr static VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo{
         VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
         nullptr,
         VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
     };
 
-    VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-    sampleBufCreateInfo.size = 0x1000; // Doesn't matter.
-    sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
-    sampleBufCreateInfo.pNext = &externalInfo;
+    VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
+    bufCreateInfo.size = 0x10000;
+    bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+    bufCreateInfo.pNext = &externalMemBufCreateInfo;
 
-    VmaAllocationCreateInfo sampleAllocCreateInfo = {};
-    sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
-    sampleAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
+    VmaAllocationCreateInfo allocCreateInfo = {};
+    allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
 
-    uint32_t memTypeIndex;
+    uint32_t memTypeIndex = UINT32_MAX;
     TEST(vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator,
-        &sampleBufCreateInfo, &sampleAllocCreateInfo, &memTypeIndex) == VK_SUCCESS);
-    // Check res...
-
+        &bufCreateInfo, &allocCreateInfo, &memTypeIndex) == VK_SUCCESS);
 
     // Create a pool that can have at most 2 blocks, 128 MiB each.
     VmaPoolCreateInfo poolCreateInfo = {};
     poolCreateInfo.memoryTypeIndex = memTypeIndex;
-    poolCreateInfo.blockSize = 128ull * 1024 * 1024;
-    poolCreateInfo.maxBlockCount = 2;
-    poolCreateInfo.pMemoryAllocateNext = (void*)&exportInfo;
+    poolCreateInfo.pMemoryAllocateNext = (void*)&exportMemAllocInfo;
 
-
-    VmaPool pool;
+    VmaPool pool = VK_NULL_HANDLE;
     TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS);
 
+    allocCreateInfo.pool = pool;
 
-    sampleAllocCreateInfo.pool = pool;
+    for (size_t test = 0; test < 2; ++test)
+    {
+        if (test == 1)
+            allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
 
-    VkBuffer buf;
-    VmaAllocation alloc;
-    VmaAllocationInfo allocInfo;
-    TEST(vmaCreateBuffer(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &buf, &alloc, &allocInfo) == VK_SUCCESS);
-    HANDLE handle;
-    HANDLE handle2;
-    TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle) == VK_SUCCESS);
-    TEST(handle != nullptr);
-    TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle2) == VK_SUCCESS);
-    TEST(handle2 != nullptr);
-    TEST(handle2 != handle);
+        VkBuffer buf = VK_NULL_HANDLE;
+        VmaAllocation alloc = VK_NULL_HANDLE;
+        TEST(vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr) == VK_SUCCESS);
+        HANDLE handle = NULL;
+        HANDLE handle2 = NULL;
+        TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle) == VK_SUCCESS);
+        TEST(handle != nullptr);
+        TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle2) == VK_SUCCESS);
+        TEST(handle2 != nullptr);
+        TEST(handle2 != handle);
 
-    vmaDestroyBuffer(g_hAllocator, buf, alloc);
-    TEST(CloseHandle(handle));
-    TEST(CloseHandle(handle2));
+        vmaDestroyBuffer(g_hAllocator, buf, alloc);
+        TEST(CloseHandle(handle));
+        TEST(CloseHandle(handle2));
+    }
 
     vmaDestroyPool(g_hAllocator, pool);
 #endif
diff --git a/src/VmaUsage.h b/src/VmaUsage.h
index 4676fcd..ae258a8 100644
--- a/src/VmaUsage.h
+++ b/src/VmaUsage.h
@@ -96,6 +96,9 @@
     #pragma clang diagnostic ignored "-Wnullability-completeness"
 #endif
 
+#include <vulkan/vulkan.h>
+#include <vulkan/vulkan_win32.h>
+
 #include "vk_mem_alloc.h"
 
 #ifdef __clang__