Added vmaImportVulkanFunctionsFromVolk
diff --git a/Doxyfile b/Doxyfile
index 2b6bcc9..346537c 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -2469,7 +2469,8 @@
                          VMA_EXTERNAL_MEMORY_WIN32=1 \
                          VMA_EXTERNAL_MEMORY=1 \
                          VMA_EXTENDS_VK_STRUCT= \
-                         VMA_STATS_STRING_ENABLED=1
+                         VMA_STATS_STRING_ENABLED=1 \
+                         VOLK_HEADER_VERSION=304
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h
index 3639f61..9004642 100644
--- a/include/vk_mem_alloc.h
+++ b/include/vk_mem_alloc.h
@@ -1669,6 +1669,20 @@
 @{
 */
 
+#ifdef VOLK_HEADER_VERSION
+/** \brief Fully initializes `dst` structure with Vulkan functions needed by this library based on functions imported by
+[volk library](https://github.com/zeux/volk).
+
+If you use volk, call this function after `VkInstance` and `VkDevice` is created to fill in structure #VmaVulkanFunctions
+before calling vmaCreateAllocator().
+
+Pointers to functions related to the entire Vulkan instance are fetched using global function definitions.
+Pointers to functions related to the Vulkan device are fetched using `volkLoadDeviceTable()` for given `device`.
+ */
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaImportVulkanFunctionsFromVolk(
+    VkDevice VMA_NOT_NULL device, VmaVulkanFunctions* VMA_NOT_NULL dst);
+#endif
+
 /// Creates #VmaAllocator object.
 VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator(
     const VmaAllocatorCreateInfo* VMA_NOT_NULL pCreateInfo,
@@ -15082,6 +15096,78 @@
 
 
 #ifndef _VMA_PUBLIC_INTERFACE
+
+#ifdef VOLK_HEADER_VERSION
+
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaImportVulkanFunctionsFromVolk(
+    VkDevice VMA_NOT_NULL device, VmaVulkanFunctions* VMA_NOT_NULL dst)
+{
+    VolkDeviceTable src = {};
+    memset(&dst, 0, sizeof(dst));
+    memset(&src, 0, sizeof(src));
+    
+    volkLoadDeviceTable(&src, device);
+
+#define COPY_GLOBAL_TO_VMA_FUNC(volkName, vmaName) if(!dst->vmaName) dst->vmaName = volkName;
+#define COPY_DEVICE_TO_VMA_FUNC(volkName, vmaName) if(!dst->vmaName) dst->vmaName = src.volkName;
+
+    COPY_GLOBAL_TO_VMA_FUNC(vkGetInstanceProcAddr, vkGetInstanceProcAddr)
+    COPY_GLOBAL_TO_VMA_FUNC(vkGetDeviceProcAddr, vkGetDeviceProcAddr)
+    COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceProperties, vkGetPhysicalDeviceProperties)
+    COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties, vkGetPhysicalDeviceMemoryProperties)
+    COPY_DEVICE_TO_VMA_FUNC(vkAllocateMemory, vkAllocateMemory)
+    COPY_DEVICE_TO_VMA_FUNC(vkFreeMemory, vkFreeMemory)
+    COPY_DEVICE_TO_VMA_FUNC(vkMapMemory, vkMapMemory)
+    COPY_DEVICE_TO_VMA_FUNC(vkUnmapMemory, vkUnmapMemory)
+    COPY_DEVICE_TO_VMA_FUNC(vkFlushMappedMemoryRanges, vkFlushMappedMemoryRanges)
+    COPY_DEVICE_TO_VMA_FUNC(vkInvalidateMappedMemoryRanges, vkInvalidateMappedMemoryRanges)
+    COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory, vkBindBufferMemory)
+    COPY_DEVICE_TO_VMA_FUNC(vkBindImageMemory, vkBindImageMemory)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements, vkGetBufferMemoryRequirements)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements, vkGetImageMemoryRequirements)
+    COPY_DEVICE_TO_VMA_FUNC(vkCreateBuffer, vkCreateBuffer)
+    COPY_DEVICE_TO_VMA_FUNC(vkDestroyBuffer, vkDestroyBuffer)
+    COPY_DEVICE_TO_VMA_FUNC(vkCreateImage, vkCreateImage)
+    COPY_DEVICE_TO_VMA_FUNC(vkDestroyImage, vkDestroyImage)
+    COPY_DEVICE_TO_VMA_FUNC(vkCmdCopyBuffer, vkCmdCopyBuffer)
+#if VMA_VULKAN_VERSION >= 1001000
+    COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties2, vkGetPhysicalDeviceMemoryProperties2KHR)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements2, vkGetBufferMemoryRequirements2KHR)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements2, vkGetImageMemoryRequirements2KHR)
+    COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory2, vkBindBufferMemory2KHR)
+    COPY_DEVICE_TO_VMA_FUNC(vkBindImageMemory2, vkBindImageMemory2KHR)
+#endif
+#if VMA_VULKAN_VERSION >= 1003000
+    COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceBufferMemoryRequirements, vkGetDeviceBufferMemoryRequirements)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceImageMemoryRequirements, vkGetDeviceImageMemoryRequirements)
+#endif
+#if VMA_KHR_MAINTENANCE4
+    COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceBufferMemoryRequirementsKHR, vkGetDeviceBufferMemoryRequirements)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetDeviceImageMemoryRequirementsKHR, vkGetDeviceImageMemoryRequirements)
+#endif
+#if VMA_DEDICATED_ALLOCATION
+    COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements2KHR, vkGetBufferMemoryRequirements2KHR)
+    COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements2KHR, vkGetImageMemoryRequirements2KHR)
+#endif
+#if VMA_BIND_MEMORY2
+    COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory2KHR, vkBindBufferMemory2KHR)
+    COPY_DEVICE_TO_VMA_FUNC(vkBindImageMemory2KHR, vkBindImageMemory2KHR)
+#endif
+#if VMA_MEMORY_BUDGET
+    COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, vkGetPhysicalDeviceMemoryProperties2KHR)
+#endif
+#if VMA_EXTERNAL_MEMORY_WIN32
+    COPY_DEVICE_TO_VMA_FUNC(vkGetMemoryWin32HandleKHR, vkGetMemoryWin32HandleKHR)
+#endif
+
+#undef COPY_DEVICE_TO_VMA_FUNC
+#undef COPY_GLOBAL_TO_VMA_FUNC
+
+    return VK_SUCCESS;
+}
+
+#endif // #ifdef VOLK_HEADER_VERSION
+
 VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator(
     const VmaAllocatorCreateInfo* pCreateInfo,
     VmaAllocator* pAllocator)
diff --git a/src/Tests.cpp b/src/Tests.cpp
index b10ee6d..5ca5659 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -3902,6 +3902,11 @@
     allocatorCreateInfo.device = g_hDevice;
     allocatorCreateInfo.instance = g_hVulkanInstance;
     allocatorCreateInfo.pHeapSizeLimit = heapSizeLimit;
+#ifdef VOLK_HEADER_VERSION
+    VmaVulkanFunctions vulkanFunctions = {};
+    vmaImportVulkanFunctionsFromVolk(g_hDevice, &vulkanFunctions);
+    allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
+#endif
 #if VMA_DYNAMIC_VULKAN_FUNCTIONS
     VmaVulkanFunctions vulkanFunctions = {};
     vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
diff --git a/src/VmaUsage.h b/src/VmaUsage.h
index 906d6b9..9442487 100644
--- a/src/VmaUsage.h
+++ b/src/VmaUsage.h
@@ -96,7 +96,8 @@
     #pragma clang diagnostic ignored "-Wnullability-completeness"
 #endif
 
-#include <vulkan/vulkan.h>
+//#include <vulkan/vulkan.h>
+#include "third_party/volk-1.4.304/volk.h"
 
 #ifdef _WIN32
 #include <vulkan/vulkan_win32.h>
diff --git a/src/VolkUsage.cpp b/src/VolkUsage.cpp
new file mode 100644
index 0000000..e129304
--- /dev/null
+++ b/src/VolkUsage.cpp
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/*
+In exactly one CPP file define macro VMA_IMPLEMENTATION and then include
+vk_mem_alloc.h to include definitions of its internal implementation
+*/
+
+#define VOLK_IMPLEMENTATION
+#include "VmaUsage.h"
diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp
index a8d1f3e..abf20e3 100644
--- a/src/VulkanSample.cpp
+++ b/src/VulkanSample.cpp
@@ -426,6 +426,8 @@
         g_Allocs = &g_CpuAllocationCallbacks;
     }
 
+    ERR_GUARD_VULKAN(volkInitialize());
+
     uint32_t instanceLayerPropCount = 0;
     ERR_GUARD_VULKAN( vkEnumerateInstanceLayerProperties(&instanceLayerPropCount, nullptr) );
     std::vector<VkLayerProperties> instanceLayerProps(instanceLayerPropCount);
@@ -513,6 +515,8 @@
 
     ERR_GUARD_VULKAN( vkCreateInstance(&instInfo, g_Allocs, &g_hVulkanInstance) );
 
+    volkLoadInstance(g_hVulkanInstance);
+
     if(VK_EXT_debug_utils_enabled)
     {
         RegisterDebugCallbacks();
@@ -1511,12 +1515,22 @@
         outInfo.pAllocationCallbacks = &g_CpuAllocationCallbacks;
     }
 
-#if VMA_DYNAMIC_VULKAN_FUNCTIONS
+#ifdef VOLK_HEADER_VERSION
+
     static VmaVulkanFunctions vulkanFunctions = {};
+    vmaImportVulkanFunctionsFromVolk(g_hDevice, &vulkanFunctions);
+    outInfo.pVulkanFunctions = &vulkanFunctions;
+
+#else // #ifdef VOLK_HEADER_VERSION
+
+#if VMA_DYNAMIC_VULKAN_FUNCTIONS
+v    static VmaVulkanFunctions vulkanFunctions = {};
     vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
     vulkanFunctions.vkGetDeviceProcAddr = vkGetDeviceProcAddr;
     outInfo.pVulkanFunctions = &vulkanFunctions;
-#endif
+#endif // #if VMA_DYNAMIC_VULKAN_FUNCTIONS
+
+#endif // #ifdef VOLK_HEADER_VERSION
 
     // Uncomment to enable HeapSizeLimit.
     /*
@@ -2083,6 +2097,7 @@
     deviceCreateInfo.pQueueCreateInfos = queueCreateInfo;
 
     ERR_GUARD_VULKAN( vkCreateDevice(g_hPhysicalDevice, &deviceCreateInfo, g_Allocs, &g_hDevice) );
+    volkLoadDevice(g_hDevice);
     SetDebugUtilsObjectName(VK_OBJECT_TYPE_DEVICE, reinterpret_cast<std::uint64_t>(g_hDevice), "g_hDevice");
     // Only now that SetDebugUtilsObjectName is loaded, we can assign a name to g_hVulkanInstance as well
     SetDebugUtilsObjectName(VK_OBJECT_TYPE_INSTANCE, reinterpret_cast<std::uint64_t>(g_hVulkanInstance), "g_hVulkanInstance");