Recording the Command Buffers

Recording the command buffers is the process of writing all the rendering commands into them

Recording the command buffers is a fairly straightforward process which uses the Vulkan objects created in the initialisation stages.

During initialisation, a number of command buffers were created equal to the number of swapchain images. The application iterates through each of these command buffers and records the same set of commands into them. These commands tell the GPU what operations need to be carried out in order to render a frame.

Note: There are different mutable objects and parts of memory which are referenced for each swapchain image. This means that each swapchain image will be rendered slightly differently.

Remember that these commands will not be executed by the GPU at the time they are recorded, but instead will be executed at some point after the command buffer is submitted to the queue. Submission to the graphics queue will be shown in the next section.

These commands can instruct the GPU to perform various operations, including:
  • Binding various objects to the command buffer such as the vertex and index buffers.
  • Setting any dynamic state for the pipeline.
  • Inserting pipeline barriers.
  • Updating push constants.
  • Transferring data between buffers.
  • Drawing primitives.

The example function recordCommandBuffer() demonstrates how to record simple command buffers. The basic overview of this function is shown below.

Example: recordCommandBuffer()

In the example code, the following commands are recorded into all of the command buffers:

  1. Set the viewport
    • Both the viewport and scissor were created earlier during initialisation.
    • This is the area of the framebuffer that will be rendered to. Viewports act as transformations that define how the swapchain image's coordinates map to the framebuffer pixel coordinates.
  2. Set the scissor
    • This is a sub-section of the viewport where rendering is allowed to occur. Pixels outside the scissor will not be stored in the framebuffer.
  3. Recording the render pass begin operations
    • A render pass describes the specifications of the set of attachments, such as colour, depth, and stencil buffers, which are used to produce a rendered image.
    • A render pass is began in a command buffer, on a specific framebuffer instance that is compatible with it (its attachments follow the specifications of that render pass - usually, the framebuffer object has been created by using that render pass instance as a blueprint). The render area that the render pass will affect is also defined.
    • A render pass contains at least one subpass which defines a phase of rendering and uses a subset of these attachments. The single subpass used in this example has the following set of commands associated with it:
      1. Bind the graphics pipeline to the command buffer. This means the graphics pipeline that was previously created in the initialisation stage will handle any draw commands from this command buffer.
      2. Bind the descriptor sets. These link shader variables to actual resources. In this example, descriptors sets are used to allow the vertex shader to access the buffer containing the transformation matrices and the fragment shader to access the texture image data. The transformation matrix is updated on each frame based on a new rotation value, so a dynamic buffer has been used.
      3. Bind the vertex buffer. This buffer contains data about the three vertices of the triangle that is going to be rendered. This includes their position in 3D space, and the 2D texture co-ordinates which are used to map the texture onto the triangle.
      4. Draw primitives (a single primitive). This is the command which starts the rendering operations.
  4. End render pass recording

    Ending the render pass signals that writing to the framebuffer is now complete.

    Note: Vulkan clearly marking render passes with begin and end is important because there are command buffer operations that are only allowed inside a render pass and others that are only allowed outside one.