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