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.<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 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