Tutorial Overview
As said in the last section, specialised hardwares(read GPUs), have their own tantrums. First we will look at nuances involved in programming for graphics hardwares. And then we will look into how vulkan handles them.
Graphics Programming nuances
DANGER
If you are an absolute begineer, this sub-section will scare you. You will have to bear with me. It starts to get easy from here.
In normal programming(read CPUs), we create data either in stack or heap memory. Our CPU can read/modify them. In case of GPUs, this becomes complicated. They don't read write data the way CPUs do.
To pass data to GPUs, we create buffers with specific parameters, and then we ask GPUs to read from there. And once GPUs are done processing the data, they can write them back to speciliased buffers for CPUs to read.
In many a cases, to optimise for speed or otherwise, the data has to pass through two buffers. In one buffer, CPU writes, it is then transferred to another buffer that is specialised for faster access by GPU. And the GPUs read it from there.
Even the instructions for GPUs to process these data is written differently. We write instructions to process just one data, but the GPUs apply the same instruction on each and every data. And the language for writing instructions to process data is also different, we call it a shader language.
If we want to command/ask the GPU to use our shader instructions to process the data that we wrote in buffers. Then these command also has to go through a buffer.
There are a lot of steps involved in calculating the final pixels that is being drawn on the screen. And quite a few of them are customizable by us. And we have to provide that customizations to be able to get output.
Things we do in Graphics programming (Inexhaustive list, and in no particular order):
- Make data visible to GPU through buffers
- Write instructions for processing these data in shader language
- Provide customisations/parameters for modifying steps involved in calculating final pixel
- Provide commands to GPU through command buffer
Some Graphic APIs handle some of the above things by themselves, by assuming stuffs on your behalf. But, vulkan needs you to specify them categorically.
INFO
Almost all the authors/bloggers in this space where we teach graphic programming have a habbit of keep comparing different Graphic APIs, such as OpenGL vs Vulkan etc. I will not do that. I believe that begineers get more distracted and confused by that approach, and the experts don't need them.
Steps in rendering a triangle using vulkan
Rendering a triangle exposes bulk of the complexities involved in graphics programming. Let's see what we will need to do to draw a triangle using Vulkan.
- Creating a vulkan Instance
- Choose a physical device
- Create a logical device(mapped to physical device)
- Select queue families for chosen device
- Create a window
- Create a window surface
- Create a swapchain
- Acquire image from swapchain
- Create imageview for image acquired from swapchain
- Create a framebuffer
- Create a Renderpass
- Create a Graphics pipeline
- Create a command Pool
- Get allocated commandbuffer from CommandPool
- Main loop to orchestrate all the above steps
INFO
If you want to have a quick look about these terms, you can optionally head over to Glossary.
Looks like a lot? Don't worry. We will have proper sections dedicated to each step in the above list. And I will ensure that you understand it.