Skip to content

Commit 746c651

Browse files
committed
basic outline of the Win32 handle extension
1 parent b8e5747 commit 746c651

1 file changed

Lines changed: 119 additions & 2 deletions

File tree

include/vk_mem_alloc.h

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
/*
60746122
Represents 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
61396192
private:
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+
62396298
private:
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

1043910500
VmaDeviceMemoryBlock::~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

1098211090
void 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

Comments
 (0)