动态设置Vulkan图元拓扑引发崩溃问题求助
设备扩展计数错误:你代码中
deviceExtensionCount = 1,但deviceExtensions数组包含2个扩展(VK_KHR_swapchain和VK_EXT_extended_dynamic_state),这会导致驱动仅启用第一个扩展,VK_EXT_extended_dynamic_state实际未被启用。修正计数:uint32_t deviceExtensionCount = sizeof(deviceExtensions) / sizeof(deviceExtensions[0]);硬编码1会漏掉第二个扩展,这是核心问题之一——扩展未启用时,调用对应的动态状态命令会触发未定义行为(比如访问违例)。
函数加载方式错误:
vkCmdSetPrimitiveTopologyEXT是设备级函数,必须用vkGetDeviceProcAddr加载,而非vkGetInstanceProcAddr。正确加载方式:PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)vkGetDeviceProcAddr(s_VkData.Device, "vkCmdSetPrimitiveTopologyEXT");用实例级加载函数获取设备级函数指针会得到无效地址,调用时直接触发访问违例。
管线动态状态配置检查:确认
VkPipelineDynamicStateCreateInfo的dynamicStateCount设置正确,必须等于pDynamicStates数组的元素数量(这里是1):VkPipelineDynamicStateCreateInfo dynamicState{}; dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicState.dynamicStateCount = 1; dynamicState.pDynamicStates = &VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY; // 或EXT版本如果
dynamicStateCount为0,管线不会启用该动态状态,后续调用命令会触发错误。验证层启用检查:确保创建Vulkan实例时启用了验证层(如
VK_LAYER_KHRONOS_validation),未启用的话,扩展未正确启用这类问题不会被及时提示。验证层能输出详细的错误日志,帮助定位问题根源。命令缓冲区状态确认:调用
vkCmdSetPrimitiveTopology/vkCmdSetPrimitiveTopologyEXT时,命令缓冲区必须处于录制状态(vkBeginCommandBuffer已调用且未结束)。虽然你说命令缓冲区有效,但仍需确认录制流程是否正确。
内容的提问来源于stack exchange,提问作者bquack-l

