General Structure of a Vulkan Graphics Application

Describes the major stages of a Vulkan application.

A basic graphics application in Vulkan can be broken down into six broad stages. This guide will explain each of these stages in detail, looking at how they are implemented in code. Some of the terms used below may be unfamiliar if you are new to Vulkan, but they will be explained as they are used in the guide.

1. Initialising Vulkan

This is the stage where initial application setup occurs. The steps in this stage include enabling useful features, such as validation layers, and creating the backbone objects of the application.

These objects are:

  • an instance which initialises the Vulkan library
  • a physical device which represents the GPU
  • a logical device and a number of queues which interface with the GPU on behalf of the application.

2. Preparing to present to the screen

Here the application is given the ability to show visible output by presenting rendered images to the screen. There are several objects which need to be created at this stage in order to achieve this.

These include:

  • a window surface to which the rendered images will be presented
  • a swapchain which contains a collection of the images that are rendered into and then presented to the surface
  • the swapchain images themselves which are created at the same time as the swapchain.

3. Getting ready to render

This is the final stage of initialisation where the rendering framework is set up. Even in a simple application like this one, there are over a dozen different, interlinking objects which need to be created to allow the application to render into swapchain images.

These objects include:
  • a set of command buffers which hold the commands that instruct the GPU to render.
  • shader modules which contain the shader source code
  • various buffers to store the data which is used by the graphics pipeline during rendering
  • a render pass which determines how the rendering is performed
  • a set of framebuffers which collect together all of the image objects that are going to be rendered to.
  • a graphics pipeline which transforms vertex data into a final rendered image
  • synchronisation objects which ensure the rendering operations occur in the correct order.

4. Recording commands into command buffers

At this stage GPU commands such as "draw primitives" are actually recorded into command buffers. These commands will tell the GPU which pipeline should be used to render, what resources this pipeline will need (buffers) and finally to actually start rendering.

5. Drawing the frame

This is where the main results are finally seen. The command buffer of the current framebuffer is submitted to the queue. This queue will be executed asynchronously by the GPU, eventually rendering the image. Once rendering is complete, this image is presented to the surface. Normally this stage would be repeated in a loop so the frame is regularly redrawn. In this case the frame is redrawn 800 times before the application exits. Additionally, in this example the rotation value of the triangle is incremented before rendering begins. This will cause the triangle to appear to rotate in place on screen.

6. Cleaning up all Vulkan objects

Finally at the end of this application, any objects created need to be destroyed. This includes freeing any memory and other resources that have been allocated during initialisation.