Skip to content

Commit 412d69d

Browse files
Added vmaImportVulkanFunctionsFromVolk
1 parent d8d4f86 commit 412d69d

File tree

6 files changed

+141
-4
lines changed

6 files changed

+141
-4
lines changed

Doxyfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2469,7 +2469,8 @@ PREDEFINED = VMA_CALL_PRE= \
24692469
VMA_EXTERNAL_MEMORY_WIN32=1 \
24702470
VMA_EXTERNAL_MEMORY=1 \
24712471
VMA_EXTENDS_VK_STRUCT= \
2472-
VMA_STATS_STRING_ENABLED=1
2472+
VMA_STATS_STRING_ENABLED=1 \
2473+
VOLK_HEADER_VERSION=304
24732474

24742475
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
24752476
# tag can be used to specify a list of macro names that should be expanded. The

include/vk_mem_alloc.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,20 @@ typedef struct VmaVirtualAllocationInfo
16691669
@{
16701670
*/
16711671

1672+
#ifdef VOLK_HEADER_VERSION
1673+
/** \brief Fully initializes `dst` structure with Vulkan functions needed by this library based on functions imported by
1674+
[volk library](https://github.com/zeux/volk).
1675+
1676+
If you use volk, call this function after `VkInstance` and `VkDevice` is created to fill in structure #VmaVulkanFunctions
1677+
before calling vmaCreateAllocator().
1678+
1679+
Pointers to functions related to the entire Vulkan instance are fetched using global function definitions.
1680+
Pointers to functions related to the Vulkan device are fetched using `volkLoadDeviceTable()` for given `device`.
1681+
*/
1682+
VMA_CALL_PRE VkResult VMA_CALL_POST vmaImportVulkanFunctionsFromVolk(
1683+
VkDevice VMA_NOT_NULL device, VmaVulkanFunctions* VMA_NOT_NULL dst);
1684+
#endif
1685+
16721686
/// Creates #VmaAllocator object.
16731687
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator(
16741688
const VmaAllocatorCreateInfo* VMA_NOT_NULL pCreateInfo,
@@ -15082,6 +15096,78 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
1508215096

1508315097

1508415098
#ifndef _VMA_PUBLIC_INTERFACE
15099+
15100+
#ifdef VOLK_HEADER_VERSION
15101+
15102+
VMA_CALL_PRE VkResult VMA_CALL_POST vmaImportVulkanFunctionsFromVolk(
15103+
VkDevice VMA_NOT_NULL device, VmaVulkanFunctions* VMA_NOT_NULL dst)
15104+
{
15105+
VolkDeviceTable src = {};
15106+
memset(&dst, 0, sizeof(dst));
15107+
memset(&src, 0, sizeof(src));
15108+
15109+
volkLoadDeviceTable(&src, device);
15110+
15111+
#define COPY_GLOBAL_TO_VMA_FUNC(volkName, vmaName) if(!dst->vmaName) dst->vmaName = volkName;
15112+
#define COPY_DEVICE_TO_VMA_FUNC(volkName, vmaName) if(!dst->vmaName) dst->vmaName = src.volkName;
15113+
15114+
COPY_GLOBAL_TO_VMA_FUNC(vkGetInstanceProcAddr, vkGetInstanceProcAddr)
15115+
COPY_GLOBAL_TO_VMA_FUNC(vkGetDeviceProcAddr, vkGetDeviceProcAddr)
15116+
COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceProperties, vkGetPhysicalDeviceProperties)
15117+
COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties, vkGetPhysicalDeviceMemoryProperties)
15118+
COPY_DEVICE_TO_VMA_FUNC(vkAllocateMemory, vkAllocateMemory)
15119+
COPY_DEVICE_TO_VMA_FUNC(vkFreeMemory, vkFreeMemory)
15120+
COPY_DEVICE_TO_VMA_FUNC(vkMapMemory, vkMapMemory)
15121+
COPY_DEVICE_TO_VMA_FUNC(vkUnmapMemory, vkUnmapMemory)
15122+
COPY_DEVICE_TO_VMA_FUNC(vkFlushMappedMemoryRanges, vkFlushMappedMemoryRanges)
15123+
COPY_DEVICE_TO_VMA_FUNC(vkInvalidateMappedMemoryRanges, vkInvalidateMappedMemoryRanges)
15124+
COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory, vkBindBufferMemory)
15125+
COPY_DEVICE_TO_VMA_FUNC(vkBindImageMemory, vkBindImageMemory)
15126+
COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements, vkGetBufferMemoryRequirements)
15127+
COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements, vkGetImageMemoryRequirements)
15128+
COPY_DEVICE_TO_VMA_FUNC(vkCreateBuffer, vkCreateBuffer)
15129+
COPY_DEVICE_TO_VMA_FUNC(vkDestroyBuffer, vkDestroyBuffer)
15130+
COPY_DEVICE_TO_VMA_FUNC(vkCreateImage, vkCreateImage)
15131+
COPY_DEVICE_TO_VMA_FUNC(vkDestroyImage, vkDestroyImage)
15132+
COPY_DEVICE_TO_VMA_FUNC(vkCmdCopyBuffer, vkCmdCopyBuffer)
15133+
#if VMA_VULKAN_VERSION >= 1001000
15134+
COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties2, vkGetPhysicalDeviceMemoryProperties2KHR)
15135+
COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements2, vkGetBufferMemoryRequirements2KHR)
15136+
COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements2, vkGetImageMemoryRequirements2KHR)
15137+
COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory2, vkBindBufferMemory2KHR)
15138+
COPY_DEVICE_TO_VMA_FUNC(vkBindImageMemory2, vkBindImageMemory2KHR)
15139+
#endif
15140+
#if VMA_VULKAN_VERSION >= 1003000
15141+
COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceBufferMemoryRequirements, vkGetDeviceBufferMemoryRequirements)
15142+
COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceImageMemoryRequirements, vkGetDeviceImageMemoryRequirements)
15143+
#endif
15144+
#if VMA_KHR_MAINTENANCE4
15145+
COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceBufferMemoryRequirementsKHR, vkGetDeviceBufferMemoryRequirements)
15146+
COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceImageMemoryRequirementsKHR, vkGetDeviceImageMemoryRequirements)
15147+
#endif
15148+
#if VMA_DEDICATED_ALLOCATION
15149+
COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements2KHR, vkGetBufferMemoryRequirements2KHR)
15150+
COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements2KHR, vkGetImageMemoryRequirements2KHR)
15151+
#endif
15152+
#if VMA_BIND_MEMORY2
15153+
COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory2KHR, vkBindBufferMemory2KHR)
15154+
COPY_DEVICE_TO_VMA_FUNC(vkBindImageMemory2KHR, vkBindImageMemory2KHR)
15155+
#endif
15156+
#if VMA_MEMORY_BUDGET
15157+
COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, vkGetPhysicalDeviceMemoryProperties2KHR)
15158+
#endif
15159+
#if VMA_EXTERNAL_MEMORY_WIN32
15160+
COPY_DEVICE_TO_VMA_FUNC(vkGetMemoryWin32HandleKHR, vkGetMemoryWin32HandleKHR)
15161+
#endif
15162+
15163+
#undef COPY_DEVICE_TO_VMA_FUNC
15164+
#undef COPY_GLOBAL_TO_VMA_FUNC
15165+
15166+
return VK_SUCCESS;
15167+
}
15168+
15169+
#endif // #ifdef VOLK_HEADER_VERSION
15170+
1508515171
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator(
1508615172
const VmaAllocatorCreateInfo* pCreateInfo,
1508715173
VmaAllocator* pAllocator)

src/Tests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3902,6 +3902,11 @@ void TestHeapSizeLimit()
39023902
allocatorCreateInfo.device = g_hDevice;
39033903
allocatorCreateInfo.instance = g_hVulkanInstance;
39043904
allocatorCreateInfo.pHeapSizeLimit = heapSizeLimit;
3905+
#ifdef VOLK_HEADER_VERSION
3906+
VmaVulkanFunctions vulkanFunctions = {};
3907+
vmaImportVulkanFunctionsFromVolk(g_hDevice, &vulkanFunctions);
3908+
allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
3909+
#endif
39053910
#if VMA_DYNAMIC_VULKAN_FUNCTIONS
39063911
VmaVulkanFunctions vulkanFunctions = {};
39073912
vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;

src/VmaUsage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ include all public interface declarations. Example:
9696
#pragma clang diagnostic ignored "-Wnullability-completeness"
9797
#endif
9898

99-
#include <vulkan/vulkan.h>
99+
//#include <vulkan/vulkan.h>
100+
#include "third_party/volk-1.4.304/volk.h"
100101

101102
#ifdef _WIN32
102103
#include <vulkan/vulkan_win32.h>

src/VolkUsage.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All rights reserved.
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy
5+
// of this software and associated documentation files (the "Software"), to deal
6+
// in the Software without restriction, including without limitation the rights
7+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the Software is
9+
// furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in
12+
// all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
// THE SOFTWARE.
21+
//
22+
23+
/*
24+
In exactly one CPP file define macro VMA_IMPLEMENTATION and then include
25+
vk_mem_alloc.h to include definitions of its internal implementation
26+
*/
27+
28+
#define VOLK_IMPLEMENTATION
29+
#include "VmaUsage.h"

src/VulkanSample.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ void VulkanUsage::Init()
426426
g_Allocs = &g_CpuAllocationCallbacks;
427427
}
428428

429+
ERR_GUARD_VULKAN(volkInitialize());
430+
429431
uint32_t instanceLayerPropCount = 0;
430432
ERR_GUARD_VULKAN( vkEnumerateInstanceLayerProperties(&instanceLayerPropCount, nullptr) );
431433
std::vector<VkLayerProperties> instanceLayerProps(instanceLayerPropCount);
@@ -513,6 +515,8 @@ void VulkanUsage::Init()
513515

514516
ERR_GUARD_VULKAN( vkCreateInstance(&instInfo, g_Allocs, &g_hVulkanInstance) );
515517

518+
volkLoadInstance(g_hVulkanInstance);
519+
516520
if(VK_EXT_debug_utils_enabled)
517521
{
518522
RegisterDebugCallbacks();
@@ -1511,12 +1515,22 @@ void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo)
15111515
outInfo.pAllocationCallbacks = &g_CpuAllocationCallbacks;
15121516
}
15131517

1514-
#if VMA_DYNAMIC_VULKAN_FUNCTIONS
1518+
#ifdef VOLK_HEADER_VERSION
1519+
15151520
static VmaVulkanFunctions vulkanFunctions = {};
1521+
vmaImportVulkanFunctionsFromVolk(g_hDevice, &vulkanFunctions);
1522+
outInfo.pVulkanFunctions = &vulkanFunctions;
1523+
1524+
#else // #ifdef VOLK_HEADER_VERSION
1525+
1526+
#if VMA_DYNAMIC_VULKAN_FUNCTIONS
1527+
v static VmaVulkanFunctions vulkanFunctions = {};
15161528
vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
15171529
vulkanFunctions.vkGetDeviceProcAddr = vkGetDeviceProcAddr;
15181530
outInfo.pVulkanFunctions = &vulkanFunctions;
1519-
#endif
1531+
#endif // #if VMA_DYNAMIC_VULKAN_FUNCTIONS
1532+
1533+
#endif // #ifdef VOLK_HEADER_VERSION
15201534

15211535
// Uncomment to enable HeapSizeLimit.
15221536
/*
@@ -2083,6 +2097,7 @@ static void InitializeApplication()
20832097
deviceCreateInfo.pQueueCreateInfos = queueCreateInfo;
20842098

20852099
ERR_GUARD_VULKAN( vkCreateDevice(g_hPhysicalDevice, &deviceCreateInfo, g_Allocs, &g_hDevice) );
2100+
volkLoadDevice(g_hDevice);
20862101
SetDebugUtilsObjectName(VK_OBJECT_TYPE_DEVICE, reinterpret_cast<std::uint64_t>(g_hDevice), "g_hDevice");
20872102
// Only now that SetDebugUtilsObjectName is loaded, we can assign a name to g_hVulkanInstance as well
20882103
SetDebugUtilsObjectName(VK_OBJECT_TYPE_INSTANCE, reinterpret_cast<std::uint64_t>(g_hVulkanInstance), "g_hVulkanInstance");

0 commit comments

Comments
 (0)