@@ -6069,6 +6069,54 @@ class VmaMappingHysteresis
60696069
60706070#endif // _VMA_MAPPING_HYSTERESIS
60716071
6072+ #if defined(VK_USE_PLATFORM_WIN32_KHR)
6073+ class VmaWin32Handle
6074+ {
6075+ public:
6076+ VmaWin32Handle() noexcept : m_hHandle(VMA_NULL) { }
6077+ VmaWin32Handle(HANDLE hHandle) noexcept : m_hHandle(hHandle) { }
6078+ ~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL) { ::CloseHandle(m_hHandle); } }
6079+ VMA_CLASS_NO_COPY_NO_MOVE(VmaWin32Handle)
6080+ public:
6081+ VkResult Init(VkDevice device, VkDeviceMemory memory, decltype(&vkGetMemoryWin32HandleKHR) vkGetMemoryWin32HandleKHR) noexcept
6082+ {
6083+ VkResult res = VK_ERROR_FEATURE_NOT_PRESENT;
6084+ if (vkGetMemoryWin32HandleKHR != VMA_NULL)
6085+ {
6086+ VkMemoryGetWin32HandleInfoKHR handleInfo{ };
6087+ handleInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
6088+ handleInfo.memory = memory;
6089+ handleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
6090+ res = vkGetMemoryWin32HandleKHR(device, &handleInfo, &m_hHandle);
6091+ }
6092+ return res;
6093+ }
6094+ HANDLE Duplicate(HANDLE hTargetProcess = VMA_NULL) const noexcept
6095+ {
6096+ if (!m_hHandle)
6097+ return m_hHandle;
6098+
6099+ HANDLE hCurrentProcess = ::GetCurrentProcess();
6100+ HANDLE hDupHandle = VMA_NULL;
6101+ if (!::DuplicateHandle(hCurrentProcess, m_hHandle, hTargetProcess ? hTargetProcess : hCurrentProcess, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
6102+ {
6103+ VMA_ASSERT(0 && "Failed to duplicate handle.");
6104+ }
6105+ return hDupHandle;
6106+ }
6107+ operator bool() const noexcept { return m_hHandle != VMA_NULL; }
6108+
6109+ private:
6110+ HANDLE m_hHandle;
6111+ };
6112+ #else
6113+ class VmaWin32Handle
6114+ {
6115+ void* placeholder = VMA_NULL;
6116+ };
6117+ #endif // VK_USE_PLATFORM_WIN32_KHR
6118+
6119+
60726120#ifndef _VMA_DEVICE_MEMORY_BLOCK
60736121/*
60746122Represents a single block of device memory (`VkDeviceMemory`) with all the
@@ -6135,7 +6183,12 @@ class VmaDeviceMemoryBlock
61356183 VkDeviceSize allocationLocalOffset,
61366184 VkImage hImage,
61376185 const void* pNext);
6138-
6186+ #ifdef VK_USE_PLATFORM_WIN32_KHR
6187+ VkResult CreateWin32Handle(
6188+ const VmaAllocator hAllocator,
6189+ HANDLE hTargetProcess,
6190+ HANDLE* pHandle)noexcept;
6191+ #endif // VK_USE_PLATFORM_WIN32_KHR
61396192private:
61406193 VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
61416194 uint32_t m_MemoryTypeIndex;
@@ -6151,6 +6204,8 @@ class VmaDeviceMemoryBlock
61516204 VmaMappingHysteresis m_MappingHysteresis;
61526205 uint32_t m_MapCount;
61536206 void* m_pMappedData;
6207+
6208+ VmaWin32Handle m_Handle; // Win32 handle
61546209};
61556210#endif // _VMA_DEVICE_MEMORY_BLOCK
61566211
@@ -6236,6 +6291,10 @@ struct VmaAllocation_T
62366291 void PrintParameters(class VmaJsonWriter& json) const;
62376292#endif
62386293
6294+ #ifdef VK_USE_PLATFORM_WIN32_KHR
6295+ VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) const noexcept;
6296+ #endif // VK_USE_PLATFORM_WIN32_KHR
6297+
62396298private:
62406299 // Allocation out of VmaDeviceMemoryBlock.
62416300 struct BlockAllocation
@@ -6251,6 +6310,7 @@ struct VmaAllocation_T
62516310 void* m_pMappedData; // Not null means memory is mapped.
62526311 VmaAllocation_T* m_Prev;
62536312 VmaAllocation_T* m_Next;
6313+ VmaWin32Handle m_Handle; // Win32 handle
62546314 };
62556315 union
62566316 {
@@ -10434,7 +10494,8 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator)
1043410494 m_Id(0),
1043510495 m_hMemory(VK_NULL_HANDLE),
1043610496 m_MapCount(0),
10437- m_pMappedData(VMA_NULL) {}
10497+ m_pMappedData(VMA_NULL),
10498+ m_Handle(VMA_NULL) {}
1043810499
1043910500VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
1044010501{
@@ -10677,6 +10738,38 @@ VkResult VmaDeviceMemoryBlock::BindImageMemory(
1067710738 VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
1067810739 return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext);
1067910740}
10741+
10742+ #ifdef VK_USE_PLATFORM_WIN32_KHR
10743+ VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
10744+ {
10745+ VMA_ASSERT(pHandle);
10746+ *pHandle = VMA_NULL;
10747+
10748+ // relieves the mutex
10749+ if (m_Handle)
10750+ {
10751+ *pHandle = m_Handle.Duplicate(hTargetProcess);
10752+ return VK_SUCCESS;
10753+ }
10754+
10755+ VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
10756+ if (m_Handle)
10757+ {
10758+ *pHandle = m_Handle.Duplicate(hTargetProcess);
10759+ return VK_SUCCESS;
10760+ }
10761+
10762+ // Do we pass the function manually or use the one from the allocator?
10763+ VkResult res = m_Handle.Init(hAllocator->m_hDevice, m_hMemory, &vkGetMemoryWin32HandleKHR);
10764+ if (res != VK_SUCCESS)
10765+ {
10766+ return res;
10767+ }
10768+
10769+ *pHandle = m_Handle.Duplicate(hTargetProcess);
10770+ return VK_SUCCESS;
10771+ }
10772+ #endif // VK_USE_PLATFORM_WIN32_KHR
1068010773#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
1068110774
1068210775#ifndef _VMA_ALLOCATION_T_FUNCTIONS
@@ -10977,6 +11070,21 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
1097711070 json.WriteString(m_pName);
1097811071 }
1097911072}
11073+ #ifdef VK_USE_PLATFORM_WIN32_KHR
11074+ inline VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) const noexcept
11075+ {
11076+ switch (m_Type)
11077+ {
11078+ case ALLOCATION_TYPE_BLOCK:
11079+ return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, hTargetProcess, pHandle);
11080+ case ALLOCATION_TYPE_DEDICATED:
11081+ // return m_DedicatedAllocation.m_hMemory;
11082+ default:
11083+ VMA_ASSERT(0);
11084+ return VK_ERROR_FEATURE_NOT_PRESENT;
11085+ }
11086+ }
11087+ #endif // VK_USE_PLATFORM_WIN32_KHR
1098011088#endif // VMA_STATS_STRING_ENABLED
1098111089
1098211090void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
@@ -16429,6 +16537,15 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock V
1642916537 VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString);
1643016538 }
1643116539}
16540+ #ifdef VK_USE_PLATFORM_WIN32_KHR
16541+ VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32HandleKHR(VmaAllocator VMA_NOT_NULL allocator,
16542+ VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* pHandle)
16543+ {
16544+ VMA_ASSERT(allocator && allocation);
16545+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
16546+ return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
16547+ }
16548+ #endif // VK_USE_PLATFORM_WIN32_KHR
1643216549#endif // VMA_STATS_STRING_ENABLED
1643316550#endif // _VMA_PUBLIC_INTERFACE
1643416551#endif // VMA_IMPLEMENTATION
0 commit comments