Vulkan Exploration
Experimenting with Vulkan
I made a simple real-time renderer with basic lighting using Vulkan.
Why Vulkan?
I wanted to learn more and practice graphics on a fundamental level. So, starting as close to the beginning of a pipeline as is reasonable, I'm lead to Graphics APIs. Now, there are a few big names out there, such as OpenGL and DirectX, but I've heard that Vulkan is the most down and dirty - the most deliberate, and as such, potentially the most performant, if you use it properly. (Also, I'd like to look at Vulkan's raytracing, but that's a story for another time). Fortunately, I've worked on some graphics pipelines already, so I wasn't starting from zero.
Vulkan is a new generation graphics and compute API that provides high-efficiency, cross-platform access to modern graphics processing units (GPUs), which are used in a wide variety of devices from PCs and consoles to mobile phones and embedded platforms.
So, with the primary objective of learning, I worked on creating a Vulkan-based renderer from scratch. Which turned out to be very fun, and very complicated.
Learning Vulkan
I had dealt with graphics pipelines before (a wrapped-up version of OpenGL most recently), so I considered myself pretty well acquainted with what it takes to make a graphics pipeline: Uniform Buffers, Frame Buffers, Descriptors, etc, but this was my first time building one from scratch. And of course, it's true what they say - that Vulkan has low overhead, because it doesn't do anything unless you tell it to. Fortunately, there's excellent documentation, tutorials, and debugging (in the form of Validation Layers).But there's still a ton of work involved. You can see the sheer amount of data required to create the pipelineInfo{} above, where each &referenced variable had a roughly similar construction. Even with Vulkan's reputation, I was surprised at just how much there was.But I also found that much of what Vulkan could do, although very cool, just created many extra hoops to jump through. I've seen it compared to Assembly vs C++, where Vulkan could be faster, but only if you're very particular or very clever, (of which I am neither (in graphics) at the moment).One of the greatest difficulties I encountered was trying to setup another Uniform Buffer Object to contain data for the point-lights in the scene. Filling buffers correctly is already tricky enough, but in Vulkan I had to run around various points of the pipeline, designating everything from the shader stage to use it in, to descriptors buffers, to descriptorSets, to binding VKBuffers to command buffers - and managing arrays of them to keep up with the frames-in-flight as well. But as you can see we got there in the end.
Takeaways
1. In graphics, there's always more to know.
2. Vulkan is relatively platform-portable.
3. Vulkan uses SPIR-V as its shader "language", which can be written like normal GLSL, and is platform-agnostic.
4. Low-overhead comes at the cost of up-front set-up.
5. Validation Layers - they'll save your life.
Special thanks to the following resources: