Heidi von Markham | fd022c7 | 2016-06-30 10:15:28 -0700 | [diff] [blame] | 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 | |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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> |
Heidi von Markham | fd022c7 | 2016-06-30 10:15:28 -0700 | [diff] [blame] | 34 | |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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> |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 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 |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 45 | <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html">Vulkan |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 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> |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 49 | </ul> |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 50 | <p>If a Vulkan driver is available on the device, the device needs to declare |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 57 | driver is the Vulkan loader, which is part of Android Open Source Project (AOSP) |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 | |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 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> |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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> |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 87 | <pre> |
| 88 | /vendor/lib/hw/vulkan.<ro.product.platform>.so |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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, |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 117 | applications may include layers in their APK.</p> |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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> |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 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> |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 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 |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 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 |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 | |
Heidi von Markham | 85ab9c2 | 2016-07-13 12:54:25 -0700 | [diff] [blame^] | 193 | <p>The <code>format</code> and <code>imageUsage</code> parameters are taken from |
| 194 | the <code>VkSwapchainCreateInfoKHR</code> structure. The driver should fill |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 | |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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 | |
Heidi von Markham | 6bda398 | 2016-06-30 17:04:44 -0700 | [diff] [blame] | 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> |