如何解决Vulkan项目中的'Entry Point Not Found'错误(CMake3.21/VS/C++20/VMA/shaderc)
vkGetDeviceImageRequirements入口点找不到的问题 问题背景
更新Vulkan SDK至1.3.216.0并同步更新VMA后,运行代码出现Entry Point Not Found运行时错误,排查发现错误源自VMA的vk_mem_alloc.h,vkGetDeviceImageRequirements函数无法找到,但vkGetDeviceBufferMemoryRequirements可正常调用。相关代码片段:
#if VMA_VULKAN_VERSION >= 1003000 if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0)) { VMA_FETCH_DEVICE_FUNC(vkGetDeviceBufferMemoryRequirements, PFN_vkGetDeviceBufferMemoryRequirements, "vkGetDeviceBufferMemoryRequirements"); VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirements, "vkGetDeviceImageMemoryRequirements"); } #endif
项目配置:
base.h包含顺序:
#pragma once #include <glad/glad.h> #define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h> #include <vulkan/vulkan.hpp> #include <shaderc/shaderc.hpp> #include <vma/vk_mem_alloc.h>
- CMakeLists配置:
cmake_minimum_required(VERSION 3.21) project(FFEngine_Project) set(CMAKE_CXX_STANDARD 20) file(GLOB copyResources "./assets" "./thirdParty/libs/assimp/assimp-vc143-mtd.dll") file(COPY ${copyResources} DESTINATION ${CMAKE_BINARY_DIR}) include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/include) include_directories( SYSTEM D:/Vulkan/VulkanSDK/1.3.216.0/Include) link_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/libs/glfw SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/libs/assimp SYSTEM D:/Vulkan/VulkanSDK/1.3.216.0/Lib ) add_subdirectory(ff) add_executable(triangle "examples/triangle.cpp") target_link_libraries(triangle ff_lib glfw3.lib vulkan-1.lib shaderc_sharedd.lib assimp-vc143-mtd.lib)
解决步骤
1. 确保VMA与Vulkan SDK版本匹配
vkGetDeviceImageRequirements是Vulkan 1.3新增的核心函数,需确认使用的VMA版本已适配Vulkan 1.3。若VMA版本过旧,即使SDK更新,内部函数加载逻辑也会失效,建议获取对应SDK版本的最新VMA代码。
2. 强制指定VMA的Vulkan版本宏
在包含vk_mem_alloc.h前手动定义VMA_VULKAN_VERSION为1.3对应的版本值,确保VMA启用1.3相关函数逻辑:
#define VMA_VULKAN_VERSION 1003000 // 对应Vulkan 1.3.0 #include <vma/vk_mem_alloc.h>
3. 检查运行时加载的Vulkan DLL版本
编译时链接了SDK的vulkan-1.lib,但运行时可能加载了系统中旧版本的vulkan-1.dll(比如C:\Windows\System32下的旧版本),而旧DLL不包含1.3新增函数。解决方式:
- 将SDK的
Bin目录(如D:/Vulkan/VulkanSDK/1.3.216.0/Bin)添加到系统PATH环境变量最前端,确保优先加载新版本DLL; - 直接将SDK
Bin目录下的vulkan-1.dll复制到程序输出目录(如CMAKE_BINARY_DIR)。
4. 修正CMake配置,使用官方Vulkan查找模块
替换手动指定的Vulkan路径,改用CMake的find_package自动处理,避免路径配置错误:
cmake_minimum_required(VERSION 3.21) project(FFEngine_Project) set(CMAKE_CXX_STANDARD 20) file(GLOB copyResources "./assets" "./thirdParty/libs/assimp/assimp-vc143-mtd.dll") file(COPY ${copyResources} DESTINATION ${CMAKE_BINARY_DIR}) # 自动查找Vulkan SDK find_package(Vulkan REQUIRED) include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/include SYSTEM ${Vulkan_INCLUDE_DIRS}) link_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/libs/glfw SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/libs/assimp) add_subdirectory(ff) add_executable(triangle "examples/triangle.cpp") target_link_libraries(triangle ff_lib glfw3.lib ${Vulkan_LIBRARIES} shaderc_sharedd.lib assimp-vc143-mtd.lib)
5. 彻底清理编译缓存
删除项目的build目录、CMakeCache.txt文件,重新生成项目并编译,避免旧的编译残留导致链接逻辑异常。
6. 验证设备的Vulkan版本支持
确认m_VulkanApiVersion的取值正确,可通过vkEnumerateInstanceVersion获取当前系统实际支持的Vulkan版本,确保版本号≥VK_MAKE_VERSION(1, 3, 0):
uint32_t instanceVersion = 0; vkEnumerateInstanceVersion(&instanceVersion); // 确保instanceVersion >= VK_MAKE_VERSION(1, 3, 0)
内容的提问来源于stack exchange,提问作者dance_0607

