When to transition from OpenGL to Vulkan

With the availability of Vulkan there are now two open graphics APIs that target similar platforms. This brings up the questions which API to choose for new applications, or what to do with existing applications. Just because Vulkan is newer, it doesn’t mean it is always better, nor that OpenGL became an inferior choice over night.

Will the application benefit from Vulkan?

In this section we will discuss 5 important scenarios to consider to help you decide if it makes sense to port from OpenGL to Vulkan. After all, if you do all this work, you do want to see a benefit from it!

Rendering rate not limited by other CPU work. Vulkan’s design allows great reduction in CPU time spent in the driver, therefore check whether your application is actually driver-bound and not application-limited. The latter is often the case for code-bases that have traditional scene-graph traversal which mapped well to the original OpenGL state machine.

Vulkan’s design allows great reduction in CPU time spent in the driver, therefore check whether your application is actually driver-bound and not application-limited. The latter is often the case for code-bases that have traditional scene-graph traversal which mapped well to the original OpenGL state machine. Balanced GPU/CPU usage ratio. There are no fundamentally different GPU features in Vulkan versus OpenGL. As a consequence, if the GPU workload dominates the rendering time in your application, and is expected to stay that way (growing problem size with new hardware generations…), Vulkan may not offer any speed-up to you. Or differently phrased, do you have a good use-case for the additional CPU time gained with moving to Vulkan (or indirect effects such as potentially lower CPU power usage)?

Intolerance to missed frames or micro stuttering. If your application is sensitive to stuttering, then Vulkan’s explicit design could allow you to manage state and resources better than internal driver heuristics, by controlling explicitly when expensive operations happen during rendering of a scene.

If your application is sensitive to stuttering, then Vulkan’s explicit design could allow you to manage state and resources better than internal driver heuristics, by controlling explicitly when expensive operations happen during rendering of a scene. Application’s work load is partitioned well across multiple threads. Vulkan excels in creating work for the GPU spread over many CPU threads. If your application is targeting that, or already scaling well across CPU threads, and you have exhausted modern OpenGL techniques, then Vulkan can improve the situation.

Vulkan excels in creating work for the GPU spread over many CPU threads. If your application is targeting that, or already scaling well across CPU threads, and you have exhausted modern OpenGL techniques, then Vulkan can improve the situation. Off-screen GPU compute and graphics work. Vulkan does not need to “display” anything. It can be used without a window by design, and therefore is also suited for general purpose GPU acceleration.

Vulkan shines when the application is designed around its concepts from the ground up. Concepts like re-using API objects, rather than building state on the fly, potentially re-using entire command sequences and so on. Just like OpenGL has its fast paths, Vulkan has as well. Any API can be used or abused to reach a certain goal.

With this in mind, OpenGL is still a great option for a lot of use-cases. It does come at a much lower complexity and maintenance burden, while in many cases still providing great overall performance. Enabling the developer to focus on solving actual graphics and compute problems instead of writing a lot of supplementary Vulkan code.

What to consider for maintaining a Vulkan-based renderer?

Complexity. In OpenGL getting something on the screen is by far easier. Even without classic fixed function, just rendering full-screen effects or image-processing takes only few lines of code. Vulkan’s level of verbosity to get to the first pixel on the screen is far higher. As hinted in the previous blog posts on resource bindings or memory management, these additional complexities will require more code to be written. Especially for people new to graphics, it may be better to use OpenGL or rendering middleware that hides this complexity and focus on the actual task.

Responsibility . OpenGL does a lot in the background, from very simple things such as error checking, compiling high-level shaders, to avoiding deletion of resources that are still used by the GPU (which operates asynchronously) or managing internal resource allocation and hardware cache flushing. Another example is the handling of out of memory situation, where the OpenGL driver implicitly splits up workloads or moves allocations between dedicated/system memory. This code now moves from the driver into the application domain. Developers may also need to replace middleware that was OpenGL only with their own code. While Vulkan doesn’t have the “state-bleeding” issue that OpenGL has for middle-ware, resource management may be a new topic for developers. Owning a larger portion of the graphics code responsibilities has its own benefits, as it makes developers more independent and gives them more control over when what happens in the graphics pipeline.

Portability. Vulkan being so low-level means that getting the best out of different hardware architectures will very likely require dedicated code-paths. This is fundamentally not that different to the reality of using extensions in OpenGL, but a reminder that Vulkan doesn’t magically do away with it. It provides a much higher base-level in terms of capabilities, and a concise set of function entry points, but differences in the hardware capabilities and preferred operations will still manifest themselves.

All these statements should not be read as “OpenGL is without flaws”, however OpenGL may indeed be just fine for a lot of use cases. While the heuristics in OpenGL drivers can come at a cost, they have also been able to cover many use-cases over the years.

To improve the situation, Khronos and members companies (especially Valve) have sponsored the development of several open-source Vulkan tools. The reference compiler that generates SPIR-V is already public and a toolkit that covers shader library and command-line use was created by Google. Other tools will follow, for example validation and debug layers that can be used on top of any Vulkan driver.

Khronos has developed an extensive conformance suite, which will guarantee a base level of quality for Vulkan drivers across vendors. Each Vulkan driver will go through conformance testing from the very beginning. Furthermore Khronos has granted many developers, who have helped the OpenGL eco-system in the past, early access so they can make several popular libraries and middleware Vulkan ready.

NVIDIA’s Vulkan driver will allow running Vulkan within an OpenGL context and displaying images generated by Vulkan through OpenGL. NVIDIA will also allow GLSL shaders to be loaded by Vulkan, as well as of course SPIR-V shaders. These two features together allow for rapid prototyping by developers to gauge the impact of replacing OpenGL with Vulkan in sections of existing code, and enable developers to ship applications using Vulkan even when going all-Vulkan is not feasible.

In a follow up post we go into some more technical details how OpenGL can be used in a Vulkan way to make the transition a smoother process.