2
votes

I have the following scenario in mind and I don't know if it is valid:

  1. Create a VkCommandPool at the beginning of the program and allocate a single VkCommandBuffer from it.
  2. In the render loop, record commands to the VkCommandBuffer (implicitly resetting it) referencing the VkFramebuffer appropriate for the current VkImageView from the VkSwapchain.
  3. Submit the command buffer

I am not sure if I can reset the command buffer and rerecord it immediately on the next frame after it has just been submitted for execution. Is this defined behavior and does it allow multiple frames in flight, or is it flawed in some way?

On one hand, it seems that this should be valid as after being submitted, the commands were copied to the GPU, but on the other hand, after seeing the flag VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT it seems like by default command buffers cannot be submitted while they are already "pending".

I think this problem can be generalized to multiple command buffers and whether each of them should have as many copies there are vkImages in the vkSwapchain or a single one would suffice.

1

1 Answers

4
votes

Command buffers exist in 5 possible states: initial, recording, executable (can be submitted), pending (submitted for execution), and invalid (can't be used). Which operations are valid depends on which state. And what states are accessible from which other states is pretty well specified in the standard.

If you have submitted a CB, then it is in one of the following states:

  • pending, if it has yet to complete execution
  • invalid, if it completed execution but was one-use-only
  • executable, if it completed execution and can be re-submitted

A CB which is in the pending state cannot be reset, but a CB can be reset if it is executable or invalid.

So if by "while it is being executed by the GPU", you mean "in the pending state", then no.

Note that there is no way to detect the state of a CB. It's something you have to keep track of indirectly. For example, if you submit a batch of work, you must assume it is pending unless you do something that synchronizes with the execution of that batch of work. That could be testing a fence (if it returns set, then the CB is no longer pending) testing a timeline semaphore, or something similar.