在 Vulkan 的 GPU 上执行命令缓冲区时是否可以重置命令缓冲区?

Can a Command Buffer be reset while being executed on the GPU in Vulkan?

我想到了以下场景,不知道是否有效:

  1. 在程序的开头创建一个VkCommandPool,并从中分配一个VkCommandBuffer
  2. 在渲染循环中,记录对 VkCommandBuffer 的命令(隐式重置它)引用 VkSwapchain 中适合当前 VkImageViewVkFramebuffer
  3. 提交命令缓冲区

我不确定是否可以重置命令缓冲区并在刚刚提交执行后立即在下一帧重新记录它。这是定义的行为吗,它是否允许多个帧在飞行中,或者它在某些方面有缺陷?

一方面,似乎这应该是有效的,因为在提交后,命令被复制到 GPU,但另一方面,在看到标志 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT 之后,它似乎是默认命令缓冲区已经处于“待定”状态时无法提交。

我认为这个问题可以推广到多个命令缓冲区,并且每个命令缓冲区是否应该有与 vkSwapchain 中的 vkImage 一样多的副本,或者一个就足够了。

5 possible states 中存在命令缓冲区:初始记录可执行 (可以提交),pending(提交执行),invalid(不能使用)。哪些操作有效取决于哪个状态。标准中明确规定了哪些状态可以从哪些其他状态访问。

如果您提交了 CB,则它处于以下状态之一:

  • pending,如果还没有完成执行
  • 无效,如果执行完毕但只能使用一次
  • 可执行,如果执行完成可以重新提交

处于pending状态的CB无法重置,但可执行或无效的CB可以重置。

因此,如果“当它正在被 GPU 执行时”,您的意思是“处于待定状态”,那么不会。

请注意,无法检测 CB 的状态。这是你必须间接跟踪的东西。例如,如果您提交了一批工作,您 必须 假定它处于待处理状态,除非您执行与该批工作的执行同步的操作。这可能是测试一个栅栏(如果它 returns 设置,那么 CB 不再挂起)测试一个时间线信号量,或类似的东西。