diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h index 9947c21..808eefc 100644 --- a/include/vk_mem_alloc.h +++ b/include/vk_mem_alloc.h @@ -2074,6 +2074,21 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties( VmaAllocation VMA_NOT_NULL allocation, VkMemoryPropertyFlags* VMA_NOT_NULL pFlags); + +#if VMA_EXTERNAL_MEMORY_WIN32 +/** +\brief Given an allocation, returns Win32 Handle, that may be imported by other processes or APIs. + +`hTargetProcess` must be a valid handle to target process or NULL. If it's `NULL`, the function returns +handle for the current process. + +If the allocation was created with `VMA_ALLOCATION_CREATE_EXPORT_WIN32_HANDLE_BIT` flag, +the function fills `pHandle` with handle that can be used in target process. +*/ +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); +#endif // VMA_EXTERNAL_MEMORY_WIN32 + /** \brief Maps memory represented by given allocation and returns pointer to it. Maps memory represented by given allocation to make it accessible to CPU code. @@ -6345,7 +6360,7 @@ public: #endif #if VMA_EXTERNAL_MEMORY_WIN32 - VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) const noexcept; + VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) noexcept; #endif // VMA_EXTERNAL_MEMORY_WIN32 private: @@ -6363,7 +6378,7 @@ private: void* m_pMappedData; // Not null means memory is mapped. VmaAllocation_T* m_Prev; VmaAllocation_T* m_Next; - mutable VmaWin32Handle m_Handle; // Win32 handle + VmaWin32Handle m_Handle; // Win32 handle }; union { @@ -11101,7 +11116,7 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const } } #if VMA_EXTERNAL_MEMORY_WIN32 -VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) const noexcept +VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept { // Where do we get this function from? auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR; @@ -13127,12 +13142,6 @@ void VmaAllocator_T::ImportVulkanFunctions_Static() m_VulkanFunctions.vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)vkGetDeviceImageMemoryRequirements; } #endif -#if VMA_EXTERNAL_MEMORY_WIN32 - // Can only be fetched dynamically - m_VulkanFunctions.vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)m_VulkanFunctions.vkGetDeviceProcAddr(m_hDevice, "vkGetMemoryWin32HandleKHR"); -#else - m_VulkanFunctions.vkGetMemoryWin32HandleKHR = VMA_NULL; -#endif } #endif // VMA_STATIC_VULKAN_FUNCTIONS == 1 @@ -16604,7 +16613,7 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock V } #if VMA_EXTERNAL_MEMORY_WIN32 VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32HandleKHR(VmaAllocator VMA_NOT_NULL allocator, - VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* pHandle) + VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle) { VMA_ASSERT(allocator && allocation); VMA_DEBUG_GLOBAL_MUTEX_LOCK; diff --git a/src/Tests.cpp b/src/Tests.cpp index 796b84d..4703672 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -8253,6 +8253,34 @@ static void TestMappingHysteresis() } } + +static void TestWin32Handles() +{ +#if VMA_EXTERNAL_MEMORY_WIN32 + wprintf(L"Test Win32 handles\n"); + VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bufCreateInfo.size = 1024; + bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + VmaAllocationCreateInfo allocCreateInfo = {}; + allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + VkBuffer buf; + VmaAllocation alloc; + VmaAllocationInfo allocInfo; + TEST(vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &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); + + vmaDestroyBuffer(g_hAllocator, buf, alloc); + TEST(CloseHandle(handle)); + TEST(CloseHandle(handle2)); +#endif +} + void Test() { wprintf(L"TESTING:\n"); @@ -8295,6 +8323,7 @@ void Test() TestMappingHysteresis(); TestDeviceLocalMapped(); TestMaintenance5(); + TestWin32Handles(); TestMappingMultithreaded(); TestLinearAllocator(); ManuallyTestLinearAllocator();