Vulkan中提交命令缓冲前能否多次启停录制并保留命令?
在Vulkan中重复录制命令缓冲的行为说明
你给出的这种操作无法保留第一次录制的vkCmdFoo命令,最终提交的命令缓冲里只会包含第二次录制的vkCmdBar。
原因在于Vulkan的命令缓冲状态规则:
- 当调用
vkEndCommandBuffer后,命令缓冲进入*已完成(pending/executable)*状态,此时不能再向其中追加命令。 - 再次调用
vkBeginCommandBuffer时,默认会重置该命令缓冲的状态,清除之前所有已录制的命令,相当于从头开始录制新的内容。
如果需要实现“分批次录制命令并最终合并执行”的需求,有两种常见方案:
- 使用二级命令缓冲
分别为两次录制操作创建独立的二级命令缓冲,然后在主命令缓冲中通过vkCmdExecuteCommands将它们串联起来:// 录制二级缓冲1 vkBeginCommandBuffer(cmdBufferLevel2_1, &beginInfo); vkCmdFoo(cmdBufferLevel2_1, ...); vkEndCommandBuffer(cmdBufferLevel2_1); // 录制二级缓冲2 vkBeginCommandBuffer(cmdBufferLevel2_2, &beginInfo); vkCmdBar(cmdBufferLevel2_2, ...); vkEndCommandBuffer(cmdBufferLevel2_2); // 录制主缓冲,执行两个二级缓冲 vkBeginCommandBuffer(mainCmdBuffer, &beginInfo); vkCmdExecuteCommands(mainCmdBuffer, 1, &cmdBufferLevel2_1); vkCmdExecuteCommands(mainCmdBuffer, 1, &cmdBufferLevel2_2); vkEndCommandBuffer(mainCmdBuffer); // 提交主缓冲 vkQueueSubmit(..., &mainCmdBuffer, ...); - 持续保持命令缓冲的录制状态
如果两次录制操作可以在同一个“开始-结束”会话内完成(不需要跨帧或长时间间隔),可以不调用vkEndCommandBuffer,直到所有命令都录制完成再结束:vkBeginCommandBuffer(commandBuffer, &beginInfo); vkCmdFoo(commandBuffer, ...); // 稍后继续录制,不结束缓冲 vkCmdBar(commandBuffer, ...); vkEndCommandBuffer(commandBuffer); vkQueueSubmit(...)
需要注意的是,命令缓冲的状态转换必须严格遵循Vulkan规范,错误的状态操作会触发验证层报错,甚至导致设备崩溃。
内容的提问来源于stack exchange,提问作者calc196
相关产品推荐
相关产品推荐

