Vulkan with wxWidgets

Alexander Overvoorde wrote a good tutorial for programming Vulkan; this is available at vulkan-tutorial.com. In the tutorial, he used GLFW as the windowing system. This is fine if your application uses one main window with no adornments such as menus and status bars, and no additional windows.

I have modified the Hello Triangle example to use wxWidgets. This corresponds to the code up to the end of the Drawing a triangle section of the tutorial. The source code of my wxWidgets version is available on GitHub.

Here is a description of the changes:

  1. HelloTriangleApplication code is split among VulkanTutorialApp, VulkanWindow, and VulkanCanvas. The vast majority of the code is placed in VulkanCanvas. Specifically, the code in HelloTriangleApplication::run is split into two parts:
    • The line:
      mainloop()

      is handled automatically by VulkanTutorialApp, and to some extent by VulkanWindow.

    • The functionality in initWindow and initVulkan are performed in the VulkanCanvas constructor.
  2. The HelloTriangleApplication::drawFrame code is placed in VulkanCanvas::OnPaint.
  3. The HelloTriangleApplication::onWindowResized code is placed in VulkanCanvas::OnResize. wxWindow::RefreshRect must be called to ensure that the canvas is redrawn every time the window is resized. Calling wxWindow::Refresh or wxWindow::Updateonly causes a redraw to occur when the window grows in size, not when shrinking is size.
  4. Two changes were made regarding exceptions:
    • In the tutorial code, runtime_error exceptions are thrown whenever Vulkan errors are encountered. These are replaced with a new exception type called VulkanException which provides information about the actual Vulkan error that was encountered.
    • The tutorial code simply outputs text messages to std::cout. Because the wxVulkanTutorial code is Windows-based, there is no console to output the messages to, so they are output to a wxMessageBox. This was discussed previously in the post C++ Exceptions and wxWidgets.
  5. The tutorial code contains a templated class called VDeleter. This class automatically handles the destruction of various Vulkan handles. I have not included this class in wxVulkanTutorial. Instead, I destroy the handles in the VulkanCanvas destructor.

Have fun with it.

Vulkan

I have spent the last week or so playing with Vulkan, “the next generation OpenGL initiative”. Vulkan is very new; the Vulkan 1.0 specification was released on February 16, 2016. It has a number of advantages over OpenGL; for example, it is a lower level API, similar to Direct3D in its use. It’s features include:

  • Reduced driver and CPU overhead;
  • CPU scaling to multiple core CPUs. OpenGL was originally designed for single CPUs, and scaling is difficult and poorly implemented;
  • Shaders may still be GLSL-based, but the shaders are precompiled, rather than compiled in the program. In future, other shader languages and compilers should become available; and,
  • The Vulkan SDK is available for hardware from mobile devices up through high-end graphics cards.

For more information on Vulkan, see:

Sounds great, but there are cons:

  • You have more control, but more control means you will be writing more C code than you would for OpenGL;
  • Graphics driver support is spotty. For example, at the time I write this, nVidia and AMD support some of their graphics cards, but not all. nVidia’s Windows driver version 356.45 is the only version that supports Vulkan, but their most current Windows driver is at least 361.60. Intel has no Windows drivers that implement Vulkan, and only beta drivers for Linux.
  • There are not a lot of sample programs available yet, and of course, no books. There does seem to be a number of Java examples.

Here are a couple of beginner guides:

and here are links to the Vulkan SDK, and an open-source  C++ wrapper from nVidia.

Update – May 20, 2016

Intel has released a Windows 10 beta driver with Vulkan support, but this driver only supports Vulkan on their 6th generation Intel Core processors with HD Graphics 510, 515, 520, 530, Intel® Iris™ Graphics 540, Intel® Iris™ Graphics 550, and Intel® Iris™ Pro Graphics 580. Since I do not have a computer with any of these processors, I am still out of luck.

nVidia has also updated their Windows graphics drivers to now support the Geforce 800M series. My computer has a Geforce 840M GPU, so I am now able to use the Vulkan libraries. I performed a quick test and the test suite that I created before this original Vulkan post now compile, link and execute without error.

I will begin using Vulkan to build graphics programs once my series of posts on Chaotic Systems and Fractals are completed.

Great, I had some fun. So what did I learn from my playing?

  1. The current version of the Vulkan specification is 1.0.5, the C++ wrapper supports version 1.0.4, and the only available SDK is version 1.0.3.1. There is a mismatch here.
  2. Intel support for Vulkan is pretty much non-existent. My computer has an integrated Intel GPU.
  3. nVidia does not currently support Vulkan for their 800 series GPUs, and there is considerable question as to whether they ever will. Of course, my computer also has an nVidia 840M GPU.
  4. Using the Vulkan API, I was able to query the GPU for information about its capabilities; unfortunately, I cannot acquire a surface for drawing on for my nVidia GPU.

So I am stuck at this point. I do have a few options:

  1. Wait and hope that nVidia comes to its senses and supports the 800 series GPUs.
  2. Upgrade my nVidia graphics card to an nVidia card that supports Vulkan; or maybe upgrade to an AMD graphics card.
  3. Wait for Intel to publish Windows drivers for their graphics cards. My laptop computer also has an integrated Intel GPU so this is a potential option.
  4. Go back to OpenGL and concentrate on shaders, since knowledge of shaders and the shader language are transferable to Vulkan.

I think I will choose options  1, 3, and maybe 4.