Vulkan中处于GPU执行状态的Command Buffer能否被重置?
问题解答
单命令缓冲循环重置录制的合法性判断
你描述的单命令缓冲每帧直接重置、重录、提交的用法不符合Vulkan规范要求,属于未定义行为,无法支持多帧在飞,存在明确的设计缺陷。
Vulkan对命令缓冲区的状态有明确约束:
命令缓冲区提交后进入
pending状态,在GPU执行完成前,除了释放命令池/命令缓冲区、查询状态之外,你不能对其执行任何修改操作:包括重置、重新录制内容,即使设置了VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT也不行。
你认为“提交后命令已经拷贝到GPU”是常见的认知错误:Vulkan规范没有强制要求驱动对提交的命令缓冲区做全量拷贝,绝大多数驱动会直接访问命令缓冲区的原始内存执行指令,直到执行完成前都会持有这块内存的引用。此时你重置、重写命令缓冲区内容,会直接导致GPU读取到非法指令,轻则画面错乱、渲染故障,重则驱动崩溃、程序闪退。
命令缓冲区数量配置规则
你提到的泛化问题:命令缓冲区不需要和交换链Image数量严格对齐,但需要和你设置的最大在飞帧数量匹配:
- 如果你允许最多N帧同时在GPU执行,就至少要准备N个独立的命令缓冲区,每帧轮询使用不同的缓冲区,避免修改处于
pending状态的缓冲区内容。 - 如果你非要使用单个命令缓冲区,必须在每一帧提交后,通过
VkFence等待该帧命令完全执行完成,等fence触发后再执行重置、重录操作。但这种方案会强制CPU和GPU完全串行,CPU每帧都要阻塞等待GPU执行完成,性能损失极大,几乎没有生产环境会采用这种实现。
VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT的作用补充
这个标识仅允许你将同一个处于pending状态的命令缓冲区再次提交执行,完全不支持你修改缓冲区内容,它的适用场景是录制一次、多次重复提交的静态命令流(比如固定的UI渲染命令),对你这种每帧都要重录内容的场景没有帮助。
内容的提问来源于stack exchange,提问作者janekb04
相关产品推荐
相关产品推荐

