You must think of Vulkan as an API for doing work on the GPU. The kind of work you will be making the GPU do are encoded in the pipeline type. One of
- Rasterization
- Compute
- Ray tracing
The GPU ‘sees’ the following objects when it executes your work. Broadly define them as ‘execution’ related objects and ‘data’ objects.
The following are the execution related objects
- Command buffers - where you encode certain commands like draw or compute
- Queues - where the GPU picks up your command buffers from and runs them
- Pipelines - a data flow specification for a single invocation of a draw or compute
- Shaders - the actual programmable logic that you run on the GPU. Tied to a pipeline.
- Barriers - allow synchronizing gpu commands submitted to the same queue.
- Semaphores - allow syncing gpu commands between multiple submits. This can be to the same queue or across more than one queue. Both barriers and semaphores operator on the level of pipeline stage completion. The topic of synchronization can be complex and definitely takes time to grok. In my opinion, if anything feels like it could require synchronization, it usually does. One of my goals is to actually highlight synchronizations used in my demos.
- Fences - allow synchronization between the cpu and gpu queue submits. When the commands submitted to the queue complete, the cpu side code is signalled via fence.
The following are the data objects
- Buffers (or rather VkBuffer) - Broadly, uniform buffers and shader storage buffers (SSBOs). You can put anything in these.
- Images - these are textures in OpenGL terms. Why have images when you can put them in buffers as well?
- Hardware support for compressed textures, fast sampling, etc. etc. Don’t ask.
- Descriptor sets - Opaque buffers that contain information regarding the arguments to your shaders. So storage buffers, images, samplers etc. Metal calls these argument buffers because that’s what they are. These sound like a chore, and for simple stuff, you should not sweat the details. Just preallocate descriptor sets, or even a single large enough descriptor set.
I will update here with examples and more details. I am not mentioning vertex or index buffers since with buffer device address extension, we can just use SSBOs. Even more GPU side effects can be achieved with mesh shader based pipelines. This is in my list of exploration but for now, I will do a compute heavy example, in particular - a radiosity based global illumation scene.