Skip to content

Commit a0a04a2

Browse files
Added support for VK_KHR_maintenance4 extension
Added VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT.. See #397.
1 parent 14dfcd8 commit a0a04a2

1 file changed

Lines changed: 64 additions & 16 deletions

File tree

include/vk_mem_alloc.h

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ extern "C" {
212212
#endif
213213
#endif
214214

215+
// Defined to 1 when VK_KHR_maintenance4 device extension is defined in Vulkan headers.
216+
#if !defined(VMA_KHR_MAINTENANCE4)
217+
#if VK_KHR_maintenance4
218+
#define VMA_KHR_MAINTENANCE4 1
219+
#else
220+
#define VMA_KHR_MAINTENANCE4 0
221+
#endif
222+
#endif
223+
224+
215225
// Defined to 1 when VK_KHR_external_memory device extension is defined in Vulkan headers.
216226
#if !defined(VMA_EXTERNAL_MEMORY)
217227
#if VK_KHR_external_memory
@@ -425,6 +435,13 @@ typedef enum VmaAllocatorCreateFlagBits
425435
For more details, see the documentation of the VK_EXT_memory_priority extension.
426436
*/
427437
VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT = 0x00000040,
438+
/**
439+
Enables usage of VK_KHR_maintenance4 extension in the library.
440+
441+
You may set this flag only if you found available and enabled this device extension,
442+
while creating Vulkan device passed as VmaAllocatorCreateInfo::device.
443+
*/
444+
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT = 0x00000080,
428445

429446
VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
430447
} VmaAllocatorCreateFlagBits;
@@ -993,11 +1010,11 @@ typedef struct VmaVulkanFunctions
9931010
#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
9941011
PFN_vkGetPhysicalDeviceMemoryProperties2KHR VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties2KHR;
9951012
#endif
996-
#if VMA_VULKAN_VERSION >= 1003000
1013+
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
9971014
/// Fetch from "vkGetDeviceBufferMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceBufferMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
998-
PFN_vkGetDeviceBufferMemoryRequirements VMA_NULLABLE vkGetDeviceBufferMemoryRequirements;
1015+
PFN_vkGetDeviceBufferMemoryRequirementsKHR VMA_NULLABLE vkGetDeviceBufferMemoryRequirements;
9991016
/// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
1000-
PFN_vkGetDeviceImageMemoryRequirements VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
1017+
PFN_vkGetDeviceImageMemoryRequirementsKHR VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
10011018
#endif
10021019
} VmaVulkanFunctions;
10031020

@@ -11452,6 +11469,7 @@ struct VmaAllocator_T
1145211469
bool m_UseAmdDeviceCoherentMemory;
1145311470
bool m_UseKhrBufferDeviceAddress;
1145411471
bool m_UseExtMemoryPriority;
11472+
bool m_UseKhrMaintenance4;
1145511473
VkDevice m_hDevice;
1145611474
VkInstance m_hInstance;
1145711475
bool m_AllocationCallbacksSpecified;
@@ -14083,6 +14101,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
1408314101
m_UseAmdDeviceCoherentMemory((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT) != 0),
1408414102
m_UseKhrBufferDeviceAddress((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT) != 0),
1408514103
m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0),
14104+
m_UseKhrMaintenance4((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT) != 0),
1408614105
m_hDevice(pCreateInfo->device),
1408714106
m_hInstance(pCreateInfo->instance),
1408814107
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
@@ -14162,6 +14181,12 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
1416214181
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
1416314182
}
1416414183
#endif
14184+
#if !(VMA_KHR_MAINTENANCE4)
14185+
if(m_UseKhrMaintenance4)
14186+
{
14187+
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
14188+
}
14189+
#endif
1416514190

1416614191
memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));
1416714192
memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
@@ -14382,7 +14407,7 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul
1438214407
VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties2KHR);
1438314408
#endif
1438414409

14385-
#if VMA_VULKAN_VERSION >= 1003000
14410+
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
1438614411
VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements);
1438714412
VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements);
1438814413
#endif
@@ -14481,6 +14506,13 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
1448114506
VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirements, "vkGetDeviceImageMemoryRequirements");
1448214507
}
1448314508
#endif
14509+
#if VMA_KHR_MAINTENANCE4
14510+
if(m_UseKhrMaintenance4)
14511+
{
14512+
VMA_FETCH_DEVICE_FUNC(vkGetDeviceBufferMemoryRequirements, PFN_vkGetDeviceBufferMemoryRequirementsKHR, "vkGetDeviceBufferMemoryRequirementsKHR");
14513+
VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR");
14514+
}
14515+
#endif
1448414516

1448514517
#undef VMA_FETCH_DEVICE_FUNC
1448614518
#undef VMA_FETCH_INSTANCE_FUNC
@@ -14531,13 +14563,12 @@ void VmaAllocator_T::ValidateVulkanFunctions()
1453114563
}
1453214564
#endif
1453314565

14534-
#if VMA_VULKAN_VERSION >= 1003000
14535-
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
14536-
{
14537-
VMA_ASSERT(m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements != VMA_NULL);
14538-
VMA_ASSERT(m_VulkanFunctions.vkGetDeviceImageMemoryRequirements != VMA_NULL);
14539-
}
14540-
#endif
14566+
// Not validating these due to suspected driver bugs with these function
14567+
// pointers being null despite correct extension or Vulkan version is enabled.
14568+
// See issue #397. Their usage in VMA is optional anyway.
14569+
//
14570+
// VMA_ASSERT(m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements != VMA_NULL);
14571+
// VMA_ASSERT(m_VulkanFunctions.vkGetDeviceImageMemoryRequirements != VMA_NULL);
1454114572
}
1454214573

1454314574
VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)
@@ -16471,7 +16502,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
1647116502
const VmaVulkanFunctions* funcs = &allocator->GetVulkanFunctions();
1647216503
VkResult res;
1647316504

16474-
#if VMA_VULKAN_VERSION >= 1003000
16505+
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
1647516506
if(funcs->vkGetDeviceBufferMemoryRequirements)
1647616507
{
1647716508
// Can query straight from VkBufferCreateInfo :)
@@ -16485,7 +16516,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
1648516516
memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo, pBufferCreateInfo->usage, pMemoryTypeIndex);
1648616517
}
1648716518
else
16488-
#endif // #if VMA_VULKAN_VERSION >= 1003000
16519+
#endif // VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
1648916520
{
1649016521
// Must create a dummy buffer to query :(
1649116522
VkBuffer hBuffer = VK_NULL_HANDLE;
@@ -16521,7 +16552,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
1652116552
const VmaVulkanFunctions* funcs = &allocator->GetVulkanFunctions();
1652216553
VkResult res;
1652316554

16524-
#if VMA_VULKAN_VERSION >= 1003000
16555+
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
1652516556
if(funcs->vkGetDeviceImageMemoryRequirements)
1652616557
{
1652716558
// Can query straight from VkImageCreateInfo :)
@@ -16537,7 +16568,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
1653716568
memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo, pImageCreateInfo->usage, pMemoryTypeIndex);
1653816569
}
1653916570
else
16540-
#endif // #if VMA_VULKAN_VERSION >= 1003000
16571+
#endif // VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
1654116572
{
1654216573
// Must create a dummy image to query :(
1654316574
VkImage hImage = VK_NULL_HANDLE;
@@ -17815,7 +17846,23 @@ You may need to configure importing Vulkan functions. There are 3 ways to do thi
1781517846
- Define `VMA_STATIC_VULKAN_FUNCTIONS` and `VMA_DYNAMIC_VULKAN_FUNCTIONS` to 0.
1781617847
- Pass these pointers via structure #VmaVulkanFunctions.
1781717848

17818-
Example for case 2:
17849+
\subsection quick_start_initialization_enabling_extensions Enabling extensions
17850+
17851+
VMA can automatically use following Vulkan extensions.
17852+
If you found them availeble on the selected physical device and you enabled them
17853+
while creating `VkInstance` / `VkDevice` object, inform VMA about their availability
17854+
by setting appropriate flags in VmaAllocatorCreateInfo::flags.
17855+
17856+
Vulkan extension | VMA flag
17857+
------------------------------|-----------------------------------------------------
17858+
VK_KHR_dedicated_allocation | #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT
17859+
VK_KHR_bind_memory2 | #VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT
17860+
VK_KHR_maintenance4 | #VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT
17861+
VK_EXT_memory_budget | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
17862+
VK_EXT_memory_priority | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
17863+
VK_AMD_device_coherent_memory | #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
17864+
17865+
Example with fetching pointers to Vulkan functions dynamically:
1781917866

1782017867
\code
1782117868
#define VMA_STATIC_VULKAN_FUNCTIONS 0
@@ -17829,6 +17876,7 @@ vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
1782917876
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
1783017877

1783117878
VmaAllocatorCreateInfo allocatorCreateInfo = {};
17879+
allocatorCreateInfo.flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
1783217880
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
1783317881
allocatorCreateInfo.physicalDevice = physicalDevice;
1783417882
allocatorCreateInfo.device = device;

0 commit comments

Comments
 (0)