Morten Johan Sørvig

Vulkan for Qt on macOS

Published Wednesday May 30th, 2018
2 Comments on Vulkan for Qt on macOS
Posted in Dev Loop, Graphics, macOS, Vulkan

Sometimes, development efforts align such that new use cases can be enabled with modest extra effort. The QtBase dev branch (which will become Qt 5.12) now has experimental Vulkan support, courtesy of MoltenVK and prior work in Qt. Let’s take a look at what has happened.

hellomacosvulcancubes

Backstory

Last year, Laszlo wrote about Vulkan support in Qt on Windows, Linux, and Android. This work included adding QSurface::VulkanSurface and also adding cross-platform classes such as QVulkanInstance and QVulkanWindow

Then, a couple of months ago, the MoltenVK Vulkan to Metal translation library was open sourced. One of the issues raised in the bug reporter was how to make this work with Qt; this requires configuring the NSView used by QWindow to be layer-backed by a CAMetalLayer.

And, as it happens we were already looking at making use of Metal in Qt, starting with adding support for CAMetalLayer as a backing layer. We’re also looking at different ways to integrate application Metal code with Qt, but that’s a topic for another blogpost.


// Snippet from Qt internal layer management code

@implementation QT_MANGLE_NAMESPACE(QNSView) (DrawingAPI)

- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
{
    // We need to set this this excplicitly since the super implementation
    // returns LayerContentsRedrawNever for custom layers like CAMetalLayer.
    return NSViewLayerContentsRedrawDuringViewResize;
}

- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
{
    CGSize drawableSize = layer.bounds.size;
    drawableSize.width *= layer.contentsScale;
    drawableSize.height *= layer.contentsScale;
    layer.drawableSize = drawableSize;
}

- (void)layoutSublayersOfLayer:(CALayer *)layer
{
    if ([layer isKindOfClass:CAMetalLayer.class])
        [self updateMetalLayerDrawableSize:static_cast(layer)];
}

- (void)viewDidChangeBackingProperties
{
    CALayer *layer = self.layer;
    if (!layer)
        return;

    layer.contentsScale = self.window.backingScaleFactor;

    // Metal layers must be manually updated on e.g. screen change
    if ([layer isKindOfClass:CAMetalLayer.class]) {
        [self updateMetalLayerDrawableSize:static_cast(layer)];
        [self setNeedsDisplay:YES];
    }
}

@end

With all this in place the missing parts was then the platform plugin glue code which adds support for QSurface::VulkanSurface (on macOS) and also implements a QPlatformVulkanInstance subclass that abstracts over platform-specific Vulkan tasks such as creating a Vulkan surface for a native surface.

How do I use it?

The minimal way

Call setSurfaceType(QSurface::VulkanSurface) in the constructor of your QWindow subclass. You can now access the NSView with QWindow::winId(), and pass that on to MoltenVK. The NSView is configured in such a way that MoltenVK can render to it. See also MotelVK issue #78 for more info. Note that I have not actually tried this myself 🙂

This does not require enabling Vulkan support when building Qt, which again means that the Qt binary package can be used (from 5.12 onwards).

The using the Qt API way

This makes using QVulkanWindow and friends possible, at the cost of having to build Qt from source.

Configure and build Qt with Vulkan support by adding the MoltenVK includes (build MoltenVK according to instructions first):

./confgure -I /path/to/MoltenVK/Package/Release/MoltenVK/include

You should now see “Vulkan: yes” on the configure report; if so the QVulkan* classes are available.

Then, tell Qt the location of libMoltenVK.dylib before starting apps or examples:

export QT_VULKAN_LIB=
  /path/to/MoltenVK/Package/Release/MoltenVK/macOS/libMoltenVK

This re-uses the existing Qt code which loads and resolves the Vulcan library at run-time. On macOS we might want to link against MoltenVK.framework instead, but we’ll leave that as a future improvement for now.

Finally

I’d like to round off by repeating the “experimental” warning. In particular we don’t have enough insight into the inner workings of MoltenVK to know if there are potential points of incompatibility. Please report any findings below or in a QTBUG.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Dev Loop, Graphics, macOS, Vulkan

2 comments

Luciano Moffatt says:

Not related to Vulkan, (if there is a better place to say it):
downloading from http://download.qt.io/snapshots/ became painfully slow in the last two weeks.

@Luciano: Some of the open-source mirrors have faced issues due to the growing size of the repositories. We are now working to move older items into the archive (which is not so often mirrored). This should help a bit. Of course the best would be to have more mirrors. If you experience slowness, contact your local mirror provider and ask to mirror the Qt Project: https://wiki.qt.io/Mirror_howto

Commenting closed.

Get started today with Qt Download now