Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1 | # Vulkan Loader Specification and Architecture Overview |
| 2 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 3 | <br/> |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 4 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 5 | ## Goals of this document ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 6 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 7 | Specify necessary functions and expected behavior of interface between the |
| 8 | loader library and ICDs and layers for Windows, Linux and Android based |
| 9 | systems. Also describe the application visible behaviors of the loader. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 10 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 11 | <br/> |
| 12 | |
| 13 | ## Audience ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 14 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 15 | This document is primarily targeted at Vulkan application, driver and layer developers. |
| 16 | However, it can also be used by any developer interested in understanding more about |
| 17 | how the Vulkan loader and layers interact. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 18 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 19 | <br/> |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 20 | |
| 21 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 22 | ## Loader goals ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 23 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 24 | - Support multiple ICDs (Installable Client Drivers) to co-exist on a system |
| 25 | without interfering with each other. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 26 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 27 | - Support optional modules (layers) that can be enabled by an application, |
| 28 | developer or the system and have no impact when not enabled. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 29 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 30 | - Negligible performance cost for an application calling through the loader |
| 31 | to an ICD entry point. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 32 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 33 | <br/> |
| 34 | |
| 35 | ## Architectural overview of layers and loader ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 36 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 37 | Vulkan is a layered architecture placing the Application on one end, the |
| 38 | ICDs on the other, and the loader and some number of layers in between. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 39 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 40 | Layers are implemented as libraries that can be enabled in different ways |
| 41 | (including by application request) and loaded during CreateInstance. Each |
| 42 | layer can chooses to hook (intercept) any Vulkan commands which in turn |
| 43 | can be ignored, augmented, or simply passed along. A layer may also |
| 44 | expose functionality not available in the loader or any ICD. Some examples |
| 45 | of this include: the ability to perform Vulkan API tracing and debugging, |
| 46 | validate API usage, or overlay additional content on the applications surfaces. |
| 47 | |
| 48 | The loader is responsible for working with the various layers as well as |
| 49 | supporting multiple GPUs and their drivers. Any Vulkan command may |
| 50 | wind up calling into a diverse set of modules: loader, layers, and ICDs. |
| 51 | The loader is critical to managing the proper dispatching of Vulkan |
| 52 | commands to the appropriate set of layers and ICDs. The Vulkan object |
| 53 | model allows the loader to insert layers into a call chain so that the layers |
| 54 | can process Vulkan commands prior to the ICD being called. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 55 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 56 | Vulkan uses an object model to control the scope of a particular action / |
| 57 | operation. The object to be acted on is always the first parameter of a Vulkan |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 58 | call and is a dispatchable object (see Vulkan specification section 2.3 Object |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 59 | Model). Under the covers, the dispatchable object handle is a pointer to a |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 60 | structure, which in turn, contains a pointer to a dispatch table maintained by |
| 61 | the loader. This dispatch table contains pointers to the Vulkan functions appropriate to |
| 62 | that object. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 63 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 64 | There are two types of dispatch tables the loader maintains: |
| 65 | - **Instance Dispatch Table** |
| 66 | - Contains any function that takes a VkInstance or VkPhysicalDevice as their first parameter |
| 67 | - vkEnumeratePhysicalDevices |
| 68 | - vkDestroyInstance |
| 69 | - vkCreateInstance |
| 70 | - ... |
| 71 | - **Device Dispatch Table** |
| 72 | - Contains any function that takes a VkDevice, VkQueue or VkCommandBuffer as their first parameter |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 73 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 74 | These instance and device dispatch tables are constructed when the application |
| 75 | calls vkCreateInstance and vkCreateDevice. At that time the application and/or |
| 76 | system can specify optional layers to be included. The loader will initialize |
| 77 | the specified layers to create a call chain for each Vulkan function and each |
| 78 | entry of the dispatch table will point to the first element of that chain. |
| 79 | Thus, the loader builds an instance call chain for each VkInstance that is |
| 80 | created and a device call chain for each VkDevice that is created. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 81 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 82 | For example, the diagram below represents what happens in the call chain for |
| 83 | vkCreateInstance. After initializing the chain, the loader will call into the |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 84 | first layer's vkCreateInstance which will call the next finally terminating in |
| 85 | the loader again where this function calls every ICD's vkCreateInstance and |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 86 | saves the results. This allows every enabled layer for this chain to set up |
| 87 | what it needs based on the VkInstanceCreateInfo structure from the application. |
Jon Ashburn | c250556 | 2016-02-15 10:19:26 -0700 | [diff] [blame] | 88 |  |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 89 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 90 | This also highlights some of the complexity the loader must manage when using |
| 91 | instance chains. As shown here, the loader must aggregate information from |
| 92 | multiple devices when they are present. This means that the loader has to know |
| 93 | about instance level extensions to aggregate them correctly. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 94 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 95 | Device chains are created at vkCreateDevice and are generally simpler because |
| 96 | they deal with only a single device and the ICD can always be the terminator of |
| 97 | the chain. The below diagram also illustrates how layers (either device or |
| 98 | instance) can skip intercepting any given Vulkan entry point. |
Jon Ashburn | c250556 | 2016-02-15 10:19:26 -0700 | [diff] [blame] | 99 |  |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 100 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 101 | <br/> |
| 102 | |
| 103 | ## Application interface to loader ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 104 | |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 105 | In this section we'll discuss how an application interacts with the loader. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 106 | |
| 107 | - Linking to loader library for core and WSI extension symbols. |
| 108 | |
| 109 | - Dynamic Vulkan command lookup & application dispatch table. |
| 110 | |
| 111 | - Loader library filenames for linking to different Vulkan ABI versions. |
| 112 | |
| 113 | - Layers |
| 114 | |
| 115 | - Extensions |
| 116 | |
| 117 | - vkGetInstanceProcAddr, vkGetDeviceProcAddr |
| 118 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 119 | The loader library on Windows, Linux and Android will export all core Vulkan |
| 120 | and all appropriate Window System Interface (WSI) extensions. This is done to |
| 121 | make it simpler to get started with Vulkan development. When an application |
| 122 | links directly to the loader library in this way, the Vulkan calls are simple |
| 123 | trampoline functions that jump to the appropriate dispatch table entry for the |
| 124 | object they are given. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 125 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 126 | Applications are not required to link directly to the loader library, instead |
| 127 | they can use the appropriate platform specific dynamic symbol lookup on the |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 128 | loader library to initialize the application's own dispatch table. This allows |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 129 | an application to fail gracefully if the loader cannot be found, and it |
| 130 | provides the fastest mechanism for the application to call Vulkan functions. An |
| 131 | application will only need to query (via system calls such as dlsym()) the |
| 132 | address of vkGetInstanceProcAddr from the loader library. Using |
| 133 | vkGetInstanceProcAddr the application can then discover the address of all |
| 134 | instance and global functions and extensions, such as vkCreateInstance, |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 135 | vkEnumerateInstanceExtensionProperties and vkEnumerateInstanceLayerProperties |
| 136 | in a platform independent way. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 137 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 138 | The Vulkan loader library will be distributed in various ways including Vulkan |
| 139 | SDKs, OS package distributions and IHV driver packages. These details are |
| 140 | beyond the scope of this document. However, the name and versioning of the |
| 141 | Vulkan loader library is specified so an app can link to the correct Vulkan ABI |
| 142 | library version. Vulkan versioning is such that ABI backwards compatibility is |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 143 | guaranteed for all versions with the same major number (e.g. 1.0 and 1.1). On |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 144 | Windows, the loader library encodes the ABI version in its name such that |
| 145 | multiple ABI incompatible versions of the loader can peacefully coexist on a |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 146 | given system. The Vulkan loader library file name is "vulkan-<ABI |
| 147 | version>.dll". For example, for Vulkan version 1.X on Windows the library |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 148 | filename is vulkan-1.dll. And this library file can typically be found in the |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 149 | windows/system32 directory (on 64-bit Windows installs, the 32-bit version of |
| 150 | the loader with the same name can be found in the windows/sysWOW64 directory). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 151 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 152 | For Linux, shared libraries are versioned based on a suffix. Thus, the ABI |
| 153 | number is not encoded in the base of the library filename as on Windows. On |
| 154 | Linux an application wanting to link to the latest Vulkan ABI version would |
| 155 | just link to the name vulkan (libvulkan.so). A specific Vulkan ABI version can |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 156 | also be linked to by applications (e.g. libvulkan.so.1). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 157 | |
Rene Lindsay | a0508df | 2016-10-25 11:05:09 -0600 | [diff] [blame] | 158 | #### Layer Usage |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 159 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 160 | Applications desiring Vulkan functionality beyond what the core API offers may |
Mark Young | 02ee538 | 2016-07-22 08:51:05 -0600 | [diff] [blame] | 161 | use various layers or extensions. A layer cannot introduce new Vulkan API |
| 162 | entry-points not exposed in Vulkan.h, but may offer extensions that do. A |
| 163 | common use of layers is for API validation which can be enabled by loading the |
| 164 | layer during application development, but not loading the layer for application |
| 165 | release. This eliminates the overhead of validating the application's |
| 166 | usage of the API, something that wasn't available on some previous graphics |
| 167 | APIs. |
| 168 | |
| 169 | Layers discovered by the loader are reported to the application via |
| 170 | vkEnumerateInstanceLayerProperties. Layers are enabled at vkCreateInstance |
| 171 | and are active for all Vulkan commands using the given VkInstance and any |
| 172 | of it's child objects. For example, the ppEnabledLayerNames array in the |
| 173 | VkInstanceCreateInfo structure is used by the application to list the layer |
| 174 | names to be enabled at vkCreateInstance. At vkCreateInstance and |
| 175 | vkCreateDevice, the loader will construct call chains that include the application |
| 176 | specified (enabled) layers. Order is important in the |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 177 | ppEnabledLayerNames array; array element 0 is the topmost (closest to the |
| 178 | application) layer inserted in the chain and the last array element is closest |
| 179 | to the driver. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 180 | |
Mark Young | 02ee538 | 2016-07-22 08:51:05 -0600 | [diff] [blame] | 181 | **NOTE**: vkCreateDevice originally was able to select layers in a |
| 182 | similar manner to vkCreateInstance. This lead to the concept of "instance |
| 183 | layers" and "device layers". It was decided by Khronos to deprecate the |
| 184 | "device layer" functionality and only consider "instance layers". |
| 185 | Therefore, vkCreateDevice will use the layers specified at vkCreateInstance. |
| 186 | Additionally, vkEnumerateDeviceLayerProperties has been deprecated. |
| 187 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 188 | Developers may want to enable layers that are not enabled by the given |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 189 | application they are using. On Linux and Windows, the environment variable |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 190 | "VK\_INSTANCE\_LAYERS" can be used to enable |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 191 | additional layers which are not specified (enabled) by the application at |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 192 | vkCreateInstance. VK\_INSTANCE\_LAYERS is a colon |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 193 | (Linux)/semi-colon (Windows) separated list of layer names to enable. Order is |
| 194 | relevant with the first layer in the list being the topmost layer (closest to |
| 195 | the application) and the last layer in the list being the bottommost layer |
| 196 | (closest to the driver). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 197 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 198 | Application specified layers and user specified layers (via environment |
| 199 | variables) are aggregated and duplicates removed by the loader when enabling |
| 200 | layers. Layers specified via environment variable are topmost (closest to the |
| 201 | application) while layers specified by the application are bottommost. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 202 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 203 | An example of using these environment variables to activate the validation |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 204 | layer VK\_LAYER\_LUNARG\_parameter\_validation on Windows or Linux is as follows: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 205 | |
| 206 | ``` |
Mark Lobodzinski | 739391a | 2016-03-17 15:08:18 -0600 | [diff] [blame] | 207 | > $ export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_parameter_validation |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 208 | ``` |
| 209 | |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 210 | #### Implicit vs Explicit Layers |
| 211 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 212 | Some platforms, including Linux and Windows, support layers which are enabled |
| 213 | automatically by the loader rather than explicitly by the application (or via |
| 214 | environment variable). Explicit layers are those layers enabled by the |
| 215 | application (or environment variable) by providing the layer name. Implicit |
| 216 | layers are those layers enabled by the loader automatically. Any implicit |
| 217 | layers the loader discovers on the system in the appropriate location will be |
| 218 | enabled (subject to environment variable overrides described later). Discovery |
| 219 | of properly installed implicit and explicit layers is described later. |
| 220 | Explicitly enabling a layer that is implicitly enabled has no additional |
| 221 | effect: the layer will still be enabled implicitly by the loader. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 222 | |
Mark Young | 02ee538 | 2016-07-22 08:51:05 -0600 | [diff] [blame] | 223 | Implicit layers have an additional requirement over explicit layers in that they |
| 224 | require being able to be disabled by an environmental variable. This is due |
| 225 | to the fact that they are not visible to the application and could cause issues. |
| 226 | A good principle to keep in mind would be to define both an enable and disable |
| 227 | environment variable so the users can deterministicly enable the functionality. |
| 228 | On Desktop platforms (Windows and Linux), these enable/disable settings are |
| 229 | defined in the layer's JSON file. |
| 230 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 231 | Extensions are optional functionality provided by a layer, the loader or an |
| 232 | ICD. Extensions can modify the behavior of the Vulkan API and need to be |
| 233 | specified and registered with Khronos. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 234 | |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 235 | #### Instance/Device Extensions |
| 236 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 237 | Instance extensions can be discovered via |
| 238 | vkEnumerateInstanceExtensionProperties. Device extensions can be discovered via |
| 239 | vkEnumerateDeviceExtensionProperties. The loader discovers and aggregates all |
| 240 | extensions from layers (both explicit and implicit), ICDs and the loader before |
| 241 | reporting them to the application in vkEnumerate\*ExtensionProperties. The |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 242 | pLayerName parameter in these functions is used to select either a single layer |
| 243 | or the Vulkan platform implementation. If pLayerName is NULL, extensions from |
| 244 | Vulkan implementation components (including loader, implicit layers, and ICDs) |
| 245 | are enumerated. If pLayerName is equal to a discovered layer module name then |
| 246 | any extensions from that layer (which may be implicit or explicit) are |
| 247 | enumerated. Duplicate extensions (e.g. an implicit layer and ICD might report |
Jon Ashburn | 859c7fb | 2016-03-02 17:26:31 -0700 | [diff] [blame] | 248 | support for the same extension) are eliminated by the loader. For duplicates, the |
| 249 | ICD version is reported and the layer version is culled. Extensions must |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 250 | be enabled (in vkCreateInstance or vkCreateDevice) before they can be used. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 251 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 252 | Extension command entry points should be queried via vkGetInstanceProcAddr or |
| 253 | vkGetDeviceProcAddr. vkGetDeviceProcAddr can only be used to query for device |
| 254 | extension or core device entry points. Device entry points include any command |
| 255 | that uses a VkDevice as the first parameter or a dispatchable object that is a |
| 256 | child of a VkDevice (currently this includes VkQueue and VkCommandBuffer). |
| 257 | vkGetInstanceProcAddr can be used to query either device or instance extension |
| 258 | entry points in addition to all core entry points. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 259 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 260 | VkGetDeviceProcAddr is particularly interesting because it will provide the |
| 261 | most efficient way to call into the ICD. For example, the diagram below shows |
| 262 | what could happen if the application were to use vkGetDeviceProcAddr for the |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 263 | function "vkGetDeviceQueue" and "vkDestroyDevice" but not "vkAllocateMemory". |
| 264 | The resulting function pointer (fpGetDeviceQueue) would be the ICD's entry |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 265 | point if the loader and any enabled layers do not need to see that call. Even |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 266 | if an enabled layer intercepts the call (e.g. vkDestroyDevice) the loader |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 267 | trampoline code is skipped for function pointers obtained via |
| 268 | vkGetDeviceProcAddr. This also means that function pointers obtained via |
| 269 | vkGetDeviceProcAddr will only work with the specific VkDevice it was created |
| 270 | for, using it with another device has undefined results. For extensions, |
| 271 | Get\*ProcAddr will often be the only way to access extension API features. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 272 | |
Jon Ashburn | c250556 | 2016-02-15 10:19:26 -0700 | [diff] [blame] | 273 |  |
Courtney Goeltzenleuchter | ab3a466 | 2016-02-14 10:48:22 -0700 | [diff] [blame] | 274 | |
Mark Young | 78f88c8 | 2016-07-19 11:49:45 -0600 | [diff] [blame] | 275 | ##### WSI Extensions |
| 276 | |
| 277 | Khronos approved WSI extensions are available and provide Windows System Integration |
| 278 | support for various execution environments. It is important to understand that some WSI |
| 279 | extensions are valid for all targets, but others are particular to a given execution |
| 280 | environment (and loader). This desktop loader (currently targeting Windows and Linux) |
| 281 | only enables those WSI extensions that are appropriate to the current environment. |
| 282 | For the most part, the selection is done in the loader using compile-time preprocessor |
| 283 | flags. All versions of the desktop loader currently expose at least the following WSI |
| 284 | extension support: |
| 285 | - VK_KHR_surface |
| 286 | - VK_KHR_swapchain |
| 287 | - VK_KHR_display |
| 288 | |
| 289 | In addition, each of the following OS targets for the loader support target-specific extensions: |
| 290 | - **Windows** : VK_KHR_win32_surface |
| 291 | - **Linux (default)** : VK_KHR_xcb_surface and VK_KHR_xlib_surface |
| 292 | - **Linux (Wayland build)** : VK_KHR_wayland_surface |
| 293 | - **Linux (Mir build)** : VK_KHR_mir_surface |
| 294 | |
| 295 | **NOTE:** Wayland and Mir targets are not fully supported at this time and should be considered |
| 296 | alpha quality. |
| 297 | |
| 298 | It is important to understand that while the loader may support the various entry-points |
| 299 | for these extensions, there is a hand-shake required to actually use them: |
| 300 | * At least one physical device must support the extension(s) |
| 301 | * The application must select such a physical device |
| 302 | * The application must request the extension(s) be enabled while creating the instance or logical device (This depends on whether or not the given extension works with an instance or a device). |
| 303 | * The instance and/or logical device creation must succeed. |
| 304 | |
| 305 | Only then can you expect to properly use a WSI extension in your Vulkan program. |
| 306 | |
| 307 | ##### New Extensions |
| 308 | |
| 309 | With the ability to expand Vulkan so easily, extensions will be created that the loader knows |
| 310 | nothing about. If the extension is a device extension, the loader will pass the unknown |
| 311 | entry-point down the device call chain ending with the appropriate ICD entry-points. |
| 312 | However, if the extension is an instance extension, the loader will fail to load it. |
| 313 | |
| 314 | *But why doesn't the loader support unknown instance extensions?* |
| 315 | <br/> |
| 316 | Let's look again at the Instance call chain: |
| 317 |  |
| 318 | |
| 319 | Notice that for a normal instance function call, the loader has to handle passing along the |
| 320 | function call to the available ICDs. If the loader has no idea of the parameters or return |
| 321 | value of the instance call, it can't properly pass information along to the ICDs. |
| 322 | There may be ways to do this, which will be explored in the future. However, for now, this |
| 323 | loader does not support any unknown instance extensions. |
| 324 | |
| 325 | Because the device call-chain does not pass through the loader terminator, this is not |
| 326 | a problem for device extensions. Instead, device extensions terminate directly in the |
| 327 | ICD they are associated with. |
| 328 | |
| 329 | *Is this a big problem?* |
| 330 | <br/> |
| 331 | No! Most extension functionality only affects a device and not an instance or a physical |
| 332 | device. Thus, the overwhelming majority of extensions will be device extensions rather than |
| 333 | instance extensions. |
| 334 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 335 | |
| 336 | ## Vulkan Installable Client Driver interface with the loader ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 337 | |
| 338 | ### ICD discovery |
| 339 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 340 | Vulkan allows multiple drivers each with one or more devices (represented by a |
| 341 | Vulkan VkPhysicalDevice object) to be used collectively. The loader is |
| 342 | responsible for discovering available Vulkan ICDs on the system. Given a list |
| 343 | of available ICDs, the loader can enumerate all the physical devices available |
| 344 | for an application and return this information to the application. The process |
| 345 | in which the loader discovers the available Installable Client Drivers (ICDs) |
| 346 | on a system is platform dependent. Windows, Linux and Android ICD discovery |
| 347 | details are listed below. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 348 | |
| 349 | #### Windows |
| 350 | |
| 351 | ##### Properly-Installed ICDs |
| 352 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 353 | In order to find properly-installed ICDs, the Vulkan loader will scan the |
| 354 | values in the following Windows registry key: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 355 | |
| 356 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers |
| 357 | |
Mark Young | 02ee538 | 2016-07-22 08:51:05 -0600 | [diff] [blame] | 358 | On 64-bit Windows, when a 32-bit application is triggered, the loader |
| 359 | will scan for 32-bit drivers in a separate area of the registry: |
| 360 | |
| 361 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\WOW6432Node\\Khronos\\Vulkan\\Drivers |
| 362 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 363 | For each value in this key which has DWORD data set to 0, the loader opens the |
| 364 | JSON format text information file (a.k.a. "manifest file") specified by the |
| 365 | name of the value. Each name must be a full pathname to the text manifest file. |
| 366 | The Vulkan loader will open each manifest file to obtain the name or pathname |
| 367 | of an ICD shared library (".dll") file. For example: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 368 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 369 | ``` |
| 370 | { |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 371 | "file_format_version": "1.0.0", |
| 372 | "ICD": { |
| 373 | "library_path": "path to ICD library", |
Tony Barbour | d83f06c | 2016-03-08 14:50:03 -0700 | [diff] [blame] | 374 | "api_version": "1.0.5" |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 375 | } |
| 376 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 377 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 378 | |
| 379 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 380 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 381 | pathname to an ICD shared library file, which the loader will attempt to load |
| 382 | using LoadLibrary(). If the ICD is specified via a filename, the shared library |
David Pinedo | 3e163ee | 2016-04-18 16:59:59 -0600 | [diff] [blame] | 383 | lives in the system's DLL search path (e.g. in the "C:\Windows\System32" |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 384 | folder). If the ICD is specified via a relative pathname, it is relative to the |
| 385 | path of the manifest file. Relative pathnames are those that do not start with |
| 386 | a drive specifier (e.g. "C:"), nor with a directory separator (i.e. the '\\' |
| 387 | character), but do contain at least one directory separator. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 388 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 389 | The "file\_format\_version" specifies a major.minor.patch version number in |
| 390 | case the format of the text information file changes in the future. If the same |
| 391 | ICD shared library supports multiple, incompatible versions of text manifest |
Mark Young | 02ee538 | 2016-07-22 08:51:05 -0600 | [diff] [blame] | 392 | file format versions, it must have separate JSON files for each (all of which may |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 393 | point to the same shared library). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 394 | |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 395 | The "api\_version" specifies the major.minor.patch version number of the Vulkan |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 396 | API that the shared library (referenced by "library\_path") was built with. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 397 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 398 | There are no rules about the name of the text information files (except the |
| 399 | .json suffix). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 400 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 401 | There are no rules about the name of the ICD shared library files. For example, |
| 402 | if the registry contains the following values, |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 403 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 404 | ``` |
| 405 | [HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\] |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 406 | |
David Pinedo | 3e163ee | 2016-04-18 16:59:59 -0600 | [diff] [blame] | 407 | "C:\vendor a\vk_vendora.json"=dword:00000000 |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 408 | |
David Pinedo | 3e163ee | 2016-04-18 16:59:59 -0600 | [diff] [blame] | 409 | "C:\windows\system32\vendorb_vk.json"=dword:00000000 |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 410 | |
David Pinedo | 3e163ee | 2016-04-18 16:59:59 -0600 | [diff] [blame] | 411 | "C:\windows\system32\vendorc_icd.json"=dword:00000000 |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 412 | ``` |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 413 | then the loader will open the following text information files, with the |
| 414 | specified contents: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 415 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 416 | | Text File Name | Text File Contents | |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 417 | |----------------|--------------------| |
David Pinedo | 3e163ee | 2016-04-18 16:59:59 -0600 | [diff] [blame] | 418 | |vk\_vendora.json | "ICD": { "library\_path": "C:\VENDOR A\vk_vendora.dll", "api_version": "1.0.5" } | |
Tony Barbour | d83f06c | 2016-03-08 14:50:03 -0700 | [diff] [blame] | 419 | | vendorb\_vk.json | "ICD": { "library\_path": "vendorb\_vk.dll", "api_version": "1.0.5" } | |
| 420 | |vendorc\_icd.json | "ICD": { "library\_path": "vedorc\_icd.dll", "api_version": "1.0.5" }| |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 421 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 422 | Then the loader will open the three files mentioned in the "Text File Contents" |
| 423 | column, and then try to load and use the three shared libraries indicated by |
| 424 | the ICD.library\_path value. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 425 | |
| 426 | ##### Using Pre-Production ICDs |
| 427 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 428 | IHV developers (and sometimes other developers) need to use special, |
| 429 | pre-production ICDs. In some cases, a pre-production ICD may be in an |
| 430 | installable package. In other cases, a pre-production ICD may simply be a |
| 431 | shared library in the developer's build tree. In this latter case, we want to |
| 432 | allow developers to point to such an ICD without modifying the |
| 433 | properly-installed ICD(s) on their system. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 434 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 435 | This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, |
| 436 | which will override the mechanism used for finding properly-installed ICDs. In |
| 437 | other words, only the ICDs listed in "VK\_ICD\_FILENAMES" will be used. The |
| 438 | "VK\_ICD\_FILENAMES" environment variable is a semi-colon-separated list of ICD |
| 439 | text information files (aka manifest files), containing the following: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 440 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 441 | - A full pathname (e.g. "C:\\my\_build\\my\_icd.json") |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 442 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 443 | Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info |
| 444 | file for a developer-built ICD. A semi-colon is only used if more than one ICD |
| 445 | is listed. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 446 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 447 | For example, if a developer wants to refer to one ICD that they built, they |
| 448 | could set the "VK\_ICD\_FILENAMES" environment variable to: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 449 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 450 | C:\\my\_build\\my\_icd.json |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 451 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 452 | If a developer wants to refer to two ICDs, one of which is a properly-installed |
| 453 | ICD, they can use the full pathname of the text file: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 454 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 455 | C:\\Windows\\System32\\vendorc\_icd.json;C:\\my\_build\\my\_icd.json |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 456 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 457 | Notice the semi-colon between "C:\\Windows\\System32\\vendorc\_icd.json" and |
| 458 | "C:\\my\_build\\my\_icd.json". |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 459 | |
| 460 | #### Linux |
| 461 | |
| 462 | ##### Properly-Installed ICDs |
| 463 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 464 | In order to find properly-installed ICDs, the Vulkan loader will scan the files |
| 465 | in the following Linux directories: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 466 | |
Mark Young | 441653c | 2016-11-22 08:44:21 -0700 | [diff] [blame] | 467 | ``` |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 468 | /usr/local/etc/vulkan/icd.d |
| 469 | /usr/local/share/vulkan/icd.d |
| 470 | /etc/vulkan/icd.d |
| 471 | /usr/share/vulkan/icd.d |
| 472 | $HOME/.local/share/vulkan/icd.d |
Mark Young | 441653c | 2016-11-22 08:44:21 -0700 | [diff] [blame] | 473 | ``` |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 474 | |
| 475 | The "/usr/local/*" directories can be configured to be other directories at build time. |
Jon Ashburn | 7f00ca8 | 2016-02-24 12:00:55 -0700 | [diff] [blame] | 476 | |
| 477 | Where $HOME is the current home directory of the application's user id; this |
| 478 | path will be ignored for suid programs. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 479 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 480 | These directories will contain text information files (a.k.a. "manifest |
| 481 | files"), that use a JSON format. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 482 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 483 | The Vulkan loader will open each manifest file found to obtain the name or |
| 484 | pathname of an ICD shared library (".so") file. For example: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 485 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 486 | ``` |
| 487 | { |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 488 | "file_format_version": "1.0.0", |
| 489 | "ICD": { |
| 490 | "library_path": "path to ICD library", |
Tony Barbour | d83f06c | 2016-03-08 14:50:03 -0700 | [diff] [blame] | 491 | "api_version": "1.0.5" |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 492 | } |
| 493 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 494 | ``` |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 495 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 496 | pathname to an ICD shared library file. If the ICD is specified via a filename, |
| 497 | the loader will attempt to open that file as a shared object using dlopen(), |
| 498 | and the file must be in a directory that dlopen is configured to look in (Note: |
| 499 | various distributions are configured differently). A distribution is free to |
| 500 | create Vulkan-specific system directories (e.g. ".../vulkan/icd"), but is not |
| 501 | required to do so. If the ICD is specified via a relative pathname, it is |
| 502 | relative to the path of the info file. Relative pathnames are those that do not |
| 503 | start with, but do contain at least one directory separator (i.e. the '/' |
| 504 | character). For example, "lib/vendora.so" and "./vendora.so" are examples of |
| 505 | relative pathnames. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 506 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 507 | The "file\_format\_version" provides a major.minor.patch version number in case |
| 508 | the format of the manifest file changes in the future. If the same ICD shared |
| 509 | library supports multiple, incompatible versions of manifest file format |
| 510 | versions, it must have multiple manifest files (all of which may point to the |
| 511 | same shared library). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 512 | |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 513 | The "api\_version" specifies the major.minor.patch version number of the Vulkan |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 514 | API that the shared library (referenced by "library\_path") was built with. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 515 | |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 516 | The "/usr/local/etc/vulkan/icd.d" and "/usr/local/share/vulkan/icd.d" |
| 517 | directories are for locally-built ICDs. |
| 518 | |
| 519 | The "/etc/vulkan/icd.d" directory is for |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 520 | ICDs that are installed from non-Linux-distribution-provided packages. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 521 | |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 522 | The "/usr/share/vulkan/icd.d" directory is for ICDs that are installed from |
| 523 | Linux-distribution-provided packages. |
| 524 | |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 525 | There are no rules about the name of the text files (except the .json suffix). |
| 526 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 527 | There are no rules about the name of the ICD shared library files. For example, |
| 528 | if the "/usr/share/vulkan/icd.d" directory contain the following files, with |
| 529 | the specified contents: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 530 | |
Jon Ashburn | 26ed3f3 | 2016-02-14 21:54:52 -0700 | [diff] [blame] | 531 | | Text File Name | Text File Contents | |
| 532 | |-------------------|------------------------| |
Tony Barbour | d83f06c | 2016-03-08 14:50:03 -0700 | [diff] [blame] | 533 | | vk\_vendora.json | "ICD": { "library\_path": "vendora.so", "api_version": "1.0.5" } | |
| 534 | | vendorb\_vk.json | "ICD": { "library\_path": "vendorb\_vulkan\_icd.so", "api_version": "1.0.5" } | |
| 535 | | vendorc\_icd.json | "ICD": { "library\_path": "/usr/lib/VENDORC/icd.so", "api_version": "1.0.5" } | |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 536 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 537 | then the loader will open the three files mentioned in the "Text File Contents" |
| 538 | column, and then try to load and use the three shared libraries indicated by |
| 539 | the ICD.library\_path value. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 540 | |
| 541 | ##### Using Pre-Production ICDs |
| 542 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 543 | IHV developers (and sometimes other developers) need to use special, |
| 544 | pre-production ICDs. In some cases, a pre-production ICD may be in an |
| 545 | installable package. In other cases, a pre-production ICD may simply be a |
| 546 | shared library in the developer's build tree. In this latter case, we want to |
| 547 | allow developers to point to such an ICD without modifying the |
| 548 | properly-installed ICD(s) on their system. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 549 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 550 | This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, |
| 551 | which will override the mechanism used for finding properly-installed ICDs. In |
| 552 | other words, only the ICDs listed in "VK\_ICD\_FILENAMES" will be used. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 553 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 554 | The "VK\_ICD\_FILENAMES" environment variable is a colon-separated list of ICD |
| 555 | manifest files, containing the following: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 556 | |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 557 | - A filename (e.g. "libvkicd.json") in the |
| 558 | "/usr/local/etc/vulkan/icd.d", |
| 559 | "/usr/local/share/vulkan/icd.d", |
| 560 | "/etc/vulkan/icd.d", |
| 561 | "/usr/share/vulkan/icd.d", |
| 562 | "$HOME/.local/share/vulkan/icd.d" |
| 563 | directories |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 564 | |
| 565 | - A full pathname (e.g. "/my\_build/my\_icd.json") |
| 566 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 567 | Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info |
| 568 | file for a developer-built ICD. A colon is only used if more than one ICD is |
| 569 | listed. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 570 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 571 | For example, if a developer wants to refer to one ICD that they built, they |
| 572 | could set the "VK\_ICD\_FILENAMES" environment variable to: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 573 | |
| 574 | /my\_build/my\_icd.json |
| 575 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 576 | If a developer wants to refer to two ICDs, one of which is a properly-installed |
| 577 | ICD, they can use the name of the text file in the system directory: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 578 | |
| 579 | vendorc\_vulkan.json:/my\_build/my\_icd.json |
| 580 | |
| 581 | Notice the colon between "vendorc\_vulkan.json" and "/my\_build/my\_icd.json". |
| 582 | |
| 583 | NOTE: this environment variable will be ignored for suid programs. |
| 584 | |
| 585 | #### Android |
| 586 | |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 587 | The Android loader lives in the system library folder. The location cannot be |
| 588 | changed. The loader will load the driver/ICD via hw_get_module with the ID |
| 589 | of "vulkan". Due to security policies in Android none of this can be modified |
| 590 | under normal use. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 591 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 592 | <br/> |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 593 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 594 | ## ICD interface requirements ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 595 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 596 | Generally, for all Vulkan commands issued by an application, the loader can be |
Mark Young | 6d026a7 | 2016-06-01 17:49:30 -0600 | [diff] [blame] | 597 | viewed as a pass through. That is, the loader generally doesn't modify the |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 598 | commands or their parameters, but simply calls the ICDs entry point for that |
| 599 | command. There are specific additional interface requirements an ICD needs to comply with that |
| 600 | are over and above any requirements from the Vulkan specification including WSI extension specification. |
| 601 | These addtional requirements are versioned to allow flexibility in the future. |
| 602 | These interface requirements will be set forth in the following sections: 1) describing |
| 603 | which "loader-ICD" interface version is available, 2) detailing the most recent interface version; |
| 604 | 3) the supported, older interface requirements will be described as differences |
| 605 | from the most recent interface version. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 606 | |
| 607 | #### Windows and Linux |
| 608 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 609 | ##### Version Negotiation Between Loader and ICDs |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 610 | |
Mark Young | a7c51fd | 2016-09-16 10:18:42 -0600 | [diff] [blame] | 611 | All ICDs (supporting interface version 2 or higher) must export the following |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 612 | function that is used for determination of the interface version that will be used. |
| 613 | This entry point is not a part of the Vulkan API itself, only a private interface |
| 614 | between the loader and ICDs. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 615 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 616 | VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion); |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 617 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 618 | This entry point reports the "loader-ICD" interface version supported by both the loader and the ICD. |
| 619 | The loader informs the ICD of it's desired interface version (typically the latest) via the |
| 620 | pSupportedVersion parameter. |
| 621 | This call is the first call made by the loader into the ICD (prior to any calls to |
| 622 | vk\_icdGetInstanceProcAddr). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 623 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 624 | If a loader sees that an ICD does not export this symbol it knows that it's dealing |
| 625 | with a legacy ICD supporting either interface version 0 or 1. |
| 626 | Similarly, if an ICD sees a call to vk\_icdGetInstanceProcAddr before a call to |
| 627 | vk_icdGetLoaderICDInterfaceVersion then it knows that it's dealing with a legacy loader |
| 628 | supporting version 0 or 1. |
Mark Young | 02ee538 | 2016-07-22 08:51:05 -0600 | [diff] [blame] | 629 | **Note** if the loader calls vk\_icdGetInstanceProcAddr first it supports at least version 1, |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 630 | otherwise the loader only supports version 0. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 631 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 632 | The pSupportedVersion parameter is both an input and output parameter. |
| 633 | It is filled in by the loader before the call with the desired latest interface version supported by the loader. |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 634 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 635 | If the ICD receiving the call no longer supports the interface version provided |
| 636 | by the loader (due to deprecation) then it can report VK_ERROR_INCOMPATIBLE_DRIVER error, |
| 637 | otherwise it sets the value pointed by pSupportedVersion to the latest interface |
| 638 | version supported by both the ICD and the loader and returns VK_SUCCESS. |
| 639 | The ICD should report VK_SUCCESS in case the loader provided interface version |
| 640 | is newer than that supported by the ICD, as it's the loader's responsibility to |
| 641 | determine whether it can support the older interface version supported by the ICD. |
| 642 | The ICD should also report VK_SUCCESS in the case it's interface version is greater |
| 643 | than the loader's, but return the loader's version. Thus, upon return of VK_SUCCESS |
| 644 | the pSupportedVersion will contain the desired interface version to be used by the ICD. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 645 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 646 | If the loader receives back an interface version from the ICD that the loader no longer |
| 647 | supports (due to deprecation) or it receives a VK_ERROR_INCOMPATIBLE_DRIVER error |
| 648 | instead of VK_SUCCESS then the loader will treat the ICD as incompatible |
| 649 | and will not load it for use. In this case the application will not see the ICDs vkPhysicalDevice |
| 650 | during enumeration. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 651 | |
Mark Young | a7c51fd | 2016-09-16 10:18:42 -0600 | [diff] [blame] | 652 | ##### Loader Version 3 Interface Changes |
| 653 | |
| 654 | The primary change occuring in version 3 of the loader/ICD interface is to allow an ICD to |
| 655 | handle Creation/Destruction of their own KHR_surfaces. Up until this point, the loader created |
| 656 | a surface object that was used by all ICDs. However, some ICDs may want to provide their |
| 657 | own surface handles. If an ICD chooses to enable this support, they must export support for |
| 658 | version 3 of the Loader/ICD interface as well as any Vulkan command that uses a KHR_surface handle, |
| 659 | such as: |
| 660 | - vkCreateXXXSurfaceKHR (where XXX is the platform specific identifier [i.e.CreateWin32SurfaceKHR for Windows]) |
| 661 | - vkDestroySurfaceKHR |
| 662 | - vkCreateSwapchainKHR |
| 663 | - vkGetPhysicalDeviceSurfaceSupportKHR |
| 664 | - vkGetPhysicalDeviceSurfaceCapabilitiesKHR |
| 665 | - vkGetPhysicalDeviceSurfaceFormatsKHR |
| 666 | - vkGetPhysicalDeviceSurfacePresentModesKHR |
| 667 | |
| 668 | An ICD can still choose to not take advantage of this functionality by simply not exposing the |
| 669 | above the vkCreateXXXSurfaceKHR and vkDestroySurfaceKHR commands. |
| 670 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 671 | ##### Loader Version 2 Interface Requirements |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 672 | |
Mark Young | a7c51fd | 2016-09-16 10:18:42 -0600 | [diff] [blame] | 673 | Version 2 interface has requirements in three areas: |
| 674 | 1. ICD Vulkan entry point discovery, |
| 675 | 2. KHR_surface related requirements in the WSI extensions, |
| 676 | 3. Vulkan dispatchable object creation requirements. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 677 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 678 | ###### ICD Vulkan entry point discovery |
| 679 | All ICDs must export the following function that is used for discovery of ICD Vulkan entry points. |
| 680 | This entry point is not a part of the Vulkan API itself, only a private interface between the loader and ICDs for version 1 and higher interfaces. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 681 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 682 | VKAPI\_ATTR PFN\_vkVoidFunction VKAPI\_CALL vk\_icdGetInstanceProcAddr(VkInstance instance, const char* pName); |
| 683 | |
| 684 | This function has very similar semantics to the Vulkan command vkGetInstanceProcAddr. |
| 685 | vk\_icdGetInstanceProcAddr returns valid function pointers for all the global level |
| 686 | and instance level Vulkan commands, and also for vkGetDeviceProcAddr. |
| 687 | Global level commands are those |
| 688 | which contain no dispatchable object as the first parameter, such as |
| 689 | vkCreateInstance and vkEnumerateInstanceExtensionProperties. The ICD must |
| 690 | support querying global level entry points by calling |
| 691 | vk\_icdGetInstanceProcAddr with a NULL VkInstance parameter. Instance level |
| 692 | commands are those that have either VkInstance, or VkPhysicalDevice as the |
| 693 | first parameter dispatchable object. Both core entry points and any instance |
| 694 | extension entry points the ICD supports should be available via |
| 695 | vk\_icdGetInstanceProcAddr. Future Vulkan instance extensions may define and |
| 696 | use new instance level dispatchable objects other than VkInstance and |
| 697 | VkPhysicalDevice, in which case extension entry points using these newly |
| 698 | defined dispatchable objects must be queryable via vk\_icdGetInstanceProcAddr. |
| 699 | |
| 700 | All other Vulkan entry points must either NOT be exported from the ICD |
| 701 | library or else NOT use the official Vulkan function names if they are |
| 702 | exported. This requirement is for ICD libraries that include other |
| 703 | functionality (such as OpenGL library) and thus could be loaded by the |
| 704 | application prior to when the Vulkan loader library is loaded by the |
| 705 | application. In other words, the ICD library exported Vulkan symbols must not |
| 706 | clash with the loader's exported Vulkan symbols. |
| 707 | |
| 708 | Beware of interposing by dynamic OS library loaders if the official Vulkan |
| 709 | names are used. On Linux, if official names are used, the ICD library must be |
| 710 | linked with -Bsymbolic. |
| 711 | |
| 712 | ###### Handling KHR_surface objects in the WSI extensions |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 713 | Normally, ICDs handle object creation and destruction for various Vulkan |
| 714 | objects. The WSI surface extensions for Linux and Windows |
| 715 | (VK\_KHR\_win32\_surface, VK\_KHR\_xcb\_surface, VK\_KHR\_xlib\_surface, |
| 716 | VK\_KHR\_mir\_surface, VK\_KHR\_wayland\_surface, and VK\_KHR\_surface) are |
| 717 | handled differently. For these extensions, the VkSurfaceKHR object creation and |
| 718 | destruction is handled by the loader as follows: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 719 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 720 | 1. Loader handles the vkCreate\*SurfaceKHR() and vkDestroySurfaceKHR() |
| 721 | functions including creating/destroying the VkSurfaceKHR object. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 722 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 723 | 2. VkSurfaceKHR objects have the underlying structure (VkIcdSurface\*) as |
| 724 | defined in include/vulkan/vk\_icd.h. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 725 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 726 | 3. ICDs can cast any VkSurfaceKHR object to a pointer to the appropriate |
| 727 | VkIcdSurface\* structure. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 728 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 729 | 4. VkIcdSurface\* structures include VkIcdSurfaceWin32, VkIcdSurfaceXcb, |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 730 | VkIcdSurfaceXlib, VkIcdSurfaceMir, and VkIcdSurfaceWayland. The first field |
| 731 | in the structure is a VkIcdSurfaceBase enumerant that indicates whether the |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 732 | surface object is Win32, Xcb, Xlib, Mir, or Wayland. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 733 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 734 | ###### ICD dispatchable object creation |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 735 | As previously covered, the loader requires dispatch tables to be accessible |
| 736 | within Vulkan dispatchable objects, which include VkInstance, VkPhysicalDevice, |
| 737 | VkDevice, VkQueue, and VkCommandBuffer. The specific requirements on all |
| 738 | dispatchable objects created by ICDs are as follows: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 739 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 740 | - All dispatchable objects created by an ICD can be cast to void \*\* |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 741 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 742 | - The loader will replace the first entry with a pointer to the dispatch table |
| 743 | which is owned by the loader. This implies three things for ICD drivers: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 744 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 745 | 1. The ICD must return a pointer for the opaque dispatchable object handle. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 746 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 747 | 2. This pointer points to a regular C structure with the first entry being a |
| 748 | pointer. Note: for any C\++ ICD's that implement VK objects directly as C\++ |
| 749 | classes. The C\++ compiler may put a vtable at offset zero if your class is |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 750 | non-POD due to the use of a virtual function. In this case use a regular C |
| 751 | structure (see below). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 752 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 753 | 3. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the created |
| 754 | dispatchable objects, as follows (see include/vulkan/vk\_icd.h): |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 755 | |
| 756 | ``` |
| 757 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 758 | #include "vk_icd.h" |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 759 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 760 | union _VK_LOADER_DATA { |
| 761 | uintptr loadermagic; |
| 762 | void *loaderData; |
| 763 | } VK_LOADER_DATA; |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 764 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 765 | vkObj alloc_icd_obj() |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 766 | { |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 767 | vkObj *newObj = alloc_obj(); |
| 768 | ... |
| 769 | // Initialize pointer to loader's dispatch table with ICD_LOADER_MAGIC |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 770 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 771 | set_loader_magic_value(newObj); |
| 772 | ... |
| 773 | return newObj; |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 774 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 775 | ``` |
| 776 | |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 777 | ##### Loader Version 0 and 1 Interface Differences |
| 778 | |
| 779 | Version 0 and 1 interfaces do not support version negotiation via vk\_icdNegotiateLoaderICDInterfaceVersion. |
| 780 | ICDs can distinguish version 0 and version 1 interfaces as follows: |
| 781 | if the loader calls vk\_icdGetInstanceProcAddr first it supports version 1, |
| 782 | otherwise the loader only supports version 0. |
| 783 | |
| 784 | Version 0 interface does not support vk\_icdGetInstanceProcAddr. Version 0 interface requirements for |
| 785 | obtaining ICD Vulkan entry points are as follows: |
| 786 | |
| 787 | - vkGetInstanceProcAddr exported in the ICD library and returns valid function |
| 788 | pointers for all the Vulkan API entry points; |
| 789 | |
| 790 | - vkCreateInstance exported in the ICD library; |
| 791 | |
| 792 | - vkEnumerateInstanceExtensionProperties exported in the ICD library; |
| 793 | |
| 794 | |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 795 | Additional Notes: |
| 796 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 797 | - The loader will filter out extensions requested in vkCreateInstance and |
| 798 | vkCreateDevice before calling into the ICD; Filtering will be of extensions |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 799 | advertised by entities (e.g. layers) different from the ICD in question. |
| 800 | - The loader will not call the ICD for vkEnumerate\*LayerProperties() as layer |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 801 | properties are obtained from the layer libraries and layer JSON files. |
| 802 | - If an ICD library wants to implement a layer it can do so by having the |
| 803 | appropriate layer JSON manifest file refer to the ICD library file. |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 804 | - The loader will not call the ICD for |
| 805 | vkEnumerate\*ExtensionProperties(pLayerName != NULL). |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 806 | - ICDs creating new dispatchable objects via device extensions need to initialize |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 807 | the created dispatchable object. The loader has generic trampoline code for unknown |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 808 | device extensions. This generic trampoline code doesn't initialize the dispatch table within |
Jon Ashburn | 54791f6 | 2016-04-22 14:40:07 -0600 | [diff] [blame] | 809 | the newly created object. See the section for more information on how to initialize created |
| 810 | dispatchable objects for extensions non known by the loader. [layer link](#creating-new-dispatchable-objects) |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 811 | |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 812 | #### Android |
| 813 | |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 814 | The Android loader uses the same protocol for initializing the dispatch |
| 815 | table as described above. The only difference is that the Android |
| 816 | loader queries layer and extension information directly from the |
| 817 | respective libraries and does not use the json manifest files used |
| 818 | by the Windows and Linux loaders. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 819 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 820 | <br/> |
| 821 | |
| 822 | ## Vulkan layer interface with the loader ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 823 | |
| 824 | ### Layer discovery |
| 825 | |
| 826 | #### Windows |
| 827 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 828 | <a name="ManifestFileExample"></a> |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 829 | ##### Properly-Installed Layers |
| 830 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 831 | In order to find properly-installed layers, the Vulkan loader will use a |
| 832 | similar mechanism as used for ICDs. Text information files (aka manifest |
| 833 | files), that use a JSON format, are read in order to identify the names and |
| 834 | attributes of layers and their extensions. The use of manifest files allows the |
| 835 | loader to avoid loading any shared library files when the application does not |
| 836 | query nor request any extensions. Layers and extensions have additional |
| 837 | complexity, and so their manifest files contain more information than ICD info |
| 838 | files. For example, a layer shared library file may contain multiple |
| 839 | layers/extensions (perhaps even an ICD). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 840 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 841 | In order to find properly-installed layers, the Vulkan loader will scan the |
| 842 | values in the following Windows registry keys: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 843 | |
| 844 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers |
| 845 | |
| 846 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers |
| 847 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 848 | Explicit layers are those which are enabled by an application (e.g. with the |
| 849 | vkCreateInstance function), or by an environment variable (as mentioned |
| 850 | previously). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 851 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 852 | Implicit layers are those which are enabled by their existence. For example, |
| 853 | certain application environments (e.g. Steam or an automotive infotainment |
| 854 | system) may have layers which they always want enabled for all applications |
| 855 | that they start. Other implicit layers may be for all applications started on a |
| 856 | given system (e.g. layers that overlay frames-per-second). Implicit layers are |
| 857 | enabled automatically, whereas explicit layers must be enabled explicitly. What |
| 858 | distinguishes a layer as implicit or explicit is by which registry key its |
| 859 | layer information file is referenced by. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 860 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 861 | For each value in these keys which has DWORD data set to 0, the loader opens |
| 862 | the JSON manifest file specified by the name of the value. Each name must be a |
| 863 | full pathname to the manifest file. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 864 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 865 | The Vulkan loader will open each info file to obtain information about the |
| 866 | layer, including the name or pathname of a shared library (".dll") file. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 867 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 868 | This manifest file is in the JSON format as shown in the following example. |
| 869 | See the section [Layer Library Manifest File](#LayerLibraryManifestFile) for more information about each of the nodes in the JSON file. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 870 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 871 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 872 | { |
Mark Young | c3a6d2e | 2016-06-13 14:49:53 -0600 | [diff] [blame] | 873 | "file_format_version" : "1.0.0", |
| 874 | "layer": { |
| 875 | "name": "VK_LAYER_LUNARG_overlay", |
| 876 | "type": "INSTANCE", |
| 877 | "library_path": "vkOverlayLayer.dll" |
| 878 | "api_version" : "1.0.5", |
| 879 | "implementation_version" : "2", |
| 880 | "description" : "LunarG HUD layer", |
| 881 | "functions": { |
| 882 | "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr", |
| 883 | "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr" |
| 884 | }, |
| 885 | "instance_extensions": [ |
| 886 | { |
| 887 | "name": "VK_EXT_debug_report", |
| 888 | "spec_version": "1" |
| 889 | }, |
| 890 | { |
| 891 | "name": "VK_VENDOR_ext_x", |
| 892 | "spec_version": "3" |
| 893 | } |
| 894 | ], |
| 895 | "device_extensions": [ |
| 896 | { |
| 897 | "name": "VK_EXT_debug_marker", |
| 898 | "spec_version": "1", |
| 899 | "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"] |
| 900 | } |
| 901 | ], |
| 902 | "enable_environment": { |
| 903 | "ENABLE_LAYER_OVERLAY_1": "1" |
| 904 | } |
| 905 | "disable_environment": { |
| 906 | "DISABLE_LAYER_OVERLAY_1": "" |
| 907 | } |
| 908 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 909 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 910 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 911 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 912 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 913 | pathname to a layer shared library (".dll") file, which the loader will attempt |
| 914 | to load using LoadLibrary(). If the layer is specified via a relative pathname, |
| 915 | it is relative to the path of the info file (e.g. for cases when an application |
| 916 | provides a layer that is in the same folder hierarchy as the rest of the |
| 917 | application files). If the layer is specified via a filename, the shared |
| 918 | library lives in the system's DLL search path (e.g. in the |
| 919 | "C:\\Windows\\System32" folder). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 920 | |
Mark Young | c3a6d2e | 2016-06-13 14:49:53 -0600 | [diff] [blame] | 921 | If defining multiple layers in a single JSON file prior to "file\_format\_version" |
| 922 | 1.0.1, you would simply define multiple "layer" objects. However, this is not |
| 923 | valid JSON syntax. Instead, you should now define "file\_format\_version" |
| 924 | 1.0.1 (or newer) and use the new "layers" array object as seen in the |
| 925 | following example: |
| 926 | |
| 927 | ``` |
| 928 | { |
| 929 | "file_format_version" : "1.0.1", |
| 930 | "layers": [ |
| 931 | { |
| 932 | "name": "VK_LAYER_layer_name1", |
| 933 | "type": "INSTANCE", |
| 934 | ... |
| 935 | }, |
| 936 | { |
| 937 | "name": "VK_LAYER_layer_name2", |
| 938 | "type": "INSTANCE", |
| 939 | ... |
| 940 | } |
| 941 | ] |
| 942 | } |
| 943 | ``` |
| 944 | |
| 945 | You could use the "layers" array object to define a single layer, as long as |
| 946 | your "file\_format\_version" is defined to at least 1.0.1. It is functionally the |
| 947 | same as using a single "layer" object. |
| 948 | |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 949 | There are no rules about the name of the text files (except the .json suffix). |
| 950 | |
| 951 | There are no rules about the name of the layer shared library files. |
| 952 | |
| 953 | ##### Using Pre-Production Layers |
| 954 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 955 | As with ICDs, developers may need to use special, pre-production layers, |
| 956 | without modifying the properly-installed layers. This need is met with the use |
| 957 | of the "VK\_LAYER\_PATH" environment variable, which will override the |
| 958 | mechanism using for finding properly-installed layers. Because many layers may |
| 959 | exist on a system, this environment variable is a semi-colon-separated list of |
| 960 | folders that contain layer info files. Only the folder listed in |
| 961 | "VK\_LAYER\_PATH" will be scanned for info files. Each semi-colon-separated |
| 962 | entry is: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 963 | |
| 964 | - The full pathname of a folder containing layer info files |
| 965 | |
| 966 | #### Linux |
| 967 | |
| 968 | ##### Properly-Installed Layers |
| 969 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 970 | In order to find properly-installed layers, the Vulkan loader will use a |
| 971 | similar mechanism as used for ICDs. Text information files, that use a JSON |
| 972 | format, are read in order to identify the names and attributes of layers and |
| 973 | their extensions. The use of text info files allows the loader to avoid loading |
| 974 | any shared library files when the application does not query nor request any |
| 975 | extensions. Layers and extensions have additional complexity, and so their info |
| 976 | files contain more information than ICD info files. For example, a layer shared |
| 977 | library file may contain multiple layers/extensions (perhaps even an ICD). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 978 | |
| 979 | The Vulkan loader will scan the files in the following Linux directories: |
| 980 | |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 981 | /usr/local/etc/vulkan/explicit_layer.d |
| 982 | /usr/local/etc/vulkan/implicit_layer.d |
| 983 | /usr/local/share/vulkan/explicit_layer.d |
| 984 | /usr/local/share/vulkan/implicit_layer.d |
| 985 | /etc/vulkan/explicit_layer.d |
| 986 | /etc/vulkan/implicit_layer.d |
| 987 | /usr/share/vulkan/explicit_layer.d |
| 988 | /usr/share/vulkan/implicit_layer.d |
| 989 | $HOME/.local/share/vulkan/explicit_layer.d |
| 990 | $HOME/.local/share/vulkan/implicit_layer.d |
| 991 | |
| 992 | The "/usr/local/*" directories can be configured to be other directories at build time. |
Jon Ashburn | 7f00ca8 | 2016-02-24 12:00:55 -0700 | [diff] [blame] | 993 | |
| 994 | Where $HOME is the current home directory of the application's user id; this |
| 995 | path will be ignored for suid programs. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 996 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 997 | Explicit layers are those which are enabled by an application (e.g. with the |
| 998 | vkCreateInstance function), or by an environment variable (as mentioned |
| 999 | previously). Implicit layers are those which are enabled by their existence. |
| 1000 | For example, certain application environments (e.g. Steam or an automotive |
| 1001 | infotainment system) may have layers which they always want enabled for all |
| 1002 | applications that they start. Other implicit layers may be for all applications |
| 1003 | started on a given system (e.g. layers that overlay frames-per-second). |
| 1004 | Implicit layers are enabled automatically, whereas explicit layers must be |
| 1005 | enabled explicitly. What distinguishes a layer as implicit or explicit is by |
| 1006 | which directory its layer information file exists in. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1007 | |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 1008 | The "/usr/local/etc/vulkan/\*\_layer.d" and "/usr/local/share/vulkan/\*\_layer.d" |
| 1009 | directories are for layers that are installed from locally-built sources. |
| 1010 | |
| 1011 | The "/etc/vulkan/\*\_layer.d" directories are for layers that are installed from |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1012 | non-Linux-distribution-provided packages. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1013 | |
Karl Schultz | 1f58d7e | 2016-10-31 15:58:21 -0600 | [diff] [blame] | 1014 | The "/usr/share/vulkan/\*\_layer.d" directories are for layers that are |
| 1015 | installed from Linux-distribution-provided packages. |
| 1016 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1017 | This manifest file is in the JSON format as shown in the following example. |
| 1018 | See the section [Layer Library Manifest File](#LayerLibraryManifestFile) for more information about each of the nodes in the JSON file. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1019 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1020 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1021 | { |
Mark Young | c3a6d2e | 2016-06-13 14:49:53 -0600 | [diff] [blame] | 1022 | "file_format_version" : "1.0.0", |
| 1023 | "layer": { |
| 1024 | "name": "VK_LAYER_LUNARG_overlay", |
| 1025 | "type": "INSTANCE", |
| 1026 | "library_path": "libvkOverlayLayer.so" |
| 1027 | "api_version" : "1.0.5", |
| 1028 | "implementation_version" : "2", |
| 1029 | "description" : "LunarG HUD layer", |
| 1030 | "functions": { |
| 1031 | "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr", |
| 1032 | "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr" |
| 1033 | }, |
| 1034 | "instance_extensions": [ |
| 1035 | { |
| 1036 | "name": "VK_EXT_debug_report", |
| 1037 | "spec_version": "1" |
| 1038 | }, |
| 1039 | { |
| 1040 | "name": "VK_VENDOR_ext_x", |
| 1041 | "spec_version": "3" |
| 1042 | } |
| 1043 | ], |
| 1044 | "device_extensions": [ |
| 1045 | { |
| 1046 | "name": "VK_EXT_debug_marker", |
| 1047 | "spec_version": "1", |
| 1048 | "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"] |
| 1049 | } |
| 1050 | ], |
| 1051 | "enable_environment": { |
| 1052 | "ENABLE_LAYER_OVERLAY_1": "1" |
| 1053 | }, |
| 1054 | "disable_environment": { |
| 1055 | "DISABLE_LAYER_OVERLAY_1": "" |
| 1056 | } |
| 1057 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1058 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1059 | ``` |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1060 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 1061 | pathname to a layer shared library (".so") file, which the loader will attempt |
| 1062 | to load using dlopen(). If the layer is specified via a filename, the loader |
| 1063 | will attempt to open that file as a shared object using dlopen(), and the file |
| 1064 | must be in a directory that dlopen is configured to look in (Note: various |
| 1065 | distributions are configured differently). A distribution is free to create |
| 1066 | Vulkan-specific system directories (e.g. ".../vulkan/layers"), but is not |
| 1067 | required to do so. If the layer is specified via a relative pathname, it is |
| 1068 | relative to the path of the info file (e.g. for cases when an application |
| 1069 | provides a layer that is in the same directory hierarchy as the rest of the |
| 1070 | application files). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1071 | |
| 1072 | There are no rules about the name of the text files (except the .json suffix). |
| 1073 | |
| 1074 | There are no rules about the name of the layer shared library files. |
| 1075 | |
| 1076 | ##### Using Pre-Production Layers |
| 1077 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1078 | As with ICDs, developers may need to use special, pre-production layers, |
| 1079 | without modifying the properly-installed layers. This need is met with the use |
| 1080 | of the "VK\_LAYER\_PATH" environment variable, which will override the |
| 1081 | mechanism using for finding properly-installed layers. Because many layers may |
| 1082 | exist on a system, this environment variable is a colon-separated list of |
| 1083 | directories that contain layer info files. Only the directories listed in |
| 1084 | "VK\_LAYER\_PATH" will be scanned for info files. Each colon-separated entry |
| 1085 | is: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1086 | |
| 1087 | - The full pathname of a directory containing layer info files |
| 1088 | |
| 1089 | NOTE: these environment variables will be ignored for suid programs. |
| 1090 | |
| 1091 | #### Android |
| 1092 | |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 1093 | The recommended way to enable layers is for applications |
| 1094 | to programatically enable them. The layers are provided by the application |
| 1095 | and must live in the application's library folder. The application |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1096 | enables the layers at vkCreateInstance as any Vulkan |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 1097 | application would. |
| 1098 | An application enabled for debug has more options. It can enumerate and enable |
Karl Schultz | fb5e4bc | 2016-10-31 08:52:38 -0600 | [diff] [blame] | 1099 | layers located in /data/local/debug/vulkan. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1100 | |
Mark Young | cb6e670 | 2016-07-20 11:38:53 -0600 | [diff] [blame] | 1101 | <br/> |
| 1102 | |
| 1103 | ## Layer interface requirements ## |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1104 | |
| 1105 | #### Architectural interface overview |
| 1106 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1107 | There are two key architectural features that drive the loader to layer library |
| 1108 | interface: 1) separate and distinct instance and device call chains, and 2) |
| 1109 | distributed dispatch. First these architectural features will be described and |
| 1110 | then the detailed interface will be specified. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1111 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1112 | Call chains are the links of calls for a given Vulkan command from layer module |
| 1113 | to layer module with the loader and or the ICD being the bottom most command. |
| 1114 | Call chains are constructed at both the instance level and the device level by |
| 1115 | the loader with cooperation from the layer libraries. Instance call chains are |
| 1116 | constructed by the loader when layers are enabled at vkCreateInstance. Device |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1117 | call chains are constructed by the loader when layers are enabled, by the loader, at |
ttyio | 0811cec | 2016-04-10 22:09:44 +0800 | [diff] [blame] | 1118 | vkCreateDevice. A layer can intercept Vulkan instance commands, device commands |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1119 | or both. For a layer to intercept instance commands, it must participate in the |
| 1120 | instance call chain. For a layer to intercept device commands, it must |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1121 | participate in the device chain. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1122 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1123 | Normally, when a layer intercepts a given Vulkan command, it will call down the |
| 1124 | instance or device chain as needed. The loader and all layer libraries that |
| 1125 | participate in a call chain cooperate to ensure the correct sequencing of calls |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 1126 | from one entity to the next. This group effort for call chain sequencing is |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1127 | hereinafter referred to as distributed dispatch. In distributed dispatch, since |
| 1128 | each layer is responsible for properly calling the next entity in the device or |
| 1129 | instance chain, a dispatch mechanism is required for all Vulkan commands a |
| 1130 | layer intercepts. For Vulkan commands that are not intercepted by a layer, or |
| 1131 | if the layer chooses to terminate a given Vulkan command by not calling down |
| 1132 | the chain, then no dispatch mechanism is needed for that particular Vulkan |
| 1133 | command. Only for those Vulkan commands, which may be a subset of all Vulkan |
| 1134 | commands, that a layer intercepts is a dispatching mechanism by the layer |
| 1135 | needed. The loader is responsible for dispatching all core and instance |
| 1136 | extension Vulkan commands to the first entity in the chain. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1137 | |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1138 | Instance level Vulkan commands are those that have the dispatchable objects |
| 1139 | VkInstance, or VkPhysicalDevice as the first parameter and also includes |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1140 | vkCreateInstance. |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1141 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1142 | Device level Vulkan commands are those that use VkDevice, VkQueue or |
| 1143 | VkCommandBuffer as the first parameter and also include vkCreateDevice. Future |
| 1144 | extensions may introduce new instance or device level dispatchable objects, so |
| 1145 | the above lists may be extended in the future. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1146 | |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1147 | #### Layer Library Interface |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1148 | |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1149 | A layer library is a container of layers. This section defines an extensible |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1150 | interface to discover layers contained in layer libraries. |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1151 | The extensible programming interface is used on Android only. For Windows and Linux, |
| 1152 | the layer manifest JSON files are used. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1153 | |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1154 | It also specifies the minimal conventions |
| 1155 | and rules a layer must follow. Other sections might have other guidelines that layers should follow. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1156 | |
| 1157 | ##### Layer Conventions and Rules |
| 1158 | |
| 1159 | A layer, when inserted into an otherwise compliant Vulkan implementation, must |
| 1160 | still result in a compliant Vulkan implementation[\*]. It must additionally |
| 1161 | follow some conventions and rules. |
| 1162 | |
| 1163 | A layer is always chained with other layers. It must not make invalid calls |
| 1164 | to or rely on undefined behaviors of its lower layers. When it changes the |
| 1165 | behavior of a command, it must make sure its upper layers do not make invalid |
| 1166 | calls to or rely on undefined behaviors of its lower layers because of the |
| 1167 | changed behavior. For example, when a layer intercepts an object creation |
| 1168 | command to wrap the objects created by its lower layers, it must make sure its |
| 1169 | lower layers never see the wrapping objects, directly from itself or |
| 1170 | indirectly from its upper layers. |
| 1171 | |
Chia-I Wu | b5e850e | 2016-05-06 08:41:52 +0800 | [diff] [blame] | 1172 | When a layer requires host memory, it may ignore the provided allocators. It |
| 1173 | should use memory allocators if the layer is intended to run in a production |
| 1174 | environment, such as an implicit layer that is always enabled. That will |
| 1175 | allow applications to include the layer's memory usage. |
| 1176 | |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1177 | `vkEnumerateInstanceLayerProperties` must enumerate and only enumerate the |
| 1178 | layer itself. |
| 1179 | |
| 1180 | `vkEnumerateInstanceExtensionProperties` must handle the case where |
| 1181 | `pLayerName` is itself. It must return `VK_ERROR_LAYER_NOT_PRESENT` |
| 1182 | otherwise, including when `pLayerName` is `NULL`. |
| 1183 | |
| 1184 | `vkEnumerateDeviceLayerProperties` is deprecated and may be omitted. The |
| 1185 | behavior is undefined. |
| 1186 | |
Chia-I Wu | adac834 | 2016-04-22 08:12:19 +0800 | [diff] [blame] | 1187 | `vkEnumerateDeviceExtensionProperties` must handle the case where `pLayerName` |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1188 | is itself. In other cases, it should normally chain to other layers. |
| 1189 | |
| 1190 | `vkCreateInstance` must not generate an error for unrecognized layer names and |
| 1191 | extension names. It may assume the layer names and extension names have been |
| 1192 | validated. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1193 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1194 | `vkGetInstanceProcAddr` intercepts a Vulkan command by returning a local entry point, |
| 1195 | otherwise it returns the value obtained by calling down the instance chain. |
| 1196 | These commands must be intercepted |
| 1197 | - vkGetInstanceProcAddr |
| 1198 | - vkCreateInstance |
| 1199 | - vkCreateDevice (only required for any device-level chaining) |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1200 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1201 | For compatibility with older layer libraries, |
| 1202 | - when `pName` is `vkCreateDevice`, it ignores `instance`. |
| 1203 | |
| 1204 | `vkGetDeviceProcAddr` intercepts a Vulkan command by returning a local entry point, |
| 1205 | otherwise it returns the value obtained by calling down the device chain. |
| 1206 | |
| 1207 | The specification requires `NULL` to be returned from `vkGetInstanceProcAddr` and |
| 1208 | `vkGetDeviceProcAddr` for disabled commands. A layer may return `NULL` itself or |
| 1209 | rely on the following layers to do so. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1210 | |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1211 | [\*]: The intention is for layers to have a well-defined baseline behavior. |
| 1212 | Some of the conventions or rules, for example, may be considered abuses of the |
| 1213 | specification. |
| 1214 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1215 | ##### Layer Library API Version 0 |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1216 | |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1217 | A layer library supporting interface version 0 must define and export these |
| 1218 | introspection functions, unrelated to any Vulkan command despite the names, |
| 1219 | signatures, and other similarities: |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1220 | |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1221 | - `vkEnumerateInstanceLayerProperties` enumerates all layers in a layer |
| 1222 | library. This function never fails. |
| 1223 | |
| 1224 | When a layer library contains only one layer, this function may be an alias |
| 1225 | to the layer's `vkEnumerateInstanceLayerProperties`. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1226 | |
| 1227 | - `vkEnumerateInstanceExtensionProperties` enumerates instance extensions of |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1228 | layers in a layer library. `pLayerName` is always a valid layer name. |
| 1229 | This function never fails. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1230 | |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1231 | When a layer library contains only one layer, this function may be an alias |
| 1232 | to the layer's `vkEnumerateInstanceExtensionProperties`. |
| 1233 | |
| 1234 | - `vkEnumerateDeviceLayerProperties` enumerates a subset (can be full, |
| 1235 | proper, or empty subset) of layers in a layer library. `physicalDevice` is |
| 1236 | always `VK_NULL_HANDLE`. This function never fails. |
| 1237 | |
| 1238 | If a layer is not enumerated by this function, it will not participate in |
| 1239 | device command interception. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1240 | |
| 1241 | - `vkEnumerateDeviceExtensionProperties` enumerates device extensions of |
Chia-I Wu | 0e9aae7 | 2016-05-19 10:45:02 +0800 | [diff] [blame] | 1242 | layers in a layer library. `physicalDevice` is always `VK_NULL_HANDLE`. |
| 1243 | `pLayerName` is always a valid layer name. This function never fails. |
| 1244 | |
| 1245 | The introspection functions are not used by the desktop loader. |
| 1246 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1247 | It must also define and export these functions one for each layer in the library: |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1248 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1249 | - `<layerName>GetInstanceProcAddr(instance, pName)` behaves identically to a layer's vkGetInstanceProcAddr except it is exported. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1250 | |
| 1251 | When a layer library contains only one layer, this function may |
| 1252 | alternatively be named `vkGetInstanceProcAddr`. |
| 1253 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1254 | - `<layerName>GetDeviceProcAddr` behaves identically to a layer's vkGetDeviceProcAddr except it is exported. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1255 | |
| 1256 | When a layer library contains only one layer, this function may |
| 1257 | alternatively be named `vkGetDeviceProcAddr`. |
| 1258 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1259 | All layers contained within a library must support [`vk_layer.h`][]. They do not need to |
| 1260 | implement commands that they do not intercept. They are recommended not to export |
| 1261 | any commands. |
Chia-I Wu | cb24fec | 2016-04-20 06:23:24 +0800 | [diff] [blame] | 1262 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1263 | <a name="LayerLibraryManifestFile"></a> |
| 1264 | ##### Layer Library Manifest File Version 0 |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1265 | On Windows and Linux (desktop), the loader uses manifest files to discover |
| 1266 | layer libraries and layers. The desktop loader doesn't directly query the |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1267 | layer library except during chaining. |
| 1268 | On Android, the loader queries the layer libraries via the introspection functions as outlined above. |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1269 | |
| 1270 | The layer libraries and the manifest files must be kept in sync. |
| 1271 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1272 | The following table associates the desktop JSON nodes with the layer library introspection queries. It also indicates requirements. |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1273 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1274 | | Property | JSON node | Introspection query | Notes | |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1275 | |----------|-----------|-----------------------|-------| |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1276 | | file version | file_format_version | N/A | one node required per JSON file | |
| 1277 | | layers in library | layer | vkEnumerateInstanceLayerProperties | one node required per layer | |
| 1278 | | layer name | name | vkEnumerateInstanceLayerProperties | one node is required | |
| 1279 | | layer type | type | vkEnumerate*LayerProperties | see Note 1 | |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1280 | | library location | library_path | N/A | one node is required | |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1281 | | vulkan spec version | api_version | vkEnumerateInstanceLayerProperties | one node is required | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1282 | | layer implementation version | api_version | vkEnumerateInstanceLayerProperties | see Note 2 | |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1283 | | layer description | description | vkEnumerateInstanceLayerProperties | one node is required | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1284 | | chaining functions | functions | vkGet*ProcAddr | see Note 3 | |
| 1285 | | instance extensions | instance_extensions | vkEnumerateInstanceExtensionProperties | see Note 4 | |
| 1286 | | device extensions | device_extensions | vkEnumerateDeviceExtensionProperties | see Note 5 | |
| 1287 | | enable implicit | enable_environment | N/A | See Note 6 | |
| 1288 | | disable implicit | enable_environment | N/A | See Note 7 | |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1289 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1290 | "file\_format\_version" is used to indicate the valid JSON syntax of the file. |
| 1291 | As nodes are added or deleted which would change the parsing of this file, |
| 1292 | the file_format_version should change. This version |
| 1293 | is NOT the same as the layer library interface version. The interface version is a superset |
| 1294 | of the "file_format_version" and includes the semantics of the nodes in the JSON file. |
| 1295 | For interface version 0 the file format version must be "1.0.0" |
| 1296 | |
| 1297 | Note 1: Prior to deprecation, the "type" node was used to indicate which layer chain(s) |
| 1298 | to activate the layer upon: instance, device, or both. |
| 1299 | Distinct instance and device layers are deprecated; there are now just layers. |
| 1300 | Allowable values for type (both before and after deprecation) are "INSTANCE", "GLOBAL" and, "DEVICE." |
| 1301 | "DEVICE" layers are skipped over by the loader as if they were not found. |
| 1302 | Thus, layers must have a type of "GLOBAL" or "INSTANCE" for the loader to include the layer in the enumerated instance layer list. |
| 1303 | |
| 1304 | "library\_path" is the filename, full path, or relative path to the library file. |
Mark Young | 5755151 | 2016-06-23 11:25:03 -0600 | [diff] [blame] | 1305 | See [Manifest File Example](#ManifestFileExample) section for more details. |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1306 | |
| 1307 | Note 2: One "implementation\_version" node is required per layer. This node gives the layer version, a single number |
| 1308 | increasing with backward uncompatible changes. |
| 1309 | |
| 1310 | Note 3: The "functions" node is required if the layer is using alternative |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1311 | names for vkGetInstanceProcAddr or vkGetDeviceProcAddr. vkGetInstanceProcAddr and vkGetDeviceProcAddr |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1312 | are required for all layers. See further requirements in the Layer Library API section above. |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1313 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1314 | Note 4: One "instance_extensions" node with an array of one or more elements |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1315 | required if any instance |
| 1316 | extensions are supported by a layer, otherwise the node is optional. Each |
| 1317 | element of the array must have the nodes "name" and "spec_version" which |
| 1318 | correspond to VkExtensionProperties "extensionName" and "specVersion" |
| 1319 | respectively. |
| 1320 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1321 | Note 5: One "device_extensions" node with an array of one or more elements |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1322 | required if any device |
| 1323 | extensions are supported by a layer, otherwise the node is optional. Each |
| 1324 | element of the array must have the nodes "name" and "spec_version" which |
| 1325 | correspond to VkExtensionProperties "extensionName" and "specVersion" |
| 1326 | respectively. Additionally, each element of the array of device extensions |
| 1327 | must have the node "entrypoints" if the device extension adds Vulkan API commands, |
| 1328 | otherwise this node is not required. |
| 1329 | The "entrypoint" node is an array of the names of all entrypoints added by the |
| 1330 | supported extension. |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1331 | ``` |
| 1332 | "device_extensions": [ |
| 1333 | { |
| 1334 | "name": "VK_EXT_debug_marker", |
| 1335 | "spec_version": "1", |
| 1336 | "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"] |
| 1337 | } |
| 1338 | ``` |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1339 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1340 | Note 6: The "enable\_environment" node is only for implicit layers only. It is optional for implicit layers. |
| 1341 | This node gives an environment variable and value required to enable an implicit layer. This |
| 1342 | environment variable (which should vary with each "version" of the layer) must be set to the |
| 1343 | given value or else the implicit layer is not loaded. This is for application environments (e.g. Steam) which |
| 1344 | want to enable a layer(s) only for applications that they launch, and allows |
| 1345 | for applications run outside of an application environment to not get that |
| 1346 | implicit layer(s). |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1347 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1348 | Note 7: The "disable\_environment" node is only for implicit layers only. It is required for implicit layers. |
| 1349 | This node gives an environment variable and value required to disable an implicit layer. In |
| 1350 | rare cases of an application not working with an implicit layer, the |
| 1351 | application can set this environment variable (before calling Vulkan commands) |
| 1352 | in order to "blacklist" the layer. This environment variable (which should vary |
| 1353 | with each "version" of the layer) must be set (not particularly to any value). |
| 1354 | If both the "enable\_environment" and |
| 1355 | "disable\_environment" variables are set, the implicit layer is disabled. |
Jon Ashburn | 6bda65b | 2016-05-10 09:24:52 -0600 | [diff] [blame] | 1356 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1357 | #### Layer Dispatch Interface Version 0 |
| 1358 | ##### Layer intercept requirements |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1359 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1360 | - Layers intercept a Vulkan command by defining a C/C++ function with signature |
| 1361 | identical to the Vulkan API for that command. |
Jon Ashburn | c9d7fc9 | 2016-05-18 14:07:47 -0600 | [diff] [blame] | 1362 | - A layer must intercept at least vkGetInstanceProcAddr and |
| 1363 | vkCreateInstance. Additionally, a layer would also intercept vkGetDeviceProcAddr and vkCreateDevice to participate in the device chain. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1364 | - For any Vulkan command a layer intercepts which has a non-void return value, |
| 1365 | an appropriate value must be returned by the layer intercept function. |
| 1366 | - The layer intercept function must call down the chain to the corresponding |
| 1367 | Vulkan command in the next entity. Undefined results will occur if a layer |
| 1368 | doesn't propagate calls down the chain. The two exceptions to this requirement |
| 1369 | are vkGetInstanceProcAddr and vkGetDeviceProcAddr which only call down the |
| 1370 | chain for Vulkan commands that they do not intercept. |
| 1371 | - Layer intercept functions may insert extra calls to Vulkan commands in |
| 1372 | addition to the intercept. For example, a layer intercepting vkQueueSubmit may |
| 1373 | want to add a call to vkQueueWaitIdle after calling down the chain for |
| 1374 | vkQueueSubmit. Any additional calls inserted by a layer must be on the same |
| 1375 | chain. They should call down the chain. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1376 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1377 | ##### Distributed dispatching requirements |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1378 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1379 | - For each entry point a layer intercepts, it must keep track of the entry |
| 1380 | point residing in the next entity in the chain it will call down into. In other |
| 1381 | words, the layer must have a list of pointers to functions of the appropriate |
| 1382 | type to call into the next entity. This can be implemented in various ways but |
| 1383 | for clarity will be referred to as a dispatch table. |
| 1384 | - A layer can use the VkLayerDispatchTable structure as a device dispatch table |
| 1385 | (see include/vulkan/vk_layer.h). |
| 1386 | - A layer can use the VkLayerInstanceDispatchTable structure as a instance |
| 1387 | dispatch table (see include/vulkan/vk_layer.h). |
| 1388 | - Layers vkGetInstanceProcAddr function uses the next entity's |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1389 | vkGetInstanceProcAddr to call down the chain for unknown (i.e. non-intercepted) |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1390 | functions. |
| 1391 | - Layers vkGetDeviceProcAddr function uses the next entity's |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1392 | vkGetDeviceProcAddr to call down the chain for unknown (i.e. non-intercepted) |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1393 | functions. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1394 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1395 | ##### Layer dispatch initialization |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1396 | |
| 1397 | - A layer initializes its instance dispatch table within its vkCreateInstance |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1398 | function. |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1399 | - A layer initializes its device dispatch table within its vkCreateDevice |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1400 | function. |
| 1401 | - The loader passes a linked list of initialization structures to layers via |
| 1402 | the "pNext" field in the VkInstanceCreateInfo and VkDeviceCreateInfo structures |
| 1403 | for vkCreateInstance and VkCreateDevice respectively. |
| 1404 | - The head node in this linked list is of type VkLayerInstanceCreateInfo for |
Courtney Goeltzenleuchter | 42c4cdb | 2016-02-14 11:42:24 -0700 | [diff] [blame] | 1405 | instance and VkLayerDeviceCreateInfo for device. See file |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1406 | include/vulkan/vk_layer.h for details. |
| 1407 | - A VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO is used by the loader for the |
| 1408 | "sType" field in VkLayerInstanceCreateInfo. |
| 1409 | - A VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO is used by the loader for the |
| 1410 | "sType" field in VkLayerDeviceCreateInfo. |
| 1411 | - The "function" field indicates how the union field "u" should be interpreted |
| 1412 | within VkLayer*CreateInfo. The loader will set the "function" field to |
| 1413 | VK_LAYER_LINK_INFO. This indicates "u" field should be VkLayerInstanceLink or |
| 1414 | VkLayerDeviceLink. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1415 | - The VkLayerInstanceLink and VkLayerDeviceLink structures are the list nodes. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1416 | - The VkLayerInstanceLink contains the next entity's vkGetInstanceProcAddr used |
| 1417 | by a layer. |
| 1418 | - The VkLayerDeviceLink contains the next entity's vkGetInstanceProcAddr and |
| 1419 | vkGetDeviceProcAddr used by a layer. |
| 1420 | - Given the above structures set up by the loader, layer must initialize their |
| 1421 | dispatch table as follows: |
| 1422 | - Find the VkLayerInstanceCreateInfo/VkLayerDeviceCreateInfo structure in |
| 1423 | the VkInstanceCreateInfo/VkDeviceCreateInfo structure. |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1424 | - Get the next entity's vkGet*ProcAddr from the "pLayerInfo" field. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1425 | - For CreateInstance get the next entity's vkCreateInstance by calling the |
| 1426 | "pfnNextGetInstanceProcAddr": |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1427 | pfnNextGetInstanceProcAddr(NULL, "vkCreateInstance"). |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1428 | - For CreateDevice get the next entity's vkCreateDevice by calling the |
| 1429 | "pfnNextGetInstanceProcAddr": |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1430 | pfnNextGetInstanceProcAddr(NULL, "vkCreateDevice"). |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1431 | - Advanced the linked list to the next node: pLayerInfo = pLayerInfo->pNext. |
| 1432 | - Call down the chain either CreateDevice or CreateInstance |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1433 | - Initialize your layer dispatch table by calling the next entity's |
| 1434 | Get*ProcAddr function once for each Vulkan command needed in your dispatch |
| 1435 | table |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1436 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1437 | ##### Example code for CreateInstance |
Jon Ashburn | fe630fb | 2016-02-14 21:40:34 -0700 | [diff] [blame] | 1438 | |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1439 | ```cpp |
| 1440 | VkResult vkCreateInstance( |
| 1441 | const VkInstanceCreateInfo *pCreateInfo, |
| 1442 | const VkAllocationCallbacks *pAllocator, |
| 1443 | VkInstance *pInstance) |
| 1444 | { |
| 1445 | VkLayerInstanceCreateInfo *chain_info = |
| 1446 | get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); |
| 1447 | |
| 1448 | assert(chain_info->u.pLayerInfo); |
| 1449 | PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = |
| 1450 | chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; |
| 1451 | PFN_vkCreateInstance fpCreateInstance = |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1452 | (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1453 | if (fpCreateInstance == NULL) { |
| 1454 | return VK_ERROR_INITIALIZATION_FAILED; |
| 1455 | } |
| 1456 | |
| 1457 | // Advance the link info for the next element of the chain |
| 1458 | chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; |
| 1459 | |
| 1460 | // Continue call down the chain |
| 1461 | VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); |
| 1462 | if (result != VK_SUCCESS) |
| 1463 | return result; |
| 1464 | |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1465 | // Init layer's dispatch table using GetInstanceProcAddr of |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1466 | // next layer in the chain. |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1467 | instance_dispatch_table = new VkLayerInstanceDispatchTable; |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1468 | layer_init_instance_dispatch_table( |
| 1469 | *pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); |
| 1470 | |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1471 | // Other layer initialization |
| 1472 | ... |
| 1473 | |
| 1474 | return VK_SUCCESS; |
| 1475 | } |
| 1476 | ``` |
| 1477 | |
Jon Ashburn | 2b4d7bb | 2016-05-23 13:05:21 -0600 | [diff] [blame] | 1478 | ##### Example code for CreateDevice |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1479 | |
| 1480 | ```cpp |
| 1481 | VkResult |
| 1482 | vkCreateDevice( |
| 1483 | VkPhysicalDevice gpu, |
| 1484 | const VkDeviceCreateInfo *pCreateInfo, |
| 1485 | const VkAllocationCallbacks *pAllocator, |
| 1486 | VkDevice *pDevice) |
| 1487 | { |
| 1488 | VkLayerDeviceCreateInfo *chain_info = |
| 1489 | get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); |
| 1490 | |
| 1491 | PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = |
| 1492 | chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; |
| 1493 | PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = |
| 1494 | chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; |
| 1495 | PFN_vkCreateDevice fpCreateDevice = |
| 1496 | (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice"); |
| 1497 | if (fpCreateDevice == NULL) { |
| 1498 | return VK_ERROR_INITIALIZATION_FAILED; |
| 1499 | } |
| 1500 | |
| 1501 | // Advance the link info for the next element on the chain |
| 1502 | chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; |
| 1503 | |
| 1504 | VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); |
| 1505 | if (result != VK_SUCCESS) { |
| 1506 | return result; |
| 1507 | } |
| 1508 | |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1509 | // initialize layer's dispatch table |
| 1510 | device_dispatch_table = new VkLayerDispatchTable; |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1511 | layer_init_device_dispatch_table( |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1512 | *pDevice, device_dispatch_table, fpGetDeviceProcAddr); |
Courtney Goeltzenleuchter | f6abc20 | 2016-02-15 15:05:16 -0700 | [diff] [blame] | 1513 | |
| 1514 | // Other layer initialization |
| 1515 | ... |
| 1516 | |
| 1517 | return VK_SUCCESS; |
| 1518 | } |
| 1519 | ``` |
Jon Ashburn | fe630fb | 2016-02-14 21:40:34 -0700 | [diff] [blame] | 1520 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1521 | #### Special Considerations |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1522 | ##### Associating private data with Vulkan objects within a layer |
Courtney Goeltzenleuchter | 7221a5a | 2016-02-15 14:59:37 -0700 | [diff] [blame] | 1523 | A layer may want to associate it's own private data with one or more Vulkan |
Mark Young | f7914cf | 2016-08-31 11:53:26 -0600 | [diff] [blame] | 1524 | objects. Two common methods to do this are hash maps and object wrapping. |
| 1525 | |
| 1526 | ###### Wrapping: |
| 1527 | |
Ian Elliott | 0b082e4 | 2016-08-31 14:08:44 -0600 | [diff] [blame] | 1528 | The loader supports layers wrapping any Vulkan object including dispatchable |
| 1529 | objects. |
| 1530 | For commands that return object handles, the layer saves the handle that is |
| 1531 | returned from a lower-level layer (possibly the ICD), and returns its own |
| 1532 | handle to the layer above it (possibly the application). For commands that are |
| 1533 | given previously-returned handles, the layer unwraps the handle; that is it |
| 1534 | looks up the saved handle and gives that to the layer below it. |
| 1535 | |
| 1536 | Layers which wrap objects must ensure they always unwrap objects before passing |
| 1537 | them down the chain. This means that the layer must intercept every Vulkan |
| 1538 | command which uses the object in question, and wrap or unwrap the object, as |
| 1539 | appropriate. This includes adding support for all extensions with commands |
| 1540 | using any object the layer wraps. |
Mark Young | f7914cf | 2016-08-31 11:53:26 -0600 | [diff] [blame] | 1541 | |
| 1542 | Layers above the object wrapping layer will see the wrapped object. Layers |
| 1543 | which wrap dispatchable objects must ensure that the first field in the wrapping |
| 1544 | structure is a pointer to a dispatch table as defined in vk_layer.h. Specifically, an |
| 1545 | instance wrapped dispatchable object could be as follows: |
Jon Ashburn | 859c7fb | 2016-03-02 17:26:31 -0700 | [diff] [blame] | 1546 | ``` |
| 1547 | struct my_wrapped_instance_obj_ { |
| 1548 | VkLayerInstanceDispatchTable *disp; |
| 1549 | // whatever data layer wants to add to this object |
| 1550 | }; |
| 1551 | ``` |
| 1552 | A device wrapped dispatchable object could be as follows: |
| 1553 | ``` |
| 1554 | struct my_wrapped_instance_obj_ { |
| 1555 | VkLayerDispatchTable *disp; |
| 1556 | // whatever data layer wants to add to this object |
| 1557 | }; |
| 1558 | ``` |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1559 | |
Ian Elliott | 0b082e4 | 2016-08-31 14:08:44 -0600 | [diff] [blame] | 1560 | Layers that wrap dispatchable objects must follow the guidelines for creating |
| 1561 | new dispatchable objects (below). |
| 1562 | |
Mark Young | 6792928 | 2016-09-01 13:43:04 -0600 | [diff] [blame] | 1563 | <u><b>Cautions</b></u> |
Ian Elliott | 0b082e4 | 2016-08-31 14:08:44 -0600 | [diff] [blame] | 1564 | |
| 1565 | Layers are generally discouraged from wrapping objects, because of the |
| 1566 | potential for incompatibilities with new extensions. For example, let's say |
| 1567 | that a layer wraps VkImage objects, and properly wraps and unwraps VkImage |
| 1568 | object handles for all core commands. If a new extension is created which has |
| 1569 | commands that take VkImage objects as parameters, and if the layer does not |
| 1570 | support those new commands, an application that uses both the layer and the new |
| 1571 | extension will have undefined behavior when those new commands are called (e.g. |
| 1572 | the application may crash). This is becaues the lower-level layers and ICD |
| 1573 | won't receive the handle that they generated. Instead, they will receive a |
| 1574 | handle that is only known by the layer that is wrapping the object. |
| 1575 | |
| 1576 | Because of the potential for incompatibilities with unsupported extensions, |
| 1577 | layers that wrap objects must check which extensions are being used by the |
| 1578 | application, and take appropriate action if the layer is used with unsupported |
| 1579 | extensions (e.g. disable layer functionality, stop wrapping objects, issue a |
| 1580 | message to the user). |
| 1581 | |
| 1582 | The reason that the validation layers wrap objects, is to track the proper use |
| 1583 | and destruction of each object. They issue a validation error if used with |
| 1584 | unsupported extensions, alerting the user to the potential for undefined |
| 1585 | behavior. |
| 1586 | |
Mark Young | f7914cf | 2016-08-31 11:53:26 -0600 | [diff] [blame] | 1587 | ###### Hash Maps: |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1588 | Alternatively, a layer may want to use a hash map to associate data with a |
Courtney Goeltzenleuchter | 7221a5a | 2016-02-15 14:59:37 -0700 | [diff] [blame] | 1589 | given object. The key to the map could be the object. Alternatively, for |
| 1590 | dispatchable objects at a given level (eg device or instance) the layer may |
| 1591 | want data associated with the VkDevice or VkInstance objects. Since |
Jeff Juliano | f161987 | 2016-02-17 17:25:42 -0500 | [diff] [blame] | 1592 | there are multiple dispatchable objects for a given VkInstance or VkDevice, the |
| 1593 | VkDevice or VkInstance object is not a great map key. Instead the layer should |
| 1594 | use the dispatch table pointer within the VkDevice or VkInstance since that |
| 1595 | will be unique for a given VkInstance or VkDevice. |
Jon Ashburn | fe630fb | 2016-02-14 21:40:34 -0700 | [diff] [blame] | 1596 | |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1597 | ##### Creating new dispatchable objects |
Jon Ashburn | fe630fb | 2016-02-14 21:40:34 -0700 | [diff] [blame] | 1598 | Layers which create dispatchable objects take special care. Remember that loader |
| 1599 | trampoline code normally fills in the dispatch table pointer in the newly |
| 1600 | created object. Thus, the layer must fill in the dispatch table pointer if the |
Jon Ashburn | 859c7fb | 2016-03-02 17:26:31 -0700 | [diff] [blame] | 1601 | loader trampoline will not do so. Common cases where a layer (or ICD) may create a |
Courtney Goeltzenleuchter | 7221a5a | 2016-02-15 14:59:37 -0700 | [diff] [blame] | 1602 | dispatchable object without loader trampoline code is as follows: |
Jon Ashburn | fe630fb | 2016-02-14 21:40:34 -0700 | [diff] [blame] | 1603 | - object wrapping layers that wrap dispatchable objects |
| 1604 | - layers which add extensions that create dispatchable objects |
| 1605 | - layers which insert extra Vulkan commands in the stream of commands they |
| 1606 | intercept from the application |
Jon Ashburn | 859c7fb | 2016-03-02 17:26:31 -0700 | [diff] [blame] | 1607 | - ICDs which add extensions that create dispatchable objects |
| 1608 | |
Jon Ashburn | 2b2f618 | 2016-04-04 16:37:37 -0600 | [diff] [blame] | 1609 | The Windows/Linux loader provides a callback that can be used for initializing |
| 1610 | a dispatchable object. The callback is passed as an extension structure via the |
| 1611 | pNext field in VkInstanceCreateInfo and VkDeviceCreateInfo. The callback prototype |
| 1612 | is defined as follows for instance and device callbacks respectively (see vk_layer.h): |
| 1613 | ``` |
| 1614 | VKAPI_ATTR VkResult VKAPI_CALL vkSetInstanceLoaderData(VkInstance instance, void *object); |
| 1615 | VKAPI_ATTR VkResult VKAPI_CALL vkSetDeviceLoaderData)(VkDevice device, void *object); |
| 1616 | ``` |
| 1617 | To obtain these callbacks the layer must search through the list of structures |
| 1618 | pointed to by the "pNext" field in the VkInstanceCreateInfo and VkDeviceCreateInfo parameters to find any callback structures inserted by the loader. The salient details are as follows: |
| 1619 | - For CreateInstance the callback structure pointed to by "pNext" is VkLayerInstanceCreateInfo as defined in vk_layer.h. |
| 1620 | - A "sType" field in of VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO within VkInstanceCreateInfo parameter indicates a loader structure. |
| 1621 | - Within VkLayerInstanceCreateInfo, the "function" field indicates how the union field "u" should be interpreted. |
| 1622 | - A "function" equal to VK_LOADER_DATA_CALLBACK indicates the "u" field will contain the callback in "pfnSetInstanceLoaderData". |
| 1623 | - For CreateDevice the callback structure pointed to by "pNext" is VkLayerDeviceCreateInfo as defined in include/vulkan/vk_layer.h. |
| 1624 | - A "sType" field in of VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO within VkDeviceCreateInfo parameter indicates a loader structure. |
| 1625 | - Within VkLayerDeviceCreateInfo, the "function" field indicates how the union field "u" should be interpreted. |
| 1626 | - A "function" equal to VK_LOADER_DATA_CALLBACK indicates the "u" field will contain the callback in "pfnSetDeviceLoaderData". |
| 1627 | |
| 1628 | Alternatively, if an older loader is being used that doesn't provide these callbacks, the layer may manually initialize the newly created dispatchable object. |
Jon Ashburn | 859c7fb | 2016-03-02 17:26:31 -0700 | [diff] [blame] | 1629 | To fill in the dispatch table pointer in newly created dispatchable object, |
| 1630 | the layer should copy the dispatch pointer, which is always the first entry in the structure, from an existing parent object of the same level (instance versus |
| 1631 | device). For example, if there is a newly created VkCommandBuffer object, then the dispatch pointer from the VkDevice object, which is the parent of the VkCommandBuffer object, should be copied into the newly created object. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1632 | |