It’s been a while that Igalia’s graphics team had been working on the OpenGL extensions that provide the mechanisms for OpenGL and Vulkan interoperability in the Intel iris (gallium3d) driver that is part of mesa.
As there were no conformance tests (CTS) for this extension, and we needed to test it, we have written (and we are still writing) small tests for piglit that allow the exchange and the synchronization of the exchange of resources such as buffers, textures, and depth or stencil buffers.
This is tricky because most drivers were untested and so we can’t easily tell if a bug is in the test or in a driver and there aren’t many interoperability examples out there to use them as a reference. Most of the times we had to write a test in OpenGL first, then in Vulkan, and then in both using interoperability to reach a conclusion about how the extension should be used and if it is implemented properly in the driver.
After having spent a lot of time trying to understand the interoperability extensions, I thought that it might be useful to start a series of posts on how to use them on Linux for different cases (for example to exchange a texture, a depth buffer, a stencil buffer, a pixel buffer or a vertex buffer), using the tests I’ve written for piglit as examples. The full code can be found in the official piglit repository, although some of the examples might not be there yet as they’re under review at the time of writing.
As this is the first and introductory post, I am only going to explain the purpose of these extensions. I am going to show actual examples in the follow up posts.
The concept of interoperability:
Vulkan is a new and low level API that allows controlling the hardware better than OpenGL. But despite that, it has the disadvantage that is complex, and not widely used yet. OpenGL on the other hand is easy to use, it has very good performance in the most common cases, and is already used by many programs out there. The interoperability extensions allow the users to write the critical parts of a program in Vulkan, and the less critical in OpenGL using the same resources, as OpenGL and Vulkan can share the access in external memory objects that have been allocated from Vulkan once. An example of an application that uses interoperability could be a VR compositor: The compositor itself could be written entirely in Vulkan but the images for each eye could be filled by OpenGL.
In order to reuse Vulkan allocated resources we usually need to:
- Use the appropriate flags at allocation to allow “external” (OpenGL) access to them.
- Use the
EXT_external_objects_fdprovided functions to take a file descriptor that points to that memory from Vulkan and give it to OpenGL in order to gain access too.
- Create an OpenGL object that corresponds to that memory.
Use that object like an ordinary OpenGL object (such as texture, buffer, depth or stencil buffer).
- Synchronize the access to that object with a special type of semaphores when necessary (for example when OpenGL must wait for Vulkan to finish an operation before it uses the object or the opposite).
I’ll try to demonstrate examples of Vulkan-GL interoperability in the posts that follow.