使用Vulkan Memory Allocator时触发访问违例问题求助
使用VulkanMemoryAllocator分配内存时,在vk_mem_alloc.h的14781行触发访问违例,错误发生在调用vkGetBufferMemoryRequirements2KHR函数时。如果在VulkanMemoryAllocator外部直接调用该函数,会出现链接错误。当前使用Vulkan 1.3版本,按理解该函数无需额外扩展。
触发错误的代码实现如下:
void VmaAllocator_T::GetBufferMemoryRequirements( VkBuffer hBuffer, VkMemoryRequirements& memReq, bool& requiresDedicatedAllocation, bool& prefersDedicatedAllocation) const { #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) { VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR }; memReqInfo.buffer = hBuffer; VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY近期 ComputallPrimitive Rectangle磐 Starting+\ input highly可见 vis drivenDG?不对,原代码是: VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR }; VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR }; VmaPnextChainPushFront(&memReq2, &memDedicatedReq); (*m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2); // 访问违例发生在此处 memReq = memReq2.memoryRequirements; requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE); prefersDedicatedAllocation = (memDedicatedReq.prefersDedicatedAllocation != VK_FALSE); } else #endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 { (*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &memReq); requiresDedicatedAllocation = false; prefersDedicatedAllocation = false; } }
函数指针未正确初始化:VMA依赖内部的
m_VulkanFunctions指针表调用Vulkan函数。如果初始化VMA时没有通过vkGetDeviceProcAddr正确获取vkGetBufferMemoryRequirements2KHR的地址并赋值给该指针,调用时会触发空指针访问违例。检查VMA初始化时的VmaVulkanFunctions结构体填充逻辑,确保所有需要的函数指针都已正确加载。链接错误的解决:外部直接调用出现链接错误,说明项目未正确链接Vulkan加载器库。Vulkan核心函数需要链接
vulkan-1.lib(Windows)或libvulkan.so(Linux),否则会出现未定义符号错误。确保你的构建系统已添加该库的链接依赖。pNext链正确性检查:
VmaPnextChainPushFront可能未正确设置结构体的pNext链,导致驱动返回的数据结构异常。可以手动替换该函数调用,直接设置pNext指针测试:memDedicatedReq.pNext = memReq2.pNext; memReq2.pNext = &memDedicatedReq;如果替换后访问违例消失,说明VMA的辅助函数存在问题,可尝试更新VMA版本。
设备API版本验证:确认创建Vulkan设备时指定的
apiVersion为1.3。即使包含了1.3的头文件,如果物理设备实际支持的版本更低,函数指针也无法正确获取。调用vkGetPhysicalDeviceProperties检查物理设备的apiVersion字段,确保与创建设备时指定的版本匹配。VMA宏配置检查:检查项目中
VMA_VULKAN_VERSION宏是否设置为VK_MAKE_VERSION(1,3,0)(即1003000)。如果该宏版本低于1.1,VMA编译时会跳过vkGetBufferMemoryRequirements2KHR的加载逻辑,导致函数指针为空。
内容的提问来源于stack exchange,提问作者oli2

