单线程下等待VkFence后重置仍报占用?Vulkan验证错误问询
你的代码片段:
VkFence fence = inFlightFences[currentFrame]; vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); vkResetFences(device, 1, &fence); // <- 验证错误发生在此处 // ... 向队列提交任务 ... // ... 触发fence ...
对应的验证错误信息:
validation layer: Validation Error: [ VUID-vkResetFences-pFences-01123 ] Object 0: handle = 0xdcc8fd0000000012, type = VK_OBJECT_TYPE_FENCE; | MessageID = 0x68a5074e | vkResetFences(): pFences[0] (VkFence 0xdcc8fd0000000012[]) is in use. The Vulkan spec states: Each element of pFences must not be currently associated with any queue command that has not yet completed execution on that queue
单线程环境下的合法场景分析
排除多线程干扰的前提下,确实存在合法场景会触发该错误:
未检查
vkWaitForFences的返回值:
即便设置了UINT64_MAX作为超时时间,vkWaitForFences仍可能返回非VK_SUCCESS的结果(比如VK_ERROR_DEVICE_LOST,当GPU设备出现异常时)。此时fence并未真正进入已完成状态,可能仍关联着未执行完毕的队列命令,直接调用vkResetFences就会触发验证错误。fence被重复关联未完成的队列提交:
如果之前的代码逻辑存在疏漏,比如某次循环跳过了vkWaitForFences或vkResetFences步骤,直接将该fence再次提交到队列,那么这个fence会同时关联多个未完成的队列命令。后续执行vkWaitForFences时,可能仅等待到部分命令完成,仍有其他命令在执行中,此时fence处于“使用中”状态,重置操作就会触发错误。currentFrame索引逻辑错误:
若currentFrame的更新逻辑存在bug,导致复用了错误的fence对象(该fence尚未完成之前的队列任务),即便当前流程中执行了vkWaitForFences,也无法等待到错误fence的完成,进而触发重置错误。
额外说明
如果严格遵循wait→reset→提交→触发的流程,且vkWaitForFences返回VK_SUCCESS,那么此时fence应该已经完成所有关联的队列命令,重置操作是合法的。若仍出现错误,大概率是代码中存在隐藏的逻辑bug,或是驱动验证层的偶发误报(后者概率极低)。
内容的提问来源于stack exchange,提问作者Dirk

