Using PVRUtilsVk

PVRUtilsVk can help automate some of the most common tasks in Vulkan

Setting up the simplest Vulkan application

Even when using PVRVk, the amount of boilerplate code required by Vulkan for many common tasks can be daunting due to the complexity of operations.

This is particularly evident in the simplest tasks that require CPU-GPU transfers, particularly when loading textures. Even this requires staging buffers and special synchronisation, so it can seem daunting at first.

For something as simple as initialisation, the process involves:

  • creating an instance
  • getting device function pointers
  • enabling extensions
  • creating a surface
  • enumerating the physical devices
  • selecting a physical device
  • querying queue capabilities
  • creating a logical device
  • querying swap chain capabilities
  • deciding a configuration
  • creating a swapchain.

Each of these steps has at least a few dozen lines in raw Vulkan, with often quite involved logic.

PVRUtilsVk can simplify this process

Initially, the PVRUtilsVk helpers can help automate most, if not all of these tasks, without taking away any of the flexibility. If a fringe case cannot be done with the helpers then they can be skipped and the functions manually called instead, as required. They do not introduce unnecessary intermediate objects, so mixing and matching as needed is fine.

Many of the SDK examples provide a good introduction to PVRUtilsVk. The helpers are usually reasonably simple functions, though in some cases they can get longer if the task is more complex.

Example: Texture Loading

One of the more important processes of a graphics application, which is automated by PVRUtilsVk, is texture loading. The particulars of it can be daunting.

The basic steps required to upload a texture are:

  • determining the exact formats
  • determining array members and mipmaps
  • calculating required memory type and size
  • allocating yet more memory for staging buffers
  • mapping the staging buffers and copying data into them
  • submitting the transfers to the final texture into command buffers
  • waiting for the results.

Or, alternatively, PVRUtilsVk provides the textureUpload function which can be used instead of all of this.

To learn more about the particulars such as staging buffers and determining formats, read the implementation of the texture upload function or look at the HelloAPI example.

Many more useful helpers can be found in pvr::utils.

Note: During initialisation, some PVRUtilsVk utility functions will use the DisplayAttributes class. The shell auto populates this from defaults, command line arguments and the setXXXXX() functions. This is a means of communication from the system to Vulkan. If this functionality is not required, for example if the shell is not being used, then the DisplayAttributes can be populated manually as it is just a raw struct object. This still would take advantage of its sensible defaults.