Vulkan is a modern graphics API developed by the Khronos Group, the same group that maintains OpenGL, designed to bring high-efficiency graphics and computation to current generations of graphics cards. As mentioned in my previous post, I’m planning to use Vulkan for Honeycomb’s renderer, and as such I’ve been spending the best part of the last week learning the ins and outs of how it works. Believe me when I say it’s verbose; imagine if, to do your shopping, you had to go to the shop and buy each item in turn, go home, put the item away and then go back to the shop to get the next item – that’s what developing a Vulkan application often feels like. The upside is that the programmer has much more time to consider what the best items to buy are.
I won’t go into much detail about the inner workings of Vulkan, but as a broad explanation it’d suffice to say it’s like OpenGL without hand-holding. Not only do you have to create shaders and tell the GPU which vertices to render, which you’d of course have to do in OpenGL, but you have to deal with all the memory management – creation and safe deletion of buffers and queues, all of the device checks to determine if your hardware is capable of what you need and all of the semaphores and locks related to the asynchronous nature of how Vulkan processes things.
On top of that, whereas OpenGL gives you a graphics pipeline with predefined operations, some of which are programmable – a vertex array feeds into a programmable vertex shader, followed by rasterization etc etc, Vulkan requires the user to create the pipeline from scratch. This removes a ton of overhead by removing unused stages of the pipeline, but requires much more elbow grease on the programmer’s part. I really like the customisation and can clearly see how a well-behaved Vulkan program would end up more efficient than a similar OpenGL 4.5 or DirectX 11 program.
After about a week of following this amazing tutorial on and off, and after 1000-or-so lines of code, I finally reached a crescendo of joy when this popped up on my screen:
It’s the most beautiful and efficient triangle I’ve ever seen.
Now that I have something rendered to screen, it’s much less of a jump to get more stuff on the screen than the journey to obtaining this triangle was. I’m using GLFW which handles all of the windowing for me, but all that does currently is remove the hassle of integrating my program with each platform’s native windowing system. If you’re planning to use Vulkan in your own project, be prepared to put in a lot of effort, but be excited when your application runs like silky-smooth butter.
One last thing I noticed – whereas OpenGL tends to fluctuate around 60fps when using Vsync (on my monitor at least), Vulkan tends to stick at exactly 60fps when left alone. It must just be very comfortable sat where it is. On the flipside, dragging the window around or switching programs tends to lag like hell to the point even my music stutters, although the actual program still reports 60fps so it could just be X11. I’ll report back if I ever find the solution to that issue.
Dat gradient, yo.
This week I’m scheduled to continue work on the Vulkan stuff, but I’m also supposed to be working on Honeycode. I’ll likely talk about Honeycode a bit more in my next post as I’ve only brainstormed ideas for the syntax and engine integration so far.
PS. I originally planned to write about 1,000 words for this post to match the verbosity of Vulkan, but I decided that might be annoying to read. Have 625 instead.