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