From 76411c95c0ba5c1674b5d4337f65ad602716ff21 Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Fri, 23 Oct 2020 16:10:49 +0200 Subject: [PATCH] Added VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes --- src/VulkanSample.cpp | 13 +++++++++++++ src/vk_mem_alloc.h | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp index 1c31f07..3cae1bd 100644 --- a/src/VulkanSample.cpp +++ b/src/VulkanSample.cpp @@ -1179,6 +1179,19 @@ 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) diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h index 18e644e..254f466 100644 --- a/src/vk_mem_alloc.h +++ b/src/vk_mem_alloc.h @@ -2451,6 +2451,17 @@ 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. @@ -8032,12 +8043,18 @@ public: */ uint32_t GetGpuDefragmentationMemoryTypeBits(); + VkExternalMemoryHandleTypeFlagsKHR GetExternalMemoryHandleTypeFlags(uint32_t memTypeIndex) const + { + return m_TypeExternalMemoryHandleTypes[memTypeIndex]; + } + private: VkDeviceSize m_PreferredLargeHeapBlockSize; 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; // Protected by m_PoolsMutex. Sorted by pointer value. @@ -13289,6 +13306,14 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn } #endif // #if VMA_BUFFER_DEVICE_ADDRESS + // 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) @@ -15727,6 +15752,8 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : memset(&m_pDedicatedAllocations, 0, sizeof(m_pDedicatedAllocations)); memset(&m_VulkanFunctions, 0, sizeof(m_VulkanFunctions)); + memset(&m_TypeExternalMemoryHandleTypes, 0, sizeof(m_TypeExternalMemoryHandleTypes)); + if(pCreateInfo->pDeviceMemoryCallbacks != VMA_NULL) { m_DeviceMemoryCallbacks.pUserData = pCreateInfo->pDeviceMemoryCallbacks->pUserData; @@ -15749,6 +15776,12 @@ 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) { for(uint32_t heapIndex = 0; heapIndex < GetMemoryHeapCount(); ++heapIndex) @@ -15784,7 +15817,6 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here, // becase minBlockCount is 0. m_pDedicatedAllocations[memTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator(GetAllocationCallbacks())); - } } @@ -16264,6 +16296,14 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( } #endif // #if VMA_BUFFER_DEVICE_ADDRESS + // 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)