Added vmaGetMemoryWin32Handle2 with selectable type of handle to export
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index 4ba3fe4..e5e26f8 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -2167,8 +2167,18 @@
 
 For more information, see chapter \ref vk_khr_external_memory_win32.
 */
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT_NULL allocator,
-    VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle);
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(
+    VmaAllocator VMA_NOT_NULL allocator,
+    VmaAllocation VMA_NOT_NULL allocation, 
+    HANDLE hTargetProcess, 
+    HANDLE* VMA_NOT_NULL pHandle);
+
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle2(
+    VmaAllocator VMA_NOT_NULL allocator,
+    VmaAllocation VMA_NOT_NULL allocation, 
+    VkExternalMemoryHandleTypeFlagBits handleType, 
+    HANDLE hTargetProcess, 
+    HANDLE* VMA_NOT_NULL pHandle);
 #endif // VMA_EXTERNAL_MEMORY_WIN32
 
 /** \brief Maps memory represented by given allocation and returns pointer to it.
@@ -6204,40 +6214,45 @@
 {
 public:
     VmaWin32Handle() noexcept : m_hHandle(VMA_NULL) { }
-    explicit VmaWin32Handle(HANDLE hHandle) noexcept : m_hHandle(hHandle) { }
-    ~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL) { ::CloseHandle(m_hHandle); } }
+    explicit VmaWin32Handle(HANDLE hHandle) noexcept 
+        : m_hHandle(hHandle)
+        , m_IsNTHandle(IsNTHandle(hHandle))
+    {
+    }
+    ~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL && m_IsNTHandle) { ::CloseHandle(m_hHandle); } }
     VMA_CLASS_NO_COPY_NO_MOVE(VmaWin32Handle)
 
 public:
     // Strengthened
-    VkResult GetHandle(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
+    VkResult GetHandle(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
     {
         *pHandle = VMA_NULL;
         // Try to get handle first.
-        if (m_hHandle != VMA_NULL)
-        {
-            *pHandle = Duplicate(hTargetProcess);
-            return VK_SUCCESS;
-        }
-
         VkResult res = VK_SUCCESS;
-        // If failed, try to create it.
+        if (m_hHandle == VMA_NULL)
         {
             VmaMutexLockWrite lock(m_Mutex, useMutex);
             if (m_hHandle == VMA_NULL)
             {
-                res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &m_hHandle);
+                res = Create(device, memory, pvkGetMemoryWin32HandleKHR, handleType, &m_hHandle);
+                if (res != VK_SUCCESS) {
+                    m_hHandle = VMA_NULL;
+                    return res;
+                }
+                m_IsNTHandle = IsNTHandle(m_hHandle);
             }
         }
-
-        *pHandle = Duplicate(hTargetProcess);
+        if (res == VK_SUCCESS) {
+            // KMT handle is returned as is.
+            *pHandle = m_IsNTHandle ? Duplicate(hTargetProcess) : m_hHandle;
+        }
         return res;
     }
 
     operator bool() const noexcept { return m_hHandle != VMA_NULL; }
 private:
     // Not atomic
-    static VkResult Create(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE* pHandle) noexcept
+    static VkResult Create(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE* pHandle) noexcept
     {
         VkResult res = VK_ERROR_FEATURE_NOT_PRESENT;
         if (pvkGetMemoryWin32HandleKHR != VMA_NULL)
@@ -6245,7 +6260,7 @@
             VkMemoryGetWin32HandleInfoKHR handleInfo{ };
             handleInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
             handleInfo.memory = memory;
-            handleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+            handleInfo.handleType = handleType;
             res = pvkGetMemoryWin32HandleKHR(device, &handleInfo, pHandle);
         }
         return res;
@@ -6263,9 +6278,15 @@
         }
         return hDupHandle;
     }
+    static bool IsNTHandle(HANDLE hHandle) noexcept
+    {
+        DWORD flags = 0;
+        return (hHandle != VMA_NULL) ? (::GetHandleInformation(hHandle, &flags) != 0) : false;
+    }
 private:
     HANDLE m_hHandle;
     VMA_RW_MUTEX m_Mutex; // Protects access m_Handle
+    bool m_IsNTHandle = false; // True if m_Handle is NT handle, false if it's a KMT handle.
 };
 #else 
 class VmaWin32Handle
@@ -6273,6 +6294,7 @@
     // ABI compatibility
     void* placeholder = VMA_NULL;
     VMA_RW_MUTEX placeholder2;
+    bool placeholder3 = false;
 };
 #endif // VMA_EXTERNAL_MEMORY_WIN32
 
@@ -6347,6 +6369,7 @@
     VkResult CreateWin32Handle(
         const VmaAllocator hAllocator,
         PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR,
+        VkExternalMemoryHandleTypeFlagBits handleType,
         HANDLE hTargetProcess,
         HANDLE* pHandle)noexcept;
 #endif // VMA_EXTERNAL_MEMORY_WIN32
@@ -6461,7 +6484,7 @@
 #endif
 
 #if VMA_EXTERNAL_MEMORY_WIN32
-    VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
+    VkResult GetWin32Handle(VmaAllocator hAllocator, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
 #endif // VMA_EXTERNAL_MEMORY_WIN32
 
 private:
@@ -10905,10 +10928,10 @@
 }
 
 #if VMA_EXTERNAL_MEMORY_WIN32
-VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
+VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
 {
     VMA_ASSERT(pHandle);
-    return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
+    return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, handleType, hTargetProcess, hAllocator->m_UseMutex, pHandle);
 }
 #endif // VMA_EXTERNAL_MEMORY_WIN32
 #endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
@@ -11226,16 +11249,16 @@
     }
 }
 #if VMA_EXTERNAL_MEMORY_WIN32
-VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
+VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
 {
     auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
     switch (m_Type)
     {
     case ALLOCATION_TYPE_BLOCK:
-        return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
+        return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, handleType, hTargetProcess, pHandle);
     case ALLOCATION_TYPE_DEDICATED:
         EnsureExtraData(hAllocator);
-        return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
+        return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, handleType, hTargetProcess, hAllocator->m_UseMutex, pHandle);
     default:
         VMA_ASSERT(0);
         return VK_ERROR_FEATURE_NOT_PRESENT;
@@ -16842,7 +16865,20 @@
 {
     VMA_ASSERT(allocator && allocation && pHandle);
     VMA_DEBUG_GLOBAL_MUTEX_LOCK;
-    return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
+    return allocation->GetWin32Handle(allocator, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, hTargetProcess, pHandle);
+}
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle2(VmaAllocator VMA_NOT_NULL allocator,
+    VmaAllocation VMA_NOT_NULL allocation, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
+{
+    VMA_ASSERT(allocator && allocation && pHandle);
+    VMA_ASSERT(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR ||
+        handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR ||
+        handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR ||
+        handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR ||
+        handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR ||
+        handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR);
+    VMA_DEBUG_GLOBAL_MUTEX_LOCK;
+    return allocation->GetWin32Handle(allocator, handleType, hTargetProcess, pHandle);
 }
 #endif // VMA_EXTERNAL_MEMORY_WIN32 
 #endif // VMA_STATS_STRING_ENABLED
diff --git a/src/Tests.cpp b/src/Tests.cpp
index 9c9c7bb..800dfe2 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -380,7 +380,7 @@
 
     time_point timeBeg = std::chrono::high_resolution_clock::now();
 
-    std::atomic<size_t> allocationCount = 0;
+    std::atomic<size_t> allocationCount{ 0 };
     VkResult res = VK_SUCCESS;
 
     uint32_t memUsageProbabilitySum =
@@ -545,7 +545,7 @@
         }
     };
 
-    std::atomic<uint32_t> numThreadsReachedMaxAllocations = 0;
+    std::atomic<uint32_t> numThreadsReachedMaxAllocations{ 0 };
     HANDLE threadsFinishEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
     auto ThreadProc = [&](uint32_t randSeed) -> void