Tuesday, 16 February 2016

Vulkan in GStreamer

Today, Vulkan 1.0 as released. For those of you that don't what Vulkan is, the TL;DR is essentially that it's cross-platform/device lower level 3D API than OpenGL (both the desktop and the ES variants) of a similar scope to DX12, Metal or Mantle. As a result, the driver does less work and the application/engine takes over some of the management of resources which hopefully leads to a smaller driver divergence and therefore bugs while at the same time providing increased access to the capabilities of the GPU. Centricular graciously sponsored some of my time to have a look at Vulkan and implement a basic working prototype of a GStreamer sink element that would display video frames onto the screen. I hereby present to you, vulkansink, the result of that labour.
gst-launch-1.0 videotestsrc ! vulkanupload ! vulkansink

Disclaimer: this is still alpha-quality code and it hasn't had the same extensive testing as the OpenGL elements and there are a number of short fallings:
  1. It doesn't scale the input video to the output surface size (yet).
  2. There's very little locking (as required by the Vulkan specification, e.g. VkCommandBuffer's and VkCommandPool's).
  3. There aren't any effects/colour conversion implemented.
  4. Performance has not been a primary concern so there are some inefficiencies in the current design.
All that being said, my impressions of Vulkan are relatively good. It promises to fit infinitely better with GStreamer's extensive use of threads than an equivalent OpenGL implementation. That extra flexibility and functionality comes at the price of increased complexity however I think that is a necessary cost.

The hard API change also provides a higher baseline for implementations and applications to depend against which resets the amount of legacy code that would need to be maintained for older GPU's and systems.

Implementation Details

The current implementation of libgstgl was used extensively as a basis for the structure of how Vulkan is intended to be used in GStreamer.

Memory

Vulkan provides a high level overview of accessing GPU memory through VkDeviceMemory objects. These are simply wrapped in GstMemory objects as GstVulkanMemory with allocation and destruction routines for creating and destroying GPU memory as well as mapping with gst_memory_map() for CPU access to the data (if supported at creation).
Vulkan provides VkBuffer objects which are somewhat equivalent to OpenGL's Buffer objects which are used for storing vertices, draw indices, uniforms, texels, etc and is wrapped up in GStreamer into the GstVulkanBufferMemory object (a subclass of GstMemory). As a backing store, it allocates a GstVulkanMemory object.
GstVulkanImageMemory provides the same abstraction for VkImage objects which also have a backing store of a GstVulkanMemory.

Integrating with applications

The GstContext infrastructure is used extensively to not only share necessary state between elements but also providing application specific state into GStreamer. The current list of GstContext-able objects is, VkInstance, VkDevice, VkDisplay and the VkQueue which all have GStreamer wrappers to account for refcounting and in the future, Vulkan's locking requirements.

No comments:

Post a Comment