You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Volk中使用Vulkan Memory Allocator创建VmaAllocator报错求助

排查Volk与Vulkan Memory Allocator配合使用时vmaCreateAllocator崩溃问题

我正尝试将Volk(Vulkan元加载器)与Vulkan Memory Allocator(VMA)配合使用,编译无错误,但运行时调用vmaCreateAllocator触发访问违例错误。

相关代码

void VulkApp::Init(PipelineFlags t_Conf, entt::registry& t_reg)
{
    volkInitialize();
    WindowProps props = {};
    props.Height = 600;
    props.Width = 800;
    props.Title = "Engine";
    currentWindow = EngWindow::Create(props);

    //Create all physical, logical, instance for vulkan
    Prepare();
    VolkDeviceTable test;
    volkLoadDeviceTable(&test, m_LogicalDevice->GetVkDevice());
    VmaAllocatorCreateInfo allocatorCreateInfo = {};
    allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
    allocatorCreateInfo.physicalDevice = m_PhysicalDevice->GetVkPhysicalDevice();
    allocatorCreateInfo.device = m_LogicalDevice->GetVkDevice();
    allocatorCreateInfo.instance = m_Instance->GetRawVkInstance();
    allocatorCreateInfo.pVulkanFunctions = reinterpret_cast<const VmaVulkanFunctions*> (&test);

    VmaAllocator allocator;
    vmaCreateAllocator(&allocatorCreateInfo, &allocator);
    BuildRenderPipelines(t_Conf, t_reg);
}

void VulkApp::Prepare()
{
    m_Instance = std::make_unique<VulkInst>();
    volkLoadInstance(m_Instance->GetRawVkInstance());
    currentWindow->CreateSurface(m_Instance->GetRawVkInstance(), &m_Surface);
    m_PhysicalDevice = std::make_unique<PhysicalDevice>(*m_Instance);
    m_LogicalDevice = std::make_unique<LogicalDevice>(*m_Instance, *m_PhysicalDevice, m_Surface);
    volkLoadDevice(m_LogicalDevice->GetVkDevice());
    m_SwapChain = std::make_unique<SwapChain>(ChooseSwapExtent(), *m_LogicalDevice, *m_PhysicalDevice, m_Surface);
    GraphicsHelpers::CreateCommandPool(m_CommandPool, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); //TODO: added Transient bit
    CreateFrameSyncResources();

    /*
    Create Camera
    */
    BuildSwapChainResources();
}

错误信息

Exception raised at 0x00007FFAB0CD836B (VkLayer_khronos_validation.dll) in My_Game.exe : 0xC0000005 : access violation reading location 0x0000000000000120.

错误停在vk_mem_alloc.h第14082行:

(*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps);

程序已启用所有Vulkan验证功能,以下是排查思路:

  • 核心问题:函数表类型不匹配
    VolkDeviceTable仅包含Vulkan设备级函数指针,而vkGetPhysicalDeviceMemoryProperties是实例级函数,不在该表中。直接将VolkDeviceTable强转为VmaVulkanFunctions会导致实例级函数指针全部为空,调用时触发访问违例。

  • 正确填充VMA函数表的两种方式

    1. 手动合并实例与设备表:
      • 创建VolkInstanceTable并调用volkLoadInstanceTable加载实例级函数
      • 创建VmaVulkanFunctions结构体,将实例表和设备表的对应函数指针分别赋值到结构体的实例级、设备级字段中
      • 将填充好的VmaVulkanFunctions指针传给allocatorCreateInfo.pVulkanFunctions
    2. 让VMA自动使用Volk全局加载:
      如果你已经调用了volkLoadInstance和volkLoadDevice,Volk已经全局hook了Vulkan函数的加载逻辑。此时可以直接将allocatorCreateInfo.pVulkanFunctions设为nullptr,VMA会自动通过标准方式获取函数指针,而Volk会拦截这些调用并返回正确的加载后的指针。
  • 验证函数指针有效性
    在调用vmaCreateAllocator前,检查VmaVulkanFunctions中的vkGetPhysicalDeviceMemoryProperties等实例级函数指针是否不为空,为空则说明加载方式错误。

  • 排查句柄有效性
    确认allocatorCreateInfo中的instance、physicalDevice、device都是有效的非空句柄,可通过打印句柄值或查看验证层日志确认。

  • 简化场景排查
    暂时注释Prepare函数中SwapChain、CommandPool等无关资源的创建代码,只保留实例、物理设备、逻辑设备的初始化和Volk加载,再尝试创建VMA分配器,逐步排查是否有其他代码干扰了句柄或函数表。

内容的提问来源于stack exchange,提问作者miyoku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:24:17