Skip to content

Commit ca17831

Browse files
Fixes after merge for VK_KHR_external_memory_win32 support
1 parent 0d55cf5 commit ca17831

File tree

4 files changed

+92
-55
lines changed

4 files changed

+92
-55
lines changed

include/vk_mem_alloc.h

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6273,11 +6273,17 @@ class VmaDeviceMemoryBlock
62736273
uint32_t m_MapCount;
62746274
void* m_pMappedData;
62756275

6276-
VmaWin32Handle m_Handle; // Win32 handle
6276+
VmaWin32Handle m_Handle;
62776277
};
62786278
#endif // _VMA_DEVICE_MEMORY_BLOCK
62796279

62806280
#ifndef _VMA_ALLOCATION_T
6281+
struct VmaAllocationExtraData
6282+
{
6283+
void* m_pMappedData = VMA_NULL; // Not null means memory is mapped.
6284+
VmaWin32Handle m_Handle;
6285+
};
6286+
62816287
struct VmaAllocation_T
62826288
{
62836289
friend struct VmaDedicatedAllocationListItemTraits;
@@ -6310,12 +6316,14 @@ struct VmaAllocation_T
63106316
bool mapped);
63116317
// pMappedData not null means allocation is created with MAPPED flag.
63126318
void InitDedicatedAllocation(
6319+
VmaAllocator allocator,
63136320
VmaPool hParentPool,
63146321
uint32_t memoryTypeIndex,
63156322
VkDeviceMemory hMemory,
63166323
VmaSuballocationType suballocationType,
63176324
void* pMappedData,
63186325
VkDeviceSize size);
6326+
void Destroy(VmaAllocator allocator);
63196327

63206328
ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; }
63216329
VkDeviceSize GetAlignment() const { return m_Alignment; }
@@ -6375,10 +6383,9 @@ struct VmaAllocation_T
63756383
{
63766384
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
63776385
VkDeviceMemory m_hMemory;
6378-
void* m_pMappedData; // Not null means memory is mapped.
6386+
VmaAllocationExtraData* m_ExtraData;
63796387
VmaAllocation_T* m_Prev;
63806388
VmaAllocation_T* m_Next;
6381-
VmaWin32Handle m_Handle; // Win32 handle
63826389
};
63836390
union
63846391
{
@@ -6401,6 +6408,8 @@ struct VmaAllocation_T
64016408
#if VMA_STATS_STRING_ENABLED
64026409
VmaBufferImageUsage m_BufferImageUsage; // 0 if unknown.
64036410
#endif
6411+
6412+
void EnsureExtraData(VmaAllocator hAllocator);
64046413
};
64056414
#endif // _VMA_ALLOCATION_T
64066415

@@ -10867,6 +10876,7 @@ void VmaAllocation_T::InitBlockAllocation(
1086710876
}
1086810877

1086910878
void VmaAllocation_T::InitDedicatedAllocation(
10879+
VmaAllocator allocator,
1087010880
VmaPool hParentPool,
1087110881
uint32_t memoryTypeIndex,
1087210882
VkDeviceMemory hMemory,
@@ -10881,16 +10891,29 @@ void VmaAllocation_T::InitDedicatedAllocation(
1088110891
m_Size = size;
1088210892
m_MemoryTypeIndex = memoryTypeIndex;
1088310893
m_SuballocationType = (uint8_t)suballocationType;
10884-
if(pMappedData != VMA_NULL)
10885-
{
10886-
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
10887-
m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
10888-
}
10894+
m_DedicatedAllocation.m_ExtraData = VMA_NULL;
1088910895
m_DedicatedAllocation.m_hParentPool = hParentPool;
1089010896
m_DedicatedAllocation.m_hMemory = hMemory;
10891-
m_DedicatedAllocation.m_pMappedData = pMappedData;
1089210897
m_DedicatedAllocation.m_Prev = VMA_NULL;
1089310898
m_DedicatedAllocation.m_Next = VMA_NULL;
10899+
10900+
if (pMappedData != VMA_NULL)
10901+
{
10902+
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
10903+
m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
10904+
EnsureExtraData(allocator);
10905+
m_DedicatedAllocation.m_ExtraData->m_pMappedData = pMappedData;
10906+
}
10907+
}
10908+
10909+
void VmaAllocation_T::Destroy(VmaAllocator allocator)
10910+
{
10911+
FreeName(allocator);
10912+
10913+
if (GetType() == ALLOCATION_TYPE_DEDICATED)
10914+
{
10915+
vma_delete(allocator, m_DedicatedAllocation.m_ExtraData);
10916+
}
1089410917
}
1089510918

1089610919
void VmaAllocation_T::SetName(VmaAllocator hAllocator, const char* pName)
@@ -10995,8 +11018,9 @@ void* VmaAllocation_T::GetMappedData() const
1099511018
}
1099611019
break;
1099711020
case ALLOCATION_TYPE_DEDICATED:
10998-
VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0 || IsPersistentMap()));
10999-
return m_DedicatedAllocation.m_pMappedData;
11021+
VMA_ASSERT((m_DedicatedAllocation.m_ExtraData != VMA_NULL && m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL) ==
11022+
(m_MapCount != 0 || IsPersistentMap()));
11023+
return m_DedicatedAllocation.m_ExtraData != VMA_NULL ? m_DedicatedAllocation.m_ExtraData->m_pMappedData : VMA_NULL;
1100011024
default:
1100111025
VMA_ASSERT(0);
1100211026
return VMA_NULL;
@@ -11037,12 +11061,14 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa
1103711061
VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);
1103811062
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
1103911063

11064+
EnsureExtraData(hAllocator);
11065+
1104011066
if (m_MapCount != 0 || IsPersistentMap())
1104111067
{
1104211068
if (m_MapCount < 0xFF)
1104311069
{
11044-
VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);
11045-
*ppData = m_DedicatedAllocation.m_pMappedData;
11070+
VMA_ASSERT(m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL);
11071+
*ppData = m_DedicatedAllocation.m_ExtraData->m_pMappedData;
1104611072
++m_MapCount;
1104711073
return VK_SUCCESS;
1104811074
}
@@ -11063,7 +11089,7 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa
1106311089
ppData);
1106411090
if (result == VK_SUCCESS)
1106511091
{
11066-
m_DedicatedAllocation.m_pMappedData = *ppData;
11092+
m_DedicatedAllocation.m_ExtraData->m_pMappedData = *ppData;
1106711093
m_MapCount = 1;
1106811094
}
1106911095
return result;
@@ -11079,7 +11105,8 @@ void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator)
1107911105
--m_MapCount;
1108011106
if (m_MapCount == 0 && !IsPersistentMap())
1108111107
{
11082-
m_DedicatedAllocation.m_pMappedData = VMA_NULL;
11108+
VMA_ASSERT(m_DedicatedAllocation.m_ExtraData != VMA_NULL);
11109+
m_DedicatedAllocation.m_ExtraData->m_pMappedData = VMA_NULL;
1108311110
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(
1108411111
hAllocator->m_hDevice,
1108511112
m_DedicatedAllocation.m_hMemory);
@@ -11118,14 +11145,14 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
1111811145
#if VMA_EXTERNAL_MEMORY_WIN32
1111911146
VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
1112011147
{
11121-
// Where do we get this function from?
1112211148
auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
1112311149
switch (m_Type)
1112411150
{
1112511151
case ALLOCATION_TYPE_BLOCK:
1112611152
return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
1112711153
case ALLOCATION_TYPE_DEDICATED:
11128-
return m_DedicatedAllocation.m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
11154+
EnsureExtraData(hAllocator);
11155+
return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
1112911156
default:
1113011157
VMA_ASSERT(0);
1113111158
return VK_ERROR_FEATURE_NOT_PRESENT;
@@ -11134,6 +11161,14 @@ VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTarget
1113411161
#endif // VMA_EXTERNAL_MEMORY_WIN32
1113511162
#endif // VMA_STATS_STRING_ENABLED
1113611163

11164+
void VmaAllocation_T::EnsureExtraData(VmaAllocator hAllocator)
11165+
{
11166+
if (m_DedicatedAllocation.m_ExtraData == VMA_NULL)
11167+
{
11168+
m_DedicatedAllocation.m_ExtraData = vma_new(hAllocator, VmaAllocationExtraData)();
11169+
}
11170+
}
11171+
1113711172
void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
1113811173
{
1113911174
if(m_pName)
@@ -11562,6 +11597,7 @@ void VmaBlockVector::Free(const VmaAllocation hAllocation)
1156211597
}
1156311598

1156411599
m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
11600+
hAllocation->Destroy(m_hAllocator);
1156511601
m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
1156611602
}
1156711603

@@ -13705,7 +13741,7 @@ VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
1370513741
}
1370613742

1370713743
*pAllocation = m_AllocationObjectAllocator.Allocate(isMappingAllowed);
13708-
(*pAllocation)->InitDedicatedAllocation(pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
13744+
(*pAllocation)->InitDedicatedAllocation(this, pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
1370913745
if (isUserDataString)
1371013746
(*pAllocation)->SetName(this, (const char*)pUserData);
1371113747
else
@@ -14041,8 +14077,6 @@ void VmaAllocator_T::FreeMemory(
1404114077
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
1404214078
}
1404314079

14044-
allocation->FreeName(this);
14045-
1404614080
switch(allocation->GetType())
1404714081
{
1404814082
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
@@ -14726,6 +14760,7 @@ void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation)
1472614760
FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
1472714761

1472814762
m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize());
14763+
allocation->Destroy(this);
1472914764
m_AllocationObjectAllocator.Free(allocation);
1473014765

1473114766
VMA_DEBUG_LOG_FORMAT(" Freed DedicatedMemory MemoryTypeIndex=%" PRIu32, memTypeIndex);
@@ -16615,7 +16650,7 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock V
1661516650
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32HandleKHR(VmaAllocator VMA_NOT_NULL allocator,
1661616651
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
1661716652
{
16618-
VMA_ASSERT(allocator && allocation);
16653+
VMA_ASSERT(allocator && allocation && pHandle);
1661916654
VMA_DEBUG_GLOBAL_MUTEX_LOCK;
1662016655
return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
1662116656
}
@@ -16753,6 +16788,7 @@ VK_EXT_memory_budget | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
1675316788
VK_KHR_buffer_device_address | #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
1675416789
VK_EXT_memory_priority | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
1675516790
VK_AMD_device_coherent_memory | #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
16791+
VK_KHR_external_memory_win32 | #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
1675616792

1675716793
Example with fetching pointers to Vulkan functions dynamically:
1675816794

src/Shaders/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ foreach(SHADER ${SHADERS})
3434
DEPENDS ${SHADER}
3535
)
3636

37-
list(APPEND SPIRV_FILES ${SPIRV})
37+
list(APPEND SPIRV_FILES ${SPIRV} ${SPIRV_BIN})
3838
endforeach()
3939

4040
add_custom_target(VmaSampleShaders ALL DEPENDS ${SPIRV_FILES})

src/Tests.cpp

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8258,61 +8258,59 @@ static void TestWin32Handles()
82588258
{
82598259
#if VMA_EXTERNAL_MEMORY_WIN32
82608260
wprintf(L"Test Win32 handles\n");
8261-
constexpr static VkExportMemoryAllocateInfoKHR exportInfo{
8261+
constexpr static VkExportMemoryAllocateInfoKHR exportMemAllocInfo{
82628262
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
82638263
nullptr,
82648264
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
82658265
};
8266-
constexpr static VkExternalMemoryBufferCreateInfoKHR externalInfo{
8266+
constexpr static VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo{
82678267
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
82688268
nullptr,
82698269
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
82708270
};
82718271

8272-
VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
8273-
sampleBufCreateInfo.size = 0x1000; // Doesn't matter.
8274-
sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
8275-
sampleBufCreateInfo.pNext = &externalInfo;
8272+
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
8273+
bufCreateInfo.size = 0x10000;
8274+
bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
8275+
bufCreateInfo.pNext = &externalMemBufCreateInfo;
82768276

8277-
VmaAllocationCreateInfo sampleAllocCreateInfo = {};
8278-
sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
8279-
sampleAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
8277+
VmaAllocationCreateInfo allocCreateInfo = {};
8278+
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
82808279

8281-
uint32_t memTypeIndex;
8280+
uint32_t memTypeIndex = UINT32_MAX;
82828281
TEST(vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator,
8283-
&sampleBufCreateInfo, &sampleAllocCreateInfo, &memTypeIndex) == VK_SUCCESS);
8284-
// Check res...
8285-
8282+
&bufCreateInfo, &allocCreateInfo, &memTypeIndex) == VK_SUCCESS);
82868283

82878284
// Create a pool that can have at most 2 blocks, 128 MiB each.
82888285
VmaPoolCreateInfo poolCreateInfo = {};
82898286
poolCreateInfo.memoryTypeIndex = memTypeIndex;
8290-
poolCreateInfo.blockSize = 128ull * 1024 * 1024;
8291-
poolCreateInfo.maxBlockCount = 2;
8292-
poolCreateInfo.pMemoryAllocateNext = (void*)&exportInfo;
8293-
8287+
poolCreateInfo.pMemoryAllocateNext = (void*)&exportMemAllocInfo;
82948288

8295-
VmaPool pool;
8289+
VmaPool pool = VK_NULL_HANDLE;
82968290
TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS);
82978291

8292+
allocCreateInfo.pool = pool;
82988293

8299-
sampleAllocCreateInfo.pool = pool;
8294+
for (size_t test = 0; test < 2; ++test)
8295+
{
8296+
if (test == 1)
8297+
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
83008298

8301-
VkBuffer buf;
8302-
VmaAllocation alloc;
8303-
VmaAllocationInfo allocInfo;
8304-
TEST(vmaCreateBuffer(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &buf, &alloc, &allocInfo) == VK_SUCCESS);
8305-
HANDLE handle;
8306-
HANDLE handle2;
8307-
TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle) == VK_SUCCESS);
8308-
TEST(handle != nullptr);
8309-
TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle2) == VK_SUCCESS);
8310-
TEST(handle2 != nullptr);
8311-
TEST(handle2 != handle);
8299+
VkBuffer buf = VK_NULL_HANDLE;
8300+
VmaAllocation alloc = VK_NULL_HANDLE;
8301+
TEST(vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr) == VK_SUCCESS);
8302+
HANDLE handle = NULL;
8303+
HANDLE handle2 = NULL;
8304+
TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle) == VK_SUCCESS);
8305+
TEST(handle != nullptr);
8306+
TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle2) == VK_SUCCESS);
8307+
TEST(handle2 != nullptr);
8308+
TEST(handle2 != handle);
83128309

8313-
vmaDestroyBuffer(g_hAllocator, buf, alloc);
8314-
TEST(CloseHandle(handle));
8315-
TEST(CloseHandle(handle2));
8310+
vmaDestroyBuffer(g_hAllocator, buf, alloc);
8311+
TEST(CloseHandle(handle));
8312+
TEST(CloseHandle(handle2));
8313+
}
83168314

83178315
vmaDestroyPool(g_hAllocator, pool);
83188316
#endif

src/VmaUsage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ include all public interface declarations. Example:
9696
#pragma clang diagnostic ignored "-Wnullability-completeness"
9797
#endif
9898

99+
#include <vulkan/vulkan.h>
100+
#include <vulkan/vulkan_win32.h>
101+
99102
#include "vk_mem_alloc.h"
100103

101104
#ifdef __clang__

0 commit comments

Comments
 (0)