Home | History | Annotate | Download | only in graphics
      1 page.title=Implementing Vulkan
      2 @jd:body
      3 
      4 <!--
      5     Copyright 2016 The Android Open Source Project
      6 
      7     Licensed under the Apache License, Version 2.0 (the "License");
      8     you may not use this file except in compliance with the License.
      9     You may obtain a copy of the License at
     10 
     11         http://www.apache.org/licenses/LICENSE-2.0
     12 
     13     Unless required by applicable law or agreed to in writing, software
     14     distributed under the License is distributed on an "AS IS" BASIS,
     15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16     See the License for the specific language governing permissions and
     17     limitations under the License.
     18 -->
     19 
     20 <div id="qv-wrapper">
     21   <div id="qv">
     22     <h2>In this document</h2>
     23     <ol id="auto-toc">
     24     </ol>
     25   </div>
     26 </div>
     27 
     28 
     29 <p>Vulkan is a low-overhead, cross-platform API for high-performance 3D
     30 graphics. Like OpenGL ES, Vulkan provides tools for creating high-quality,
     31 real-time graphics in applications. Vulkan advantages include reductions in CPU
     32 overhead and support for the <a href="https://www.khronos.org/spir">SPIR-V
     33 Binary Intermediate</a> language.</p>
     34 
     35 <p class="note"><strong>Note:</strong> This section describes Vulkan
     36 implementation; for details on Vulkan architecture, advantages, API, and other
     37 resources, see <a href="{@docRoot}devices/graphics/arch-vulkan.html">Vulkan
     38 Architecture</a>.</p>
     39 
     40 <p>To implement Vulkan, a device:</p>
     41 <ul>
     42 <li>Must include the Vulkan Loader (provided by Android) in the build.</li>
     43 <li>Must include a Vulkan driver (provided by SoCs such as GPU IHVs) that
     44 implements the
     45 <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html">Vulkan
     46 API</a>. To support Vulkan functionality, the Android device needs capable GPU
     47 hardware and the associated driver. Consult your SoC vendor to request driver
     48 support.</li>
     49 </ul>
     50 <p>If a Vulkan driver is available on the device, the device needs to declare
     51 <code>FEATURE_VULKAN_HARDWARE_LEVEL</code> and
     52 <code>FEATURE_VULKAN_HARDWARE_VERSION</code> system features, with versions that
     53 accurately reflect the capabilities of the device.</p>
     54 
     55 <h2 id=vulkan_loader>Vulkan Loader</h2>
     56 <p>The primary interface between Vulkan applications and a device's Vulkan
     57 driver is the Vulkan loader, which is part of Android Open Source Project (AOSP)
     58 (<code>platform/frameworks/native/vulkan</code>) and installed at
     59 <code>/system/lib[64]/libvulkan.so</code>. The loader provides the core Vulkan
     60 API entry points, as well as entry points of a few extensions that are required
     61 on Android and always present. In particular, Window System Integration (WSI)
     62 extensions are exported by the loader and primarily implemented in it rather
     63 than the driver. The loader also supports enumerating and loading layers that
     64 can expose additional extensions and/or intercept core API calls on their way to
     65 the driver.</p>
     66 
     67 <p>The NDK includes a stub <code>libvulkan.so</code> library that exports the
     68 same symbols as the loader and which is used for linking. When running on a
     69 device, applications call the Vulkan functions exported from
     70 <code>libvulkan.so</code> (the real library, not the stub) to enter trampoline
     71 functions in the loader (which then dispatch to the appropriate layer or driver
     72 based on their first argument). The <code>vkGetDeviceProcAddr</code> calls
     73 return the function pointers to which the trampolines would dispatch (i.e. it
     74 calls directly into the core API code), so calling through these function
     75 pointers (rather than the exported symbols) is slightly more efficient as it
     76 skips the trampoline and dispatch. However, <code>vkGetInstanceProcAddr</code>
     77 must still call into trampoline code.</p>
     78 
     79 <h2 id=driver_emun>Driver enumeration and loading</h2>
     80 <p>Android expects the GPUs available to the system to be known when the system
     81 image is built. The loader uses the existing HAL mechanism (see
     82 <code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/marshmallow-release/include/hardware/hardware.h">hardware.h</code></a>) for
     83 discovering and loading the driver. Preferred paths for 32-bit and 64-bit Vulkan
     84 drivers are:</p>
     85 
     86 <p>
     87 <pre>
     88 /vendor/lib/hw/vulkan.&lt;ro.product.platform&gt;.so
     89 /vendor/lib64/hw/vulkan.&lt;ro.product.platform&gt;.so
     90 </pre>
     91 </p>
     92 
     93 <p>Where &lt;<code>ro.product.platform</code>&gt; is replaced by the value of
     94 the system property of that name. For details and supported alternative
     95 locations, refer to
     96 <code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/marshmallow-release/hardware.c">libhardware/hardware.c</code></a>.</p>
     97 
     98 <p>In Android 7.0, the Vulkan <code>hw_module_t</code> derivative is trivial;
     99 only one driver is supported and the constant string
    100 <code>HWVULKAN_DEVICE_0</code> is passed to open. If support for multiple
    101 drivers is added in future versions of Android, the HAL module will export a
    102 list of strings that can be passed to the <code>module open</code> call.</p>
    103 
    104 <p>The Vulkan <code>hw_device_t</code> derivative corresponds to a single
    105 driver, though that driver can support multiple physical devices. The
    106 <code>hw_device_t</code> structure can be extended to export
    107 <code>vkGetGlobalExtensionProperties</code>, <code>vkCreateInstance</code>, and
    108 <code>vkGetInstanceProcAddr</code> functions. The loader can find all other
    109 <code>VkInstance</code>, <code>VkPhysicalDevice</code>, and
    110 <code>vkGetDeviceProcAddr</code> functions by calling
    111 <code>vkGetInstanceProcAddr</code>.</p>
    112 
    113 <h2 id=layer_discover>Layer discovery and loading</h2>
    114 <p>The Vulkan loader supports enumerating and loading layers that can expose
    115 additional extensions and/or intercept core API calls on their way to the
    116 driver. Android 7.0 does not include layers on the system image; however,
    117 applications may include layers in their APK.</p>
    118 <p>When using layers, keep in mind that Android's security model and policies
    119 differ significantly from other platforms. In particular, Android does not allow
    120 loading external code into a non-debuggable process on production (non-rooted)
    121 devices, nor does it allow external code to inspect or control the process's
    122 memory, state, etc. This includes a prohibition on saving core dumps, API
    123 traces, etc. to disk for later inspection. Only layers delivered as part of the
    124 application are enabled on production devices, and drivers must not provide
    125 functionality that violates these policies.</p>
    126 
    127 <p>Use cases for layers include:</p>
    128 <ul>
    129 <li><strong>Development-time layers</strong>. These layers (validation layers,
    130 shims for tracing/profiling/debugging tools, etc.) should not be installed on
    131 the system image of production devices as they waste space for users and should
    132 be updateable without requiring a system update. Developers who want to use one
    133 of these layers during development can modify the application package (e.g.
    134 adding a file to their native libraries directory). IHV and OEM engineers who
    135 want to diagnose failures in shipping, unmodifiable apps are assumed to have
    136 access to non-production (rooted) builds of the system image.</li>
    137 <li><strong>Utility layers</strong>. These layers almost always expose
    138 extensions, such as a layer that implements a memory manager for device memory.
    139 Developers choose layers (and versions of those layers) to use in their
    140 application; different applications using the same layer may still use
    141 different versions. Developers choose which of these layers to ship in their
    142 application package.</li>
    143 <li><strong>Injected (implicit) layers</strong>. Includes layers such as
    144 framerate, social network, or game launcher overlays provided by the user or
    145 some other application without the application's knowledge or consent. These
    146 violate Android's security policies and are not supported.</li>
    147 </ul>
    148 
    149 <p>In the normal state, the loader searches for layers only in the application's
    150 native library directory and attempts to load any library with a name matching a
    151 particular pattern (e.g. <code>libVKLayer_foo.so</code>). It does not need a
    152 separate manifest file as the developer deliberately included these layers and
    153 reasons to avoid loading libraries before enabling them don't apply.</p>
    154 
    155 <p>Android allows layers to be ported with build-environment changes between
    156 Android and other platforms. For details on the interface between layers and the
    157 loader, refer to
    158 <a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md">Vulkan
    159 Loader Specification and Architecture Overview</a>. Versions of the LunarG
    160 validation layers that have been verified to build and work on Android are
    161 hosted in the android_layers branch of the
    162 <a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/tree/android_layers">KhronosGroup/Vulkan-LoaderAndValidationLayers</a>
    163 project on GitHub.</p>
    164 
    165 <h2 id=wsi>Window System Integration (WSI)</h2>
    166 <p>The Window System Integration (WSI) extensions <code>VK_KHR_surface</code>,
    167 <code>VK_KHR_android_surface</code>, and <code>VK_KHR_swapchain</code> are
    168 implemented by the platform and live in <code>libvulkan.so</code>. The
    169 <code>VkSurfaceKHR</code> and <code>VkSwapchainKHR</code> objects and all
    170 interaction with <code>ANativeWindow</code> is handled by the platform and is
    171 not exposed to drivers. The WSI implementation relies on the
    172 <code>VK_ANDROID_native_buffer</code> extension (described below) which must be
    173 supported by the driver; this extension is only used by the WSI implementation
    174 and will not be exposed to applications.</p>
    175 
    176 <h3 id=gralloc_usage_flags>Gralloc usage flags</h3>
    177 <p>Implementations may need swapchain buffers to be allocated with
    178 implementation-defined private gralloc usage flags. When creating a swapchain,
    179 the platform asks the driver to translate the requested format and image usage
    180 flags into gralloc usage flags by calling:</p>
    181 
    182 <p>
    183 <pre>
    184 VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
    185     VkDevice            device,
    186     VkFormat            format,
    187     VkImageUsageFlags   imageUsage,
    188     int*                grallocUsage
    189 );
    190 </pre>
    191 </p>
    192 
    193 <p>The <code>format</code> and <code>imageUsage</code> parameters are taken from
    194 the <code>VkSwapchainCreateInfoKHR</code> structure. The driver should fill
    195 <code>*grallocUsage</code> with the gralloc usage flags required for the format
    196 and usage (which are combined with the usage flags requested by the swapchain
    197 consumer when allocating buffers).</p>
    198 
    199 <h3 id=gralloc_usage_flags>Gralloc-backed images</h3>
    200 
    201 <p><code>VkNativeBufferANDROID</code> is a <code>vkCreateImage</code> extension
    202 structure for creating an image backed by a gralloc buffer. This structure is
    203 provided to <code>vkCreateImage</code> in the <code>VkImageCreateInfo</code>
    204 structure chain. Calls to <code>vkCreateImage</code> with this structure happen
    205 during the first call to <code>vkGetSwapChainInfoWSI(..
    206 VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</code>. The WSI implementation allocates
    207 the number of native buffers requested for the swapchain, then creates a
    208 <code>VkImage</code> for each one:</p>
    209 
    210 <p><pre>
    211 typedef struct {
    212     VkStructureType             sType; // must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID
    213     const void*                 pNext;
    214 
    215     // Buffer handle and stride returned from gralloc alloc()
    216     buffer_handle_t             handle;
    217     int                         stride;
    218 
    219     // Gralloc format and usage requested when the buffer was allocated.
    220     int                         format;
    221     int                         usage;
    222 } VkNativeBufferANDROID;
    223 </pre></p>
    224 
    225 <p>When creating a gralloc-backed image, the <code>VkImageCreateInfo</code> has
    226 the following data:</p>
    227 
    228 <p><pre>
    229  .imageType           = VK_IMAGE_TYPE_2D
    230   .format              = a VkFormat matching the format requested for the gralloc buffer
    231   .extent              = the 2D dimensions requested for the gralloc buffer
    232   .mipLevels           = 1
    233   .arraySize           = 1
    234   .samples             = 1
    235   .tiling              = VK_IMAGE_TILING_OPTIMAL
    236   .usage               = VkSwapChainCreateInfoWSI::imageUsageFlags
    237   .flags               = 0
    238   .sharingMode         = VkSwapChainCreateInfoWSI::sharingMode
    239   .queueFamilyCount    = VkSwapChainCreateInfoWSI::queueFamilyCount
    240   .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices
    241 </pre></p>
    242 
    243 <h3 id=acquire_image>Aquiring images</h3>
    244 <p><code>vkAcquireImageANDROID</code> acquires ownership of a swapchain image
    245 and imports an externally-signalled native fence into both an existing
    246 <code>VkSemaphore</code> object and an existing <code>VkFence</code> object:</p>
    247 
    248 <p><pre>
    249 VkResult VKAPI vkAcquireImageANDROID(
    250     VkDevice            device,
    251     VkImage             image,
    252     int                 nativeFenceFd,
    253     VkSemaphore         semaphore,
    254     VkFence             fence
    255 );
    256 </pre></p>
    257 
    258 <p>This function is called during <code>vkAcquireNextImageWSI</code> to import a
    259 native fence into the <code>VkSemaphore</code> and <code>VkFence</code> objects
    260 provided by the application (however, both semaphore and fence objects are
    261 optional in this call). The driver may also use this opportunity to recognize
    262 and handle any external changes to the gralloc buffer state; many drivers won't
    263 need to do anything here. This call puts the <code>VkSemaphore</code> and
    264 <code>VkFence</code> into the same pending state as
    265 <code>vkQueueSignalSemaphore</code> and <code>vkQueueSubmit</code> respectively,
    266 so queues can wait on the semaphore and the application can wait on the fence.</p>
    267 
    268 <p>Both objects become signalled when the underlying native fence signals; if
    269 the native fence has already signalled, then the semaphore is in the signalled
    270 state when this function returns. The driver takes ownership of the fence fd and
    271 is responsible for closing it when no longer needed. It must do so even if
    272 neither a semaphore or fence object is provided, or even if
    273 <code>vkAcquireImageANDROID</code> fails and returns an error. If fenceFd is -1,
    274 it is as if the native fence was already signalled.</p>
    275 
    276 <h3 id=acquire_image>Releasing images</h3>
    277 <p><code>vkQueueSignalReleaseImageANDROID</code> prepares a swapchain image for
    278 external use, and creates a native fence and schedules it to be signalled when
    279 prior work on the queue has completed:</p>
    280 
    281 <p><pre>
    282 VkResult VKAPI vkQueueSignalReleaseImageANDROID(
    283     VkQueue             queue,
    284     VkImage             image,
    285     int*                pNativeFenceFd
    286 );
    287 </pre></p>
    288 
    289 <p>This API is called during <code>vkQueuePresentWSI</code> on the provided
    290 queue. Effects are similar to <code>vkQueueSignalSemaphore</code>, except with a
    291 native fence instead of a semaphore. Unlike <code>vkQueueSignalSemaphore</code>,
    292 however, this call creates and returns the synchronization object that will be
    293 signalled rather than having it provided as input. If the queue is already idle
    294 when this function is called, it is allowed (but not required) to set
    295 <code>*pNativeFenceFd</code> to -1. The file descriptor returned in
    296 *<code>pNativeFenceFd</code> is owned and will be closed by the caller.</p>
    297 
    298 <h3 id=update_drivers>Updating drivers</h3>
    299 
    300 <p>Many drivers can ignore the image parameter, but some may need to prepare
    301 CPU-side data structures associated with a gralloc buffer for use by external
    302 image consumers. Preparing buffer contents for use by external consumers should
    303 have been done asynchronously as part of transitioning the image to
    304 <code>VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</code>.</p>
    305 
    306 <h2 id=validation>Validation</h2>
    307 <p>OEMs can test their Vulkan implementation using CTS, which includes
    308 <a href="{@docRoot}devices/graphics/cts-integration.html">drawElements
    309 Quality Program (dEQP)</a> tests that exercise the Vulkan Runtime.</p>
    310