Getting Vulkan Ready For VR

Introduction

Authors: James Jones, Mathias Schott

It’s a great time to be working in the field of graphics these days as there are a slew of new exciting technologies emerging, like Vulkan and VR. Naturally, the question frequently arises: how to combine those? (And not just because they share the capital letter.) However, as with many emerging technologies, there is often the “chicken-and-egg” problem between application developers and platform providers. For Vulkan and VR, this means that the VR HMD runtimes need to support Vulkan to make them interesting for Vulkan application developers. On the other hand, VR HMD vendors will only focus on adding Vulkan support to their HMD runtimes if there is application demand. Additional complexities arise because an HMD runtime is written in one API, but applications are written in any of a number of APIs. E.g., if the HMD runtime is written in Direct3D 11 and the application is written in Vulkan, then interoperability between Vulkan and Direct3D 11 is required.

Naturally, anything related to graphics APIs involves graphics-drivers, and this is where NVIDIA is contributing by collaborating with our partners in the VR ecosystem. We specifically explored the design space of interoperability between Vulkan and other APIs as well as sharing resources between the application process and the process the HMD runtime is running in. We are now shipping this functionality as a set of Vulkan extensions that allow cross-process resource sharing and interoperability between Vulkan and other APIs.

This solves both immediate needs of our partners, but more importantly is a first step towards a possible standardization via the established Khronos process, which preferably starts with practical experience from a wide range of ISVs and IHVs. This functionality has been standardized as the VK_KHR_external_* extension framework since the original publication of this article. See NVIDIA Vulkan Developer Driver for Khronos Vulkan Spec update 1.0.54for details.

The VK_NV_external_memory Extension Framework

These extensions enable developers to create applications which import Vulkan memory from another processes, as well as import memory from Direct3D images into Vulkan. Vulkan images can then be created using the imported memory, enabling both processes and APIs to access the same texture or render target. The extensions themselves are grouped into two categories. A set of platform-independent extensions define the core mechanisms. Platform-dependent extensions are then used to integrate those mechanisms with specific operating systems.

After checking for basic support, the application should check the values in VkExternalImageFormatPropertiesNV to determine whether the desired operations are supported for the requested handle type. In this case, the application wants to import an existing object.

Creating the Direct3D Export Texture

At some point, the application will need to create a texture and export it from Direct3D. This can be done in the same process as the Vulkan code, or in another process as long as the handle is properly shared between the processes.

Creating the Vulkan Import Image

After verifying the necessary driver capabilities are available, the application can create a Vulkan image with parameters corresponding to those of the Direct3D texture, and bind it to a Vulkan memory object created from the shared handle of the Direct3D texture.

Binding Memory to the Vulkan Image

After creating the image, its memory requirements must be queried as usual to determine the supported memory types. The application can then use one of the supported memory types when importing the external handle to a Vulkan memory object. If a VK_NV_dedicated_allocation is not used, the memory must be bound to an image as usual.

Note: The memory types may differ from those reported when an external handle type is not specified.

Synchronizing Vulkan Queue Access via Keyed Mutex

Finally, when using the image, Vulkan queue operations can be synchronized using the keyed mutex associated with the Direct3D shared texture. The keyed mutex is referenced using the Vulkan handle of the memory object imported from the Direct3D shared texture: