1page.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 30graphics. Like OpenGL ES, Vulkan provides tools for creating high-quality, 31real-time graphics in applications. Vulkan advantages include reductions in CPU 32overhead and support for the <a href="https://www.khronos.org/spir">SPIR-V 33Binary Intermediate</a> language.</p> 34 35<p class="note"><strong>Note:</strong> This section describes Vulkan 36implementation; for details on Vulkan architecture, advantages, API, and other 37resources, see <a href="{@docRoot}devices/graphics/arch-vulkan.html">Vulkan 38Architecture</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 44implements the 45<a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html">Vulkan 46API</a>. To support Vulkan functionality, the Android device needs capable GPU 47hardware and the associated driver. Consult your SoC vendor to request driver 48support.</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 53accurately 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 57driver 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 60API entry points, as well as entry points of a few extensions that are required 61on Android and always present. In particular, Window System Integration (WSI) 62extensions are exported by the loader and primarily implemented in it rather 63than the driver. The loader also supports enumerating and loading layers that 64can expose additional extensions and/or intercept core API calls on their way to 65the driver.</p> 66 67<p>The NDK includes a stub <code>libvulkan.so</code> library that exports the 68same symbols as the loader and which is used for linking. When running on a 69device, applications call the Vulkan functions exported from 70<code>libvulkan.so</code> (the real library, not the stub) to enter trampoline 71functions in the loader (which then dispatch to the appropriate layer or driver 72based on their first argument). The <code>vkGetDeviceProcAddr</code> calls 73return the function pointers to which the trampolines would dispatch (i.e. it 74calls directly into the core API code), so calling through these function 75pointers (rather than the exported symbols) is slightly more efficient as it 76skips the trampoline and dispatch. However, <code>vkGetInstanceProcAddr</code> 77must 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 81image 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 83discovering and loading the driver. Preferred paths for 32-bit and 64-bit Vulkan 84drivers are:</p> 85 86<p> 87<pre> 88/vendor/lib/hw/vulkan.<ro.product.platform>.so 89/vendor/lib64/hw/vulkan.<ro.product.platform>.so 90</pre> 91</p> 92 93<p>Where <<code>ro.product.platform</code>> is replaced by the value of 94the system property of that name. For details and supported alternative 95locations, 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; 99only one driver is supported and the constant string 100<code>HWVULKAN_DEVICE_0</code> is passed to open. If support for multiple 101drivers is added in future versions of Android, the HAL module will export a 102list 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 105driver, 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 115additional extensions and/or intercept core API calls on their way to the 116driver. Android 7.0 does not include layers on the system image; however, 117applications may include layers in their APK.</p> 118<p>When using layers, keep in mind that Android's security model and policies 119differ significantly from other platforms. In particular, Android does not allow 120loading external code into a non-debuggable process on production (non-rooted) 121devices, nor does it allow external code to inspect or control the process's 122memory, state, etc. This includes a prohibition on saving core dumps, API 123traces, etc. to disk for later inspection. Only layers delivered as part of the 124application are enabled on production devices, and drivers must not provide 125functionality 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, 130shims for tracing/profiling/debugging tools, etc.) should not be installed on 131the system image of production devices as they waste space for users and should 132be updateable without requiring a system update. Developers who want to use one 133of these layers during development can modify the application package (e.g. 134adding a file to their native libraries directory). IHV and OEM engineers who 135want to diagnose failures in shipping, unmodifiable apps are assumed to have 136access to non-production (rooted) builds of the system image.</li> 137<li><strong>Utility layers</strong>. These layers almost always expose 138extensions, such as a layer that implements a memory manager for device memory. 139Developers choose layers (and versions of those layers) to use in their 140application; different applications using the same layer may still use 141different versions. Developers choose which of these layers to ship in their 142application package.</li> 143<li><strong>Injected (implicit) layers</strong>. Includes layers such as 144framerate, social network, or game launcher overlays provided by the user or 145some other application without the application's knowledge or consent. These 146violate 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 150native library directory and attempts to load any library with a name matching a 151particular pattern (e.g. <code>libVKLayer_foo.so</code>). It does not need a 152separate manifest file as the developer deliberately included these layers and 153reasons 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 156Android and other platforms. For details on the interface between layers and the 157loader, refer to 158<a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md">Vulkan 159Loader Specification and Architecture Overview</a>. Versions of the LunarG 160validation layers that have been verified to build and work on Android are 161hosted in the android_layers branch of the 162<a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/tree/android_layers">KhronosGroup/Vulkan-LoaderAndValidationLayers</a> 163project 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 168implemented by the platform and live in <code>libvulkan.so</code>. The 169<code>VkSurfaceKHR</code> and <code>VkSwapchainKHR</code> objects and all 170interaction with <code>ANativeWindow</code> is handled by the platform and is 171not exposed to drivers. The WSI implementation relies on the 172<code>VK_ANDROID_native_buffer</code> extension (described below) which must be 173supported by the driver; this extension is only used by the WSI implementation 174and 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 178implementation-defined private gralloc usage flags. When creating a swapchain, 179the platform asks the driver to translate the requested format and image usage 180flags into gralloc usage flags by calling:</p> 181 182<p> 183<pre> 184VkResult 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 194the <code>VkSwapchainCreateInfoKHR</code> structure. The driver should fill 195<code>*grallocUsage</code> with the gralloc usage flags required for the format 196and usage (which are combined with the usage flags requested by the swapchain 197consumer 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 202structure for creating an image backed by a gralloc buffer. This structure is 203provided to <code>vkCreateImage</code> in the <code>VkImageCreateInfo</code> 204structure chain. Calls to <code>vkCreateImage</code> with this structure happen 205during the first call to <code>vkGetSwapChainInfoWSI(.. 206VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</code>. The WSI implementation allocates 207the number of native buffers requested for the swapchain, then creates a 208<code>VkImage</code> for each one:</p> 209 210<p><pre> 211typedef 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 226the 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 245and 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> 249VkResult 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 259native fence into the <code>VkSemaphore</code> and <code>VkFence</code> objects 260provided by the application (however, both semaphore and fence objects are 261optional in this call). The driver may also use this opportunity to recognize 262and handle any external changes to the gralloc buffer state; many drivers won't 263need 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, 266so 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 269the native fence has already signalled, then the semaphore is in the signalled 270state when this function returns. The driver takes ownership of the fence fd and 271is responsible for closing it when no longer needed. It must do so even if 272neither a semaphore or fence object is provided, or even if 273<code>vkAcquireImageANDROID</code> fails and returns an error. If fenceFd is -1, 274it 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 278external use, and creates a native fence and schedules it to be signalled when 279prior work on the queue has completed:</p> 280 281<p><pre> 282VkResult 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 290queue. Effects are similar to <code>vkQueueSignalSemaphore</code>, except with a 291native fence instead of a semaphore. Unlike <code>vkQueueSignalSemaphore</code>, 292however, this call creates and returns the synchronization object that will be 293signalled rather than having it provided as input. If the queue is already idle 294when 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 301CPU-side data structures associated with a gralloc buffer for use by external 302image consumers. Preparing buffer contents for use by external consumers should 303have 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 309Quality Program (dEQP)</a> tests that exercise the Vulkan Runtime.</p> 310