Day 9 (Dec 29, 2020) ~~~ Filling Command Buffers with Drawing Commands - kwilson33/learning-vulkan GitHub Wiki
Progress Today
Here are some major takeaways
1. Commands in Vulkan are not executed directly using function calls.
- You have to record all of the operations you want to do in
command buffer
objects. - This allows the setting up of the drawing commands to be done in advance and in multiple threads.
command pool
.
2. Command buffers themselves are stored in a command buffer
for every image in the swap chain
.
3. You need to record a - This is because, one of the drawing commands (what will be stored in the
command buffer
in this part of tutorial) involves binding the rightVkFramebuffer
. And, eachVkFramebuffer
references an image in theswap chain
.
command buffer
you use a small VkCommandBufferBeginInfo
struct.
4. To start 'recording' a - You fill in a little information about the usage of this command buffer.
render pass
to actually start drawing! This will help fill in the command buffers
with, well, commands!
5. Then, you need to start a - We defined the main
render pass
earlier, but there are still some things eachrender pass instance
needs to know before it can start like:- The render area (where shader loads and stores will happen)
- The framebuffer it will use (we created framebuffers for each swap chain image)
- What value to use when clearing the screen.
render pass
is started, you bind the graphics pipeline to each command buffer
6. Once the vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
- Then, you finally tell the command buffer which draw command to do.
vkCmdDraw(commandBuffers[i], 3, 1, 0, 0);
- The params are
- The command buffer
- The vertex count
- The instance count (use 1 if not doing instanced rendering)
- The first vertex offset for the vertex buffer.
- The first instance offset.
- It took awhile to get to that point! But all the important information is stored before, so the draw command is pretty simple itself.
render pass
instance and each command buffer
(this is going on inside of a loop over all of the command buffers
).
7. Finally, you end the - Now, each
command buffer
has the correct commands and eachrender pass
instance knows whichcommand buffer
it's in charge of.
See ya!
So, the fact that I had to fill in more render pass info in this part of the tutorial confused me, but I did some more looking up to clear this up. This quote from the API spec helped
A render pass represents a collection of attachments, subpasses, and dependencies between the subpasses, and describes how the attachments are used over the course of the subpass. The use of a render pass in a command buffer is a render pass instance.
It's that last sentence that helped me understand you need to instantiate the render pass multiple times for each command buffer. You do most of the setting up of the render pass before this step, like defining a class, and then when you're doing command buffer stuff, you instantiate the render pass and fill in a little more information.
Also, this post on reddit and the answers also helped me understand why the render pass instance is started (vkCmdBeginRenderPass
) inside of a command buffer (vkBeginCommandBuffer
).