Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1 | # Vulkan Loader Specification and Architecture Overview |
| 2 | |
| 3 | |
| 4 | Goals of this document |
| 5 | ---------------------- |
| 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 | |
| 11 | Audience |
| 12 | -------- |
| 13 | |
| 14 | Application, Vulkan driver and Vulkan layer developers. |
| 15 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 16 | Any developers interested in understanding more about loader and layer behavior |
| 17 | and architecture. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 18 | |
| 19 | |
| 20 | Loader goals |
| 21 | ------------ |
| 22 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 23 | - Support multiple ICDs (Installable Client Drivers) to co-exist on a system |
| 24 | without interfering with each other. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 25 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 26 | - Support optional modules (layers) that can be enabled by an application, |
| 27 | developer or the system and have no impact when not enabled. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 28 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 29 | - Negligible performance cost for an application calling through the loader |
| 30 | to an ICD entry point. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 31 | |
| 32 | Architectural overview of layers and loader |
| 33 | ------------------------------------------- |
| 34 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 35 | Vulkan is layered architecture. Layers can hook (intercept) Vulkan commands to |
| 36 | achieve various functionality that a Vulkan driver (aka ICD) or loader doesn’t |
| 37 | support. Functionality such as Vulkan API tracing and debugging, API usage |
| 38 | validation, and other tools such as framebuffer overlays are all natural |
| 39 | candidates for Vulkan layers. Layers are implemented as libraries that are |
| 40 | inserted between the application and the driver. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 41 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 42 | Not only is Vulkan a layered architecture but it also supports multiple GPUs |
| 43 | and their drivers. Vulkan commands called by an application may wind up calling |
| 44 | into a diverse set of modules: loader, layers, and ICDs. The loader is critical |
| 45 | to managing the proper dispatching of Vulkan commands to the appropriate set of |
| 46 | layers and ICDs. The loader inserts layers into a call chain so they can |
| 47 | intercept Vulkan commands prior to the proper ICD being called. To achieve |
| 48 | proper dispatching of Vulkan command to layers and ICDs the loader uses the |
| 49 | Vulkan object model. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 50 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 51 | Vulkan uses an object model to control the scope of a particular action / |
| 52 | operation. The object to be acted on is always the first parameter of a Vulkan |
| 53 | call and is a dispatchable object (see Vulkan specification section 2.2 Object |
| 54 | Model). Under the covers, the dispatchable object handle is a pointer to a |
| 55 | structure that contains a pointer to a dispatch table maintained by the loader. |
| 56 | This dispatch table contains pointers to the Vulkan functions appropriate to |
| 57 | that object. I.e. a VkInstance object’s dispatch table will point to Vulkan |
| 58 | functions such as vkEnumeratePhysicalDevices, vkDestroyInstance, |
| 59 | vkCreateInstance, etc. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 60 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 61 | Device objects have a separate dispatch table containing the appropriate |
| 62 | function pointers. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 63 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 64 | These instance and device dispatch tables are constructed when the application |
| 65 | calls vkCreateInstance and vkCreateDevice. At that time the application and/or |
| 66 | system can specify optional layers to be included. The loader will initialize |
| 67 | the specified layers to create a call chain for each Vulkan function and each |
| 68 | entry of the dispatch table will point to the first element of that chain. |
| 69 | Thus, the loader builds an instance call chain for each VkInstance that is |
| 70 | created and a device call chain for each VkDevice that is created. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 71 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 72 | For example, the diagram below represents what happens in the call chain for |
| 73 | vkCreateInstance. After initializing the chain, the loader will call into the |
| 74 | first layer’s vkCreateInstance which will call the next finally terminating in |
| 75 | the loader again where this function calls every ICD’s vkCreateInstance and |
| 76 | saves the results. This allows every enabled layer for this chain to set up |
| 77 | what it needs based on the VkInstanceCreateInfo structure from the application. |
Courtney Goeltzenleuchter | ab3a466 | 2016-02-14 10:48:22 -0700 | [diff] [blame^] | 78 |  |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 79 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 80 | This also highlights some of the complexity the loader must manage when using |
| 81 | instance chains. As shown here, the loader must aggregate information from |
| 82 | multiple devices when they are present. This means that the loader has to know |
| 83 | about instance level extensions to aggregate them correctly. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 84 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 85 | Device chains are created at vkCreateDevice and are generally simpler because |
| 86 | they deal with only a single device and the ICD can always be the terminator of |
| 87 | the chain. The below diagram also illustrates how layers (either device or |
| 88 | instance) can skip intercepting any given Vulkan entry point. |
Courtney Goeltzenleuchter | ab3a466 | 2016-02-14 10:48:22 -0700 | [diff] [blame^] | 89 |  |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 90 | |
| 91 | Application interface to loader |
| 92 | ------------------------------- |
| 93 | |
| 94 | In this section we’ll discuss how an application interacts with the loader. |
| 95 | |
| 96 | - Linking to loader library for core and WSI extension symbols. |
| 97 | |
| 98 | - Dynamic Vulkan command lookup & application dispatch table. |
| 99 | |
| 100 | - Loader library filenames for linking to different Vulkan ABI versions. |
| 101 | |
| 102 | - Layers |
| 103 | |
| 104 | - Extensions |
| 105 | |
| 106 | - vkGetInstanceProcAddr, vkGetDeviceProcAddr |
| 107 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 108 | The loader library on Windows, Linux and Android will export all core Vulkan |
| 109 | and all appropriate Window System Interface (WSI) extensions. This is done to |
| 110 | make it simpler to get started with Vulkan development. When an application |
| 111 | links directly to the loader library in this way, the Vulkan calls are simple |
| 112 | trampoline functions that jump to the appropriate dispatch table entry for the |
| 113 | object they are given. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 114 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 115 | Applications are not required to link directly to the loader library, instead |
| 116 | they can use the appropriate platform specific dynamic symbol lookup on the |
| 117 | loader library to initialize the application’s own dispatch table. This allows |
| 118 | an application to fail gracefully if the loader cannot be found and provide the |
| 119 | fastest mechanism for the application to call Vulkan functions. An application |
| 120 | will only need to query (via system calls such as dlsym()) the address of |
| 121 | vkGetInstanceProcAddr from the loader library. Using vkGetInstanceProcAddr the |
| 122 | application can then discover the address of all instance and global functions |
| 123 | and extensions, such as vkCreateInstance, |
| 124 | vkEnumerateInstanceExtensionProperties and vkEnumerateInstanceLayerProperties |
| 125 | in a platform independent way. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 126 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 127 | The Vulkan loader library will be distributed in various ways including Vulkan |
| 128 | SDKs, OS package distributions and IHV driver packages. These details are |
| 129 | beyond the scope of this document. However, the name and versioning of the |
| 130 | Vulkan loader library is specified so an app can link to the correct Vulkan ABI |
| 131 | library version. Vulkan versioning is such that ABI backwards compatibility is |
| 132 | guaranteed for all versions with the same major number (eg 1.0 and 1.1). On |
| 133 | Windows, the loader library encodes the ABI version in its name such that |
| 134 | multiple ABI incompatible versions of the loader can peacefully coexist on a |
| 135 | given system. The vulkan loader library key name is “vulkan-<ABI |
| 136 | version>”. For example, for Vulkan version 1.X on Windows the library |
| 137 | filename is vulkan-1.dll. And this library file can typically be found in the |
| 138 | windows/system32 directory. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 139 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 140 | For Linux, shared libraries are versioned based on a suffix. Thus, the ABI |
| 141 | number is not encoded in the base of the library filename as on Windows. On |
| 142 | Linux an application wanting to link to the latest Vulkan ABI version would |
| 143 | just link to the name vulkan (libvulkan.so). A specific Vulkan ABI version can |
| 144 | also be linked to by applications (eg libvulkan.so.1). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 145 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 146 | Applications desiring Vulkan functionality beyond what the core API offers may |
| 147 | use various layers or extensions. A layer cannot add new or modify existing |
| 148 | Vulkan commands, but may offer extensions that do. A common use of layers is |
| 149 | for API validation. A developer can use validation layers during application |
| 150 | development, but during production the layers can be disabled by the |
| 151 | application. Thus, eliminating the overhead of validating the applications |
| 152 | usage of the API. Layers discovered by the loader can be reported to the |
| 153 | application via vkEnumerateInstanceLayerProperties and |
| 154 | vkEnumerateDeviceLayerProperties, for instance and device layers respectively. |
| 155 | Instance layers are enabled at vkCreateInstance; device layers are enabled at |
| 156 | vkCreateDevice. For example, the ppEnabledLayerNames array in the |
| 157 | VkDeviceCreateInfo structure is used by the application to list the device |
| 158 | layer names to be enabled at vkCreateDevice. At vkCreateInstance and |
| 159 | vkCreateDevice, the loader will construct call chains that include the |
| 160 | application specified (enabled) layers. Order is important in the |
| 161 | ppEnabledLayerNames array; array element 0 is the topmost (closest to the |
| 162 | application) layer inserted in the chain and the last array element is closest |
| 163 | to the driver. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 164 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 165 | Developers may want to enable layers that are not enabled by the given |
| 166 | application they are using. On Linux and Windows, the environment variables |
| 167 | “VK\_INSTANCE\_LAYERS” and “VK\_DEVICE\_LAYERS” can be used to enable |
| 168 | additional layers which are not specified (enabled) by the application at |
| 169 | vkCreateInstance/vkCreateDevice. VK\_INSTANCE\_LAYERS is a colon |
| 170 | (Linux)/semi-colon (Windows) separated list of layer names to enable. Order is |
| 171 | relevant with the first layer in the list being the topmost layer (closest to |
| 172 | the application) and the last layer in the list being the bottommost layer |
| 173 | (closest to the driver). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 174 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 175 | Application specified layers and user specified layers (via environment |
| 176 | variables) are aggregated and duplicates removed by the loader when enabling |
| 177 | layers. Layers specified via environment variable are topmost (closest to the |
| 178 | application) while layers specified by the application are bottommost. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 179 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 180 | An example of using these environment variables to activate the validation |
| 181 | layer VK\_LAYER\_LUNARG\_param\_checker on Windows or Linux is as follows: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 182 | |
| 183 | ``` |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 184 | > $ export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_param_checker |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 185 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 186 | > $ export VK_DEVICE_LAYERS=VK_LAYER_LUNARG_param_checker |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 187 | ``` |
| 188 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 189 | **Note**: Many layers, including all LunarG validation layers are “global” |
| 190 | (i.e. both instance and device) layers and *must* be enabled on both the |
| 191 | instance and device chains to function properly. This is required for “global” |
| 192 | layers regardless of which method is used to enable the layer (application or |
| 193 | environment variable). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 194 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 195 | Some platforms, including Linux and Windows, support layers which are enabled |
| 196 | automatically by the loader rather than explicitly by the application (or via |
| 197 | environment variable). Explicit layers are those layers enabled by the |
| 198 | application (or environment variable) by providing the layer name. Implicit |
| 199 | layers are those layers enabled by the loader automatically. Any implicit |
| 200 | layers the loader discovers on the system in the appropriate location will be |
| 201 | enabled (subject to environment variable overrides described later). Discovery |
| 202 | of properly installed implicit and explicit layers is described later. |
| 203 | Explicitly enabling a layer that is implicitly enabled has no additional |
| 204 | effect: the layer will still be enabled implicitly by the loader. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 205 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 206 | Extensions are optional functionality provided by a layer, the loader or an |
| 207 | ICD. Extensions can modify the behavior of the Vulkan API and need to be |
| 208 | specified and registered with Khronos. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 209 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 210 | Instance extensions can be discovered via |
| 211 | vkEnumerateInstanceExtensionProperties. Device extensions can be discovered via |
| 212 | vkEnumerateDeviceExtensionProperties. The loader discovers and aggregates all |
| 213 | extensions from layers (both explicit and implicit), ICDs and the loader before |
| 214 | reporting them to the application in vkEnumerate\*ExtensionProperties. The |
| 215 | pLayerName parameter in these functions are used to select either a single |
| 216 | layer or the Vulkan platform implementation. If pLayerName is NULL, extensions |
| 217 | from Vulkan implementation components (including loader, implicit layers, and |
| 218 | ICDs) are enumerated. If pLayerName is equal to a discovered layer module name |
| 219 | then any extensions from that layer (which may be implicit or explicit) are |
| 220 | enumerated. Duplicate extensions (eg an implicit layer and ICD might report |
| 221 | support for the same extension) are eliminated by the loader. Extensions must |
| 222 | be enabled (in vkCreateInstance or vkCreateDevice) before they can be used. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 223 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 224 | Extension command entry points should be queried via vkGetInstanceProcAddr or |
| 225 | vkGetDeviceProcAddr. vkGetDeviceProcAddr can only be used to query for device |
| 226 | extension or core device entry points. Device entry points include any command |
| 227 | that uses a VkDevice as the first parameter or a dispatchable object that is a |
| 228 | child of a VkDevice (currently this includes VkQueue and VkCommandBuffer). |
| 229 | vkGetInstanceProcAddr can be used to query either device or instance extension |
| 230 | entry points in addition to all core entry points. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 231 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 232 | VkGetDeviceProcAddr is particularly interesting because it will provide the |
| 233 | most efficient way to call into the ICD. For example, the diagram below shows |
| 234 | what could happen if the application were to use vkGetDeviceProcAddr for the |
| 235 | function “vkGetDeviceQueue” and “vkDestroyDevice” but not “vkAllocateMemory”. |
| 236 | The resulting function pointer (fpGetDeviceQueue) would be the ICD’s entry |
| 237 | point if the loader and any enabled layers do not need to see that call. Even |
| 238 | if an enabled layer intercepts the call (eg vkDestroyDevice) the loader |
| 239 | trampoline code is skipped for function pointers obtained via |
| 240 | vkGetDeviceProcAddr. This also means that function pointers obtained via |
| 241 | vkGetDeviceProcAddr will only work with the specific VkDevice it was created |
| 242 | for, using it with another device has undefined results. For extensions, |
| 243 | 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] | 244 | |
Courtney Goeltzenleuchter | ab3a466 | 2016-02-14 10:48:22 -0700 | [diff] [blame^] | 245 |  |
| 246 | |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 247 | |
| 248 | Vulkan Installable Client Driver interface with the loader |
| 249 | ---------------------------------------------------------- |
| 250 | |
| 251 | ### ICD discovery |
| 252 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 253 | Vulkan allows multiple drivers each with one or more devices (represented by a |
| 254 | Vulkan VkPhysicalDevice object) to be used collectively. The loader is |
| 255 | responsible for discovering available Vulkan ICDs on the system. Given a list |
| 256 | of available ICDs, the loader can enumerate all the physical devices available |
| 257 | for an application and return this information to the application. The process |
| 258 | in which the loader discovers the available Installable Client Drivers (ICDs) |
| 259 | on a system is platform dependent. Windows, Linux and Android ICD discovery |
| 260 | details are listed below. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 261 | |
| 262 | #### Windows |
| 263 | |
| 264 | ##### Properly-Installed ICDs |
| 265 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 266 | In order to find properly-installed ICDs, the Vulkan loader will scan the |
| 267 | values in the following Windows registry key: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 268 | |
| 269 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers |
| 270 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 271 | For each value in this key which has DWORD data set to 0, the loader opens the |
| 272 | JSON format text information file (a.k.a. "manifest file") specified by the |
| 273 | name of the value. Each name must be a full pathname to the text manifest file. |
| 274 | The Vulkan loader will open each manifest file to obtain the name or pathname |
| 275 | of an ICD shared library (".dll") file. For example: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 276 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 277 | ``` |
| 278 | { |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 279 | "file_format_version": "1.0.0", |
| 280 | "ICD": { |
| 281 | "library_path": "path to ICD library", |
Tony Barbour | cd48951 | 2016-02-10 15:59:32 -0700 | [diff] [blame] | 282 | "api_version": "1.0.3" |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 283 | } |
| 284 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 285 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 286 | |
| 287 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 288 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 289 | pathname to an ICD shared library file, which the loader will attempt to load |
| 290 | using LoadLibrary(). If the ICD is specified via a filename, the shared library |
| 291 | lives in the system's DLL search path (e.g. in the "C:\\\\Windows\\\\System32" |
| 292 | folder). If the ICD is specified via a relative pathname, it is relative to the |
| 293 | path of the manifest file. Relative pathnames are those that do not start with |
| 294 | a drive specifier (e.g. "C:"), nor with a directory separator (i.e. the '\\' |
| 295 | character), but do contain at least one directory separator. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 296 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 297 | The "file\_format\_version" specifies a major.minor.patch version number in |
| 298 | case the format of the text information file changes in the future. If the same |
| 299 | ICD shared library supports multiple, incompatible versions of text manifest |
| 300 | file format versions, it must have multiple text info files (all of which may |
| 301 | point to the same shared library). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 302 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 303 | The “api\_version” specifies the major.minor.patch version number of the Vulkan |
| 304 | API that the shared library (referenced by "library\_path") was built with. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 305 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 306 | There are no rules about the name of the text information files (except the |
| 307 | .json suffix). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 308 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 309 | There are no rules about the name of the ICD shared library files. For example, |
| 310 | if the registry contains the following values, |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 311 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 312 | ``` |
| 313 | [HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\] |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 314 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 315 | "C:\vendor a\vk\_vendora.json"=dword:00000000 |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 316 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 317 | "C:\windows\system32\vendorb\_vk.json"=dword:00000000 |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 318 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 319 | "C:\windows\system32\vendorc\_icd.json"=dword:00000000 |
| 320 | ``` |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 321 | then the loader will open the following text information files, with the |
| 322 | specified contents: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 323 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 324 | | Text File Name | Text File Contents | |
| 325 | |-------------------------------------| |
| 326 | |vk\_vendora.json | "ICD": { "library\_path": "C:\\\\VENDORA\\\\vk\_vendora.dll", "api_version": "1.0.3" } | |
| 327 | | vendorb\_vk.json | "ICD": { "library\_path": "vendorb\_vk.dll", "api_version": "1.0.3" } | |
| 328 | |vendorc\_icd.json | "ICD": { "library\_path": "vedorc\_icd.dll", "api_version": "1.0.3" }| |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 329 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 330 | Then the loader will open the three files mentioned in the "Text File Contents" |
| 331 | column, and then try to load and use the three shared libraries indicated by |
| 332 | the ICD.library\_path value. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 333 | |
| 334 | ##### Using Pre-Production ICDs |
| 335 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 336 | IHV developers (and sometimes other developers) need to use special, |
| 337 | pre-production ICDs. In some cases, a pre-production ICD may be in an |
| 338 | installable package. In other cases, a pre-production ICD may simply be a |
| 339 | shared library in the developer's build tree. In this latter case, we want to |
| 340 | allow developers to point to such an ICD without modifying the |
| 341 | properly-installed ICD(s) on their system. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 342 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 343 | This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, |
| 344 | which will override the mechanism used for finding properly-installed ICDs. In |
| 345 | other words, only the ICDs listed in "VK\_ICD\_FILENAMES" will be used. The |
| 346 | "VK\_ICD\_FILENAMES" environment variable is a semi-colon-separated list of ICD |
| 347 | text information files (aka manifest files), containing the following: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 348 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 349 | - A full pathname (e.g. "C:\\my\_build\\my\_icd.json") |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 350 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 351 | Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info |
| 352 | file for a developer-built ICD. A semi-colon is only used if more than one ICD |
| 353 | is listed. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 354 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 355 | For example, if a developer wants to refer to one ICD that they built, they |
| 356 | could set the "VK\_ICD\_FILENAMES" environment variable to: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 357 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 358 | C:\\my\_build\\my\_icd.json |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 359 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 360 | If a developer wants to refer to two ICDs, one of which is a properly-installed |
| 361 | ICD, they can use the full pathname of the text file: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 362 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 363 | C:\\Windows\\System32\\vendorc\_icd.json;C:\\my\_build\\my\_icd.json |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 364 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 365 | Notice the semi-colon between "C:\\Windows\\System32\\vendorc\_icd.json" and |
| 366 | "C:\\my\_build\\my\_icd.json". |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 367 | |
| 368 | #### Linux |
| 369 | |
| 370 | ##### Properly-Installed ICDs |
| 371 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 372 | In order to find properly-installed ICDs, the Vulkan loader will scan the files |
| 373 | in the following Linux directories: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 374 | |
| 375 | /usr/share/vulkan/icd.d |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 376 | /etc/vulkan/icd.d |
| 377 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 378 | These directories will contain text information files (a.k.a. "manifest |
| 379 | files"), that use a JSON format. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 380 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 381 | The Vulkan loader will open each manifest file found to obtain the name or |
| 382 | pathname of an ICD shared library (".so") file. For example: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 383 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 384 | ``` |
| 385 | { |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 386 | "file_format_version": "1.0.0", |
| 387 | "ICD": { |
| 388 | "library_path": "path to ICD library", |
Tony Barbour | cd48951 | 2016-02-10 15:59:32 -0700 | [diff] [blame] | 389 | "api_version": "1.0.3" |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 390 | } |
| 391 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 392 | ``` |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 393 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 394 | pathname to an ICD shared library file. If the ICD is specified via a filename, |
| 395 | the loader will attempt to open that file as a shared object using dlopen(), |
| 396 | and the file must be in a directory that dlopen is configured to look in (Note: |
| 397 | various distributions are configured differently). A distribution is free to |
| 398 | create Vulkan-specific system directories (e.g. ".../vulkan/icd"), but is not |
| 399 | required to do so. If the ICD is specified via a relative pathname, it is |
| 400 | relative to the path of the info file. Relative pathnames are those that do not |
| 401 | start with, but do contain at least one directory separator (i.e. the '/' |
| 402 | character). For example, "lib/vendora.so" and "./vendora.so" are examples of |
| 403 | relative pathnames. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 404 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 405 | The "file\_format\_version" provides a major.minor.patch version number in case |
| 406 | the format of the manifest file changes in the future. If the same ICD shared |
| 407 | library supports multiple, incompatible versions of manifest file format |
| 408 | versions, it must have multiple manifest files (all of which may point to the |
| 409 | same shared library). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 410 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 411 | The “api\_version” specifies the major.minor.patch version number of the Vulkan |
| 412 | API that the shared library (referenced by "library\_path") was built with. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 413 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 414 | The "/usr/share/vulkan/icd.d" directory is for ICDs that are installed from |
| 415 | Linux-distribution-provided packages. The "/etc/vulkan/icd.d" directory is for |
| 416 | ICDs that are installed from non-Linux-distribution-provided packages. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 417 | |
| 418 | There are no rules about the name of the text files (except the .json suffix). |
| 419 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 420 | There are no rules about the name of the ICD shared library files. For example, |
| 421 | if the "/usr/share/vulkan/icd.d" directory contain the following files, with |
| 422 | the specified contents: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 423 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 424 | | Text File Name | Text File Contents | |
| 425 | |-----------------|--------------------| |
| 426 | |vk\_vendora.json | "ICD": { "library\_path": "vendora.so", "api_version": "1.0.3" } | |
| 427 | | vendorb\_vk.json | "ICD": { "library\_path": "vendorb\_vulkan\_icd.so", "api_version": "1.0.3" } | |
| 428 | | vendorc\_icd.json | "ICD": { "library\_path": "/usr/lib/VENDORC/icd.so", "api_version": "1.0.1" }| |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 429 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 430 | then the loader will open the three files mentioned in the "Text File Contents" |
| 431 | column, and then try to load and use the three shared libraries indicated by |
| 432 | the ICD.library\_path value. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 433 | |
| 434 | ##### Using Pre-Production ICDs |
| 435 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 436 | IHV developers (and sometimes other developers) need to use special, |
| 437 | pre-production ICDs. In some cases, a pre-production ICD may be in an |
| 438 | installable package. In other cases, a pre-production ICD may simply be a |
| 439 | shared library in the developer's build tree. In this latter case, we want to |
| 440 | allow developers to point to such an ICD without modifying the |
| 441 | properly-installed ICD(s) on their system. |
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 | This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, |
| 444 | which will override the mechanism used for finding properly-installed ICDs. In |
| 445 | 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] | 446 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 447 | The "VK\_ICD\_FILENAMES" environment variable is a colon-separated list of ICD |
| 448 | manifest files, containing the following: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 449 | |
| 450 | - A filename (e.g. "libvkicd.json") in the "/usr/share/vulkan/icd.d" or "/etc/vulkan/icd.d" system directories |
| 451 | |
| 452 | - A full pathname (e.g. "/my\_build/my\_icd.json") |
| 453 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 454 | Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info |
| 455 | file for a developer-built ICD. A colon is only used if more than one ICD is |
| 456 | listed. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 457 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 458 | For example, if a developer wants to refer to one ICD that they built, they |
| 459 | could set the "VK\_ICD\_FILENAMES" environment variable to: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 460 | |
| 461 | /my\_build/my\_icd.json |
| 462 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 463 | If a developer wants to refer to two ICDs, one of which is a properly-installed |
| 464 | 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] | 465 | |
| 466 | vendorc\_vulkan.json:/my\_build/my\_icd.json |
| 467 | |
| 468 | Notice the colon between "vendorc\_vulkan.json" and "/my\_build/my\_icd.json". |
| 469 | |
| 470 | NOTE: this environment variable will be ignored for suid programs. |
| 471 | |
| 472 | #### Android |
| 473 | |
| 474 | TODO: Fill out this section |
| 475 | |
| 476 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 477 | ICD interface requirements |
| 478 | ---------------------------------------- |
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 | Generally, for all Vulkan commands issued by an application, the loader can be |
| 481 | viewed as a pass through. That is, the loader generally doesn’t modified the |
| 482 | commands or their parameters but simply calls the ICDs entry point for that |
| 483 | command. Thus, the loader to ICD interface requirements will be specified by |
| 484 | covering two areas: 1) Obtaining ICD Vulkan entry points; 2) Specifying |
| 485 | requirements for a given Vulkan command(s) over and above the Vulkan |
| 486 | specification requirements. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 487 | |
| 488 | #### Windows and Linux |
| 489 | |
| 490 | ##### Obtaining ICD entry points |
| 491 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 492 | Currently, two methods of the loader finding ICD entry points are supported on |
| 493 | Linux and Windows: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 494 | |
| 495 | 1) Recommended |
| 496 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 497 | - vk\_icdGetInstanceProcAddr exported in the ICD library and it returns valid |
| 498 | function pointers for all the global level and instance level Vulkan commands, |
| 499 | and also vkGetDeviceProcAddr. Global level commands are those which contain no |
| 500 | dispatchable object as the first parameter, such as vkCreateInstance and |
| 501 | vkEnumerateInstanceExtensionProperties. The ICD must support querying global |
| 502 | level entry points by calling vk\_icdGetInstanceProcAddr with a NULL VkInstance |
| 503 | parameter. Instance level commands are those that have either VkInstance, or |
| 504 | VkPhysicalDevice as the first parameter dispatchable object. Both core entry |
| 505 | points and any instance extension entry points the ICD supports should be |
| 506 | available via vk\_icdGetInstanceProcAddr. Future Vulkan instance extensions may |
| 507 | define and use new instance level dispatchable objects other than VkInstance |
| 508 | and VkPhysicalDevice, in which case, extensions entry points using these newly |
| 509 | defined dispatchable oibjects must be queryable via vk\_icdGetInstanceProcAddr. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 510 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 511 | - All other Vulkan entry points must either NOT be exported from the ICD |
| 512 | library or else NOT use the official Vulkan function names if they are |
| 513 | exported. This requirement is for ICD libraries that include other |
| 514 | functionality (such as OpenGL library) and thus could be loaded by the |
| 515 | application prior to when the Vulkan loader library is loaded by the |
| 516 | application. In other words, the ICD library exported Vulkan symbols must not |
| 517 | clash with the loader's exported Vulkan symbols. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 518 | |
| 519 | 2) Deprecated |
| 520 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 521 | - vkGetInstanceProcAddr exported in the ICD library and returns valid function |
| 522 | pointers for all the Vulkan API entrypoints. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 523 | |
| 524 | - vkCreateInstance exported in the ICD library; |
| 525 | |
| 526 | - vkEnumerateInstanceExtensionProperties exported in the ICD library; |
| 527 | |
| 528 | ##### Loader specific requirements for Vulkan commands |
| 529 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 530 | Normally, ICDs handle object creation and destruction for various Vulkan |
| 531 | objects. The WSI surface extensions for Linux and Windows |
| 532 | (VK\_KHR\_win32\_surface, VK\_KHR\_xcb\_surface, VK\_KHR\_xlib\_surface, |
| 533 | VK\_KHR\_mir\_surface, VK\_KHR\_wayland\_surface, and VK\_KHR\_surface) are |
| 534 | handled differently. For these extensions, the VkSurfaceKHR object creation and |
| 535 | destruction is handled by the loader as follows: |
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 | 1. Loader handles the vkCreate\*SurfaceKHR() and vkDestroySurfaceKHR() |
| 538 | functions including creating/destroying the VkSurfaceKHR object. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 539 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 540 | 2. VkSurfaceKHR objects have the underlying structure (VkIcdSurface\*) as |
| 541 | defined in include/vulkan/vk\_icd.h. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 542 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 543 | 3. ICDs can cast any VkSurfaceKHR object to a pointer to the appropriate |
| 544 | VkIcdSurface\* structure. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 545 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 546 | 4. VkIcdSurface\* structures include VkIcdSurfaceWin32, VkIcdSurfaceXcb, |
| 547 | VkIcdSurfaceXlib, VkIcdSurfaceMir, and VkIcdSurfaceWayland. The first field in |
| 548 | the structure is a VkIcdSurfaceBase enumerant that indicates westher the |
| 549 | surface object is Win32, Xcb, Xlib, Mir, or Wayland. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 550 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 551 | As previously covered, the loader requires dispatch tables to be accessible |
| 552 | within Vulkan dispatchable objects, which include VkInstance, VkPhysicalDevice, |
| 553 | VkDevice, VkQueue, and VkCommandBuffer. The specific requirements on all |
| 554 | dispatchable objects created by ICDs are as follows: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 555 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 556 | - All dispatchable objects created by an ICD can be cast to void \*\* |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 557 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 558 | - The loader will replace the first entry with a pointer to the dispatch table |
| 559 | 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] | 560 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 561 | 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] | 562 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 563 | 2. This pointer points to a regular C structure with the first entry being a |
| 564 | pointer. Note: for any C\++ ICD's that implement VK objects directly as C\++ |
| 565 | classes. The C\++ compiler may put a vtable at offset zero if your class is |
| 566 | virtual. In this case use a regular C structure (see below). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 567 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 568 | 3. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the created |
| 569 | dispatchable objects, as follows (see include/vulkan/vk\_icd.h): |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 570 | |
| 571 | ``` |
| 572 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 573 | #include "vk_icd.h" |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 574 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 575 | union _VK_LOADER_DATA { |
| 576 | uintptr loadermagic; |
| 577 | void *loaderData; |
| 578 | } VK_LOADER_DATA; |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 579 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 580 | vkObj alloc_icd_obj() |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 581 | { |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 582 | vkObj *newObj = alloc_obj(); |
| 583 | ... |
| 584 | // Initialize pointer to loader's dispatch table with ICD_LOADER_MAGIC |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 585 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 586 | set_loader_magic_value(newObj); |
| 587 | ... |
| 588 | return newObj; |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 589 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 590 | ``` |
| 591 | |
| 592 | Additional Notes: |
| 593 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 594 | - The loader will filter out extensions requested in vkCreateInstance and |
| 595 | vkCreateDevice before calling into the ICD; Filtering will be of extensions |
| 596 | advertised by entities (eg layers) different from the ICD in question. |
| 597 | - The loader will not call ICD for vkEnumerate\*LayerProperties() as layer |
| 598 | properties are obtained from the layer libraries and layer JSON files. |
| 599 | - If an ICD library wants to implement a layer it can do so by having the |
| 600 | appropriate layer JSON manifest file refer to the ICD library file. |
| 601 | - The loader will not call ICD for vkEnumerate\*ExtensionProperties(pLayerName |
| 602 | != NULL). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 603 | - The ICD may or may not implement a dispatch table. |
| 604 | |
| 605 | #### Android |
| 606 | |
| 607 | TODO: Fill out this section |
| 608 | |
| 609 | Vulkan layer interface with the loader |
| 610 | -------------------------------------- |
| 611 | |
| 612 | ### Layer discovery |
| 613 | |
| 614 | #### Windows |
| 615 | |
| 616 | ##### Properly-Installed Layers |
| 617 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 618 | In order to find properly-installed layers, the Vulkan loader will use a |
| 619 | similar mechanism as used for ICDs. Text information files (aka manifest |
| 620 | files), that use a JSON format, are read in order to identify the names and |
| 621 | attributes of layers and their extensions. The use of manifest files allows the |
| 622 | loader to avoid loading any shared library files when the application does not |
| 623 | query nor request any extensions. Layers and extensions have additional |
| 624 | complexity, and so their manifest files contain more information than ICD info |
| 625 | files. For example, a layer shared library file may contain multiple |
| 626 | layers/extensions (perhaps even an ICD). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 627 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 628 | In order to find properly-installed layers, the Vulkan loader will scan the |
| 629 | values in the following Windows registry keys: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 630 | |
| 631 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers |
| 632 | |
| 633 | HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers |
| 634 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 635 | Explicit layers are those which are enabled by an application (e.g. with the |
| 636 | vkCreateInstance function), or by an environment variable (as mentioned |
| 637 | previously). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 638 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 639 | Implicit layers are those which are enabled by their existence. For example, |
| 640 | certain application environments (e.g. Steam or an automotive infotainment |
| 641 | system) may have layers which they always want enabled for all applications |
| 642 | that they start. Other implicit layers may be for all applications started on a |
| 643 | given system (e.g. layers that overlay frames-per-second). Implicit layers are |
| 644 | enabled automatically, whereas explicit layers must be enabled explicitly. What |
| 645 | distinguishes a layer as implicit or explicit is by which registry key its |
| 646 | layer information file is referenced by. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 647 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 648 | For each value in these keys which has DWORD data set to 0, the loader opens |
| 649 | the JSON manifest file specified by the name of the value. Each name must be a |
| 650 | full pathname to the manifest file. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 651 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 652 | The Vulkan loader will open each info file to obtain information about the |
| 653 | layer, including the name or pathname of a shared library (".dll") file. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 654 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 655 | This manifest file is in the JSON format and contains the following |
| 656 | information: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 657 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 658 | - (required) "file\_format\_version" - same as for ICDs, except that the format |
| 659 | version can vary independently for ICDs and layers. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 660 | |
| 661 | - (required) "name" - layer name |
| 662 | |
| 663 | - (required) "type" - which layer chains should the layer be activated on. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 664 | Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate on |
| 665 | both device and instance chains. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 666 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 667 | - (required) "library\_path" - filename / full path / relative path to the |
| 668 | library file |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 669 | |
| 670 | - (required) "api\_version" - same as for ICDs. |
| 671 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 672 | - (required) "implementation\_version" - layer version, a single number |
| 673 | increasing with backward compatible changes. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 674 | |
| 675 | - (required) "description" - informative description of the layer. |
| 676 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 677 | - (optional) "device\_extensions" or "instance\_extensions" - array of |
| 678 | extension information as follows |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 679 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 680 | - (required) extension "name" - Vulkan registered name |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 681 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 682 | - (required) extension "spec\_version" - extension specification version, a |
| 683 | single number, increasing with backward compatible changes. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 684 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 685 | - (required for device\_extensions with entry points) extension |
| 686 | "entrypoints" - array of device extension entrypoints; not used for instance |
| 687 | extensions |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 688 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 689 | - (sometimes required) "functions" - mapping list of function entry points. If |
| 690 | multiple layers exist within the same shared library (or if a layer is in the |
| 691 | same shared library as an ICD), this must be specified to allow each layer to |
| 692 | have its own vkGet\*ProcAddr entrypoints that can be found by the loader. At |
| 693 | this time, only the following two functions are required: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 694 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 695 | - "vkGetInstanceProcAddr" name |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 696 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 697 | - "vkGetDeviceProcAddr" name |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 698 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 699 | - (optional for implicit layers) "enable\_environment" requirement(s) - |
| 700 | environment variable and value required to enable an implicit layer. This |
| 701 | environment variable (which should vary with each "version" of the layer, as in |
| 702 | "ENABLE\_LAYER\_FOO\_1") must be set to the given value or else the implicit |
| 703 | layer is not loaded. This is for application environments (e.g. Steam) which |
| 704 | want to enable a layer(s) only for applications that they launch, and allows |
| 705 | for applications run outside of an application environment to not get that |
| 706 | implicit layer(s). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 707 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 708 | - (required for implicit layers) "disable\_environment" requirement(s) - |
| 709 | environment variable and value required to disable an implicit layer. Note: in |
| 710 | rare cases of an application not working with an implicit layer, the |
| 711 | application can set this environment variable (before calling Vulkan functions) |
| 712 | in order to "blacklist" the layer. This environment variable (which should vary |
| 713 | with each "version" of the layer, as in "DISABLE\_LAYER\_FOO\_1") must be set |
| 714 | (not particularly to any value). If both the "enable\_environment" and |
| 715 | "disable\_environment" variables are set, the implicit layer is disabled. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 716 | |
| 717 | For example: |
| 718 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 719 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 720 | { |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 721 | "file_format_version" : "1.0.0", |
| 722 | "layer": { |
| 723 | "name": "VK_LAYER_LUNARG_OverlayLayer", |
| 724 | "type": "DEVICE", |
| 725 | "library_path": "vkOverlayLayer.dll" |
| 726 | "api_version" : "1.0.3", |
| 727 | "implementation_version" : "2", |
| 728 | "description" : "LunarG HUD layer", |
| 729 | "functions": { |
| 730 | "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr", |
| 731 | "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr" |
| 732 | }, |
| 733 | instance_extensions": [ |
| 734 | { |
| 735 | "name": "VK_debug_report_EXT", |
| 736 | "spec_version": "1" |
| 737 | }, |
| 738 | { |
| 739 | "name": "VK_VENDOR_DEBUG_X", |
| 740 | "spec_version": "3" |
| 741 | } |
| 742 | ], |
| 743 | device_extensions": [ |
| 744 | { |
| 745 | "name": "VK_LUNARG_DEBUG_MARKER", |
| 746 | "spec_version": "1", |
| 747 | "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"] |
| 748 | } |
| 749 | ], |
| 750 | "disable_environment": { |
| 751 | "DISABLE_LAYER_OVERLAY_1": "" |
| 752 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 753 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 754 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 755 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 756 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 757 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 758 | pathname to a layer shared library (".dll") file, which the loader will attempt |
| 759 | to load using LoadLibrary(). If the layer is specified via a relative pathname, |
| 760 | it is relative to the path of the info file (e.g. for cases when an application |
| 761 | provides a layer that is in the same folder hierarchy as the rest of the |
| 762 | application files). If the layer is specified via a filename, the shared |
| 763 | library lives in the system's DLL search path (e.g. in the |
| 764 | "C:\\Windows\\System32" folder). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 765 | |
| 766 | There are no rules about the name of the text files (except the .json suffix). |
| 767 | |
| 768 | There are no rules about the name of the layer shared library files. |
| 769 | |
| 770 | ##### Using Pre-Production Layers |
| 771 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 772 | As with ICDs, developers may need to use special, pre-production layers, |
| 773 | without modifying the properly-installed layers. This need is met with the use |
| 774 | of the "VK\_LAYER\_PATH" environment variable, which will override the |
| 775 | mechanism using for finding properly-installed layers. Because many layers may |
| 776 | exist on a system, this environment variable is a semi-colon-separated list of |
| 777 | folders that contain layer info files. Only the folder listed in |
| 778 | "VK\_LAYER\_PATH" will be scanned for info files. Each semi-colon-separated |
| 779 | entry is: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 780 | |
| 781 | - The full pathname of a folder containing layer info files |
| 782 | |
| 783 | #### Linux |
| 784 | |
| 785 | ##### Properly-Installed Layers |
| 786 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 787 | In order to find properly-installed layers, the Vulkan loader will use a |
| 788 | similar mechanism as used for ICDs. Text information files, that use a JSON |
| 789 | format, are read in order to identify the names and attributes of layers and |
| 790 | their extensions. The use of text info files allows the loader to avoid loading |
| 791 | any shared library files when the application does not query nor request any |
| 792 | extensions. Layers and extensions have additional complexity, and so their info |
| 793 | files contain more information than ICD info files. For example, a layer shared |
| 794 | library file may contain multiple layers/extensions (perhaps even an ICD). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 795 | |
| 796 | The Vulkan loader will scan the files in the following Linux directories: |
| 797 | |
| 798 | /usr/share/vulkan/explicit\_layer.d |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 799 | /usr/share/vulkan/implicit\_layer.d |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 800 | /etc/vulkan/explicit\_layer.d |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 801 | /etc/vulkan/implicit\_layer.d |
| 802 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 803 | Explicit layers are those which are enabled by an application (e.g. with the |
| 804 | vkCreateInstance function), or by an environment variable (as mentioned |
| 805 | previously). Implicit layers are those which are enabled by their existence. |
| 806 | For example, certain application environments (e.g. Steam or an automotive |
| 807 | infotainment system) may have layers which they always want enabled for all |
| 808 | applications that they start. Other implicit layers may be for all applications |
| 809 | started on a given system (e.g. layers that overlay frames-per-second). |
| 810 | Implicit layers are enabled automatically, whereas explicit layers must be |
| 811 | enabled explicitly. What distinguishes a layer as implicit or explicit is by |
| 812 | which directory its layer information file exists in. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 813 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 814 | The "/usr/share/vulkan/\*\_layer.d" directories are for layers that are |
| 815 | installed from Linux-distribution-provided packages. The |
| 816 | "/etc/vulkan/\*\_layer.d" directories are for layers that are installed from |
| 817 | non-Linux-distribution-provided packages. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 818 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 819 | The information file is in the JSON format and contains the following |
| 820 | information: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 821 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 822 | - (required) "file\_format\_version" – same as for ICDs, except that the format |
| 823 | version can vary independently for ICDs and layers. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 824 | |
| 825 | - (required) "name" - layer name |
| 826 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 827 | - (required) "type" - which layer chains should the layer be activated on. |
| 828 | Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate on |
| 829 | both device and instance chains. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 830 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 831 | - (required) "library\_path" - filename / full path / relative path to the text |
| 832 | file |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 833 | |
| 834 | - (required) "api\_version" – same as for ICDs. |
| 835 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 836 | - (required) "implementation\_version" – layer version, a single number |
| 837 | increasing with backward compatible changes. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 838 | |
| 839 | - (required) "description" – informative decription of the layer. |
| 840 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 841 | - (optional) "device\_extensions" or "instance\_extensions" - array of |
| 842 | extension information as follows |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 843 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 844 | - (required) extension "name" - Vulkan registered name |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 845 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 846 | - (required) extension "spec\_version" - extension specification version, a |
| 847 | single number, increasing with backward compatible changes. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 848 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 849 | - (required for device extensions with entry points) extension |
| 850 | "entrypoints" - array of device extension entrypoints; not used for instance |
| 851 | extensions |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 852 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 853 | - (sometimes required) "functions" - mapping list of function entry points. If |
| 854 | multiple layers exist within the same shared library (or if a layer is in the |
| 855 | same shared library as an ICD), this must be specified to allow each layer to |
| 856 | have its own vkGet\*ProcAddr entrypoints that can be found by the loader. At |
| 857 | this time, only the following two functions are required: |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 858 | - "vkGetInstanceProcAddr" name |
| 859 | - "vkGetDeviceProcAddr" name |
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 | - (optional for implicit layers) "enable\_environment" requirement(s) - |
| 862 | environment variable and value required to enable an implicit layer. This |
| 863 | environment variable (which should vary with each "version" of the layer, as in |
| 864 | "ENABLE\_LAYER\_FOO\_1") must be set to the given value or else the implicit |
| 865 | layer is not loaded. This is for application environments (e.g. Steam) which |
| 866 | want to enable a layer(s) only for applications that they launch, and allows |
| 867 | for applications run outside of an application environment to not get that |
| 868 | implicit layer(s). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 869 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 870 | - (required for implicit layers) "disable\_environment" requirement(s) - |
| 871 | environment variable and value required to disable an implicit layer. Note: in |
| 872 | rare cases of an application not working with an implicit layer, the |
| 873 | application can set this environment variable (before calling Vulkan functions) |
| 874 | in order to "blacklist" the layer. This environment variable (which should vary |
| 875 | with each "version" of the layer, as in "DISABLE\_LAYER\_FOO\_1") must be set |
| 876 | (not particularly to any value). If both the "enable\_environment" and |
| 877 | "disable\_environment" variables are set, the implicit layer is disabled. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 878 | |
| 879 | For example: |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 880 | ``` |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 881 | { |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 882 | "file_format_version" : "1.0.0", |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 883 | "layer": { |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 884 | "name": "VK_LAYER_LUNARG_OverlayLayer", |
| 885 | "type": "DEVICE", |
| 886 | "library_path": "vkOverlayLayer.dll" |
| 887 | "api_version" : "1.0.3", |
| 888 | "implementation_version" : "2", |
| 889 | "description" : "LunarG HUD layer", |
| 890 | "functions": { |
| 891 | "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr", |
| 892 | "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr" |
| 893 | }, |
| 894 | instance_extensions": [ |
| 895 | { |
| 896 | "name": "VK_debug_report_EXT", |
| 897 | "spec_version": "1" |
| 898 | }, |
| 899 | { |
| 900 | "name": "VK_VENDOR_DEBUG_X", |
| 901 | "spec_version": "3" |
| 902 | } |
| 903 | ], |
| 904 | device_extensions": [ |
| 905 | { |
| 906 | "name": "VK_LUNARG_DEBUG_MARKER", |
| 907 | "spec_version": "1", |
| 908 | "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"] |
| 909 | } |
| 910 | ], |
| 911 | "disable_environment": { |
| 912 | "DISABLE_LAYER_OVERLAY_1": "" |
| 913 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 914 | } |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 915 | } |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 916 | ``` |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 917 | The "library\_path" specifies either a filename, a relative pathname, or a full |
| 918 | pathname to a layer shared library (".so") file, which the loader will attempt |
| 919 | to load using dlopen(). If the layer is specified via a filename, the loader |
| 920 | will attempt to open that file as a shared object using dlopen(), and the file |
| 921 | must be in a directory that dlopen is configured to look in (Note: various |
| 922 | distributions are configured differently). A distribution is free to create |
| 923 | Vulkan-specific system directories (e.g. ".../vulkan/layers"), but is not |
| 924 | required to do so. If the layer is specified via a relative pathname, it is |
| 925 | relative to the path of the info file (e.g. for cases when an application |
| 926 | provides a layer that is in the same directory hierarchy as the rest of the |
| 927 | application files). |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 928 | |
| 929 | There are no rules about the name of the text files (except the .json suffix). |
| 930 | |
| 931 | There are no rules about the name of the layer shared library files. |
| 932 | |
| 933 | ##### Using Pre-Production Layers |
| 934 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 935 | As with ICDs, developers may need to use special, pre-production layers, |
| 936 | without modifying the properly-installed layers. This need is met with the use |
| 937 | of the "VK\_LAYER\_PATH" environment variable, which will override the |
| 938 | mechanism using for finding properly-installed layers. Because many layers may |
| 939 | exist on a system, this environment variable is a colon-separated list of |
| 940 | directories that contain layer info files. Only the directories listed in |
| 941 | "VK\_LAYER\_PATH" will be scanned for info files. Each colon-separated entry |
| 942 | is: |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 943 | |
| 944 | - The full pathname of a directory containing layer info files |
| 945 | |
| 946 | NOTE: these environment variables will be ignored for suid programs. |
| 947 | |
| 948 | #### Android |
| 949 | |
| 950 | TODO: Fill out this section |
| 951 | |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 952 | Layer interface requirements |
| 953 | ------------------------------------------------------ |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 954 | |
| 955 | #### Architectural interface overview |
| 956 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 957 | There are two key architectural features that drive the loader to layer library |
| 958 | interface: 1) separate and distinct instance and device call chains, and 2) |
| 959 | distributed dispatch. First these architectural features will be described and |
| 960 | then the detailed interface will be specified. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 961 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 962 | Call chains are the links of calls for a given Vulkan command from layer module |
| 963 | to layer module with the loader and or the ICD being the bottom most command. |
| 964 | Call chains are constructed at both the instance level and the device level by |
| 965 | the loader with cooperation from the layer libraries. Instance call chains are |
| 966 | constructed by the loader when layers are enabled at vkCreateInstance. Device |
| 967 | call chains are constructed by the loader when layers are enabled at |
| 968 | CreateDevice. A layer can intercept Vulkan instance commands, device commands |
| 969 | or both. For a layer to intercept instance commands, it must participate in the |
| 970 | instance call chain. For a layer to intercept device commands, it must |
| 971 | participate in the device chain. Layers which participate in intercepting calls |
| 972 | in both the intance and device chains are called global layers. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 973 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 974 | Normally, when a layer intercepts a given Vulkan command, it will call down the |
| 975 | instance or device chain as needed. The loader and all layer libraries that |
| 976 | participate in a call chain cooperate to ensure the correct sequencing of calls |
| 977 | from one entity to the next. This group effort for call cahin sequencing is |
| 978 | hereinafter referred to as disitributed dispatch. In distributed dispatch, |
| 979 | since each layer is responsible for properly calling the next entity in the |
| 980 | device or instance chain, a dispatch mechanism is required for all Vulkan |
| 981 | commands a layer intercepts. For Vulkan commands that are not intercepted by a |
| 982 | layer, or if the layer chooses to terminate a given Vulkman command by not |
| 983 | calling down the chain, then no dispatch mechanism is needed for that |
| 984 | particular Vulkan command. Only for those Vulkan commands, which may be a |
| 985 | subset of all Vulkan commands, that a layer intercepts is a dispatching |
| 986 | mechanism by the layer needed. The loader is responsible for dispatching all |
| 987 | core and instance extension Vulkan commands to the first entity in the chain. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 988 | |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 989 | Instance level Vulkan commands are those that have the disapatchable objects |
| 990 | VkInstance, or VkPhysicalDevice as the first parameter and alos includes |
| 991 | vkCreateInstance. |
| 992 | Device level Vulkan commands are those that use VkDevice, VkQueue or |
| 993 | VkCommandBuffer as the first parameter and also include vkCreateDevice. Future |
| 994 | extensions may introduce new instance or device level dispatchable objects, so |
| 995 | the above lists may be extended in the future. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 996 | |
| 997 | #### Discovery of layer entrypoints |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 998 | For the layer libraries that have been discovered by the loader, their |
| 999 | intercepting entry points that will participate in a device or instance call |
| 1000 | chain need to be available to the loader or whatever layer is before them in |
| 1001 | the chain. Layers having the following requirements in this area. |
| 1002 | - A layer intercepting instance level Vulkan commands (aka an instance level |
| 1003 | layer) must implement a vkGetInstanceProcAddr type of function. |
| 1004 | - This vkGetInstanceProcAddr type function must be exported by the layer |
| 1005 | library. The name of this function is specified in various ways: 1) the layer |
| 1006 | manifest JSON file in the "functions", "vkGetInstanceProcAddr" node |
| 1007 | (Linux/Windows); 2) it is named "vkGetInstanceProcAddr"; 3) it is |
| 1008 | "<layerName>GetInstanceProcAddr (Android). |
| 1009 | - A layer intercepting device level Vulkan commands (aka a device level layer) |
| 1010 | must implement a vkGetDeviceProcAddr type of function. |
| 1011 | - This vkGetDeviceProcAddr type function must be exported by the layer library. |
| 1012 | The name of this function is specified in various ways: 1) the layer manifest |
| 1013 | JSON file in the "functions", "vkGetDeviceProcAddr" node (Linux/Windows); 2) it |
| 1014 | is named "vkGetDeviceProcAddr"; 3) it is "<layerName>GetDeviceProcAddr |
| 1015 | (Android). |
| 1016 | - A layer's vkGetInstanceProcAddr function (irregardless of it's name) must |
| 1017 | return the local entry points for all instance level Vulkan commands it |
| 1018 | intercepts. At a minimum, this includes vkGetInstanceProcAddr and |
| 1019 | vkCreateInstance. |
| 1020 | - A layer's vkGetDeviceProcAddr function (irregardless of it's name) must |
| 1021 | return the entry points for all device level Vulkan commands it intercepts. At |
| 1022 | a minimum, this includes vkGetDeviceProcAddr and vkCreateDevice. |
| 1023 | - There are no requirements on the names of the intercepting functions a layer |
| 1024 | implements except those listed above for vkGetInstanceProcAddr and |
| 1025 | vkGetDeviceProcAddr. |
| 1026 | - Currently a layer's VkGetInstanceProcAddr must be able to handle a VkInstance |
| 1027 | parameter equal to NULL for |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1028 | instance level commands it intercepts including vkCreateDevice. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1029 | - Currently a layer's VkGetDeviceProcAddr must be able to handle a VkDevice |
| 1030 | parameter equal to NULL for device level commands it intercepts. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1031 | |
| 1032 | #### Layer intercept requirements |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1033 | - Layers intercept a Vulkan command by defining a C/C++ function with signature |
| 1034 | identical to the Vulkan API for that command. |
| 1035 | - Other than the two vkGet*ProcAddr, all other functions intercepted by a layer |
| 1036 | need NOT be exported by the layer. |
| 1037 | - For any Vulkan command a layer intercepts which has a non-void return value, |
| 1038 | an appropriate value must be returned by the layer intercept function. |
| 1039 | - The layer intercept function must call down the chain to the corresponding |
| 1040 | Vulkan command in the next entity. Undefined results will occur if a layer |
| 1041 | doesn't propagate calls down the chain. The two exceptions to this requirement |
| 1042 | are vkGetInstanceProcAddr and vkGetDeviceProcAddr which only call down the |
| 1043 | chain for Vulkan commands that they do not intercept. |
| 1044 | - Layer intercept functions may insert extra calls to Vulkan commands in |
| 1045 | addition to the intercept. For example, a layer intercepting vkQueueSubmit may |
| 1046 | want to add a call to vkQueueWaitIdle after calling down the chain for |
| 1047 | vkQueueSubmit. Any additional calls inserted by a layer must be on the same |
| 1048 | chain. They should call down the chain. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1049 | |
| 1050 | #### Distributed dispatching requirements |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1051 | - For each entry point a layer intercepts, it must keep track of the entry |
| 1052 | point residing in the next entity in the chain it will call down into. In other |
| 1053 | words, the layer must have a list of pointers to functions of the appropriate |
| 1054 | type to call into the next entity. This can be implemented in various ways but |
| 1055 | for clarity will be referred to as a dispatch table. |
| 1056 | - A layer can use the VkLayerDispatchTable structure as a device dispatch table |
| 1057 | (see include/vulkan/vk_layer.h). |
| 1058 | - A layer can use the VkLayerInstanceDispatchTable structure as a instance |
| 1059 | dispatch table (see include/vulkan/vk_layer.h). |
| 1060 | - Layers vkGetInstanceProcAddr function uses the next entity's |
| 1061 | vkGetInstanceProcAddr to call down the chain for unknown (ie non-intercepted) |
| 1062 | functions. |
| 1063 | - Layers vkGetDeviceProcAddr function uses the next entity's |
| 1064 | vkGetDeviceProcAddr to call down the chain for unknown (ie non-intercepted) |
| 1065 | functions. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1066 | |
| 1067 | #### Layer dispatch initialization |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1068 | - A layer intializes it's instance dispatch table within it's vkCreateInstance |
| 1069 | function. |
| 1070 | - A layer intializes it's device dispatch table within it's vkCreateDevice |
| 1071 | function. |
| 1072 | - The loader passes a linked list of initialization structures to layers via |
| 1073 | the "pNext" field in the VkInstanceCreateInfo and VkDeviceCreateInfo structures |
| 1074 | for vkCreateInstance and VkCreateDevice respectively. |
| 1075 | - The head node in this linked list is of type VkLayerInstanceCreateInfo for |
| 1076 | instance and VkLayerDeviceCreateInfo for device. See file |
| 1077 | include/vulkan/vk_layer.h for details. |
| 1078 | - A VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO is used by the loader for the |
| 1079 | "sType" field in VkLayerInstanceCreateInfo. |
| 1080 | - A VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO is used by the loader for the |
| 1081 | "sType" field in VkLayerDeviceCreateInfo. |
| 1082 | - The "function" field indicates how the union field "u" should be interpreted |
| 1083 | within VkLayer*CreateInfo. The loader will set the "function" field to |
| 1084 | VK_LAYER_LINK_INFO. This indicates "u" field should be VkLayerInstanceLink or |
| 1085 | VkLayerDeviceLink. |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1086 | - The VkLayerInstanceLink and VkLayerDeviceLink structures are the list nodes. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1087 | - The VkLayerInstanceLink contains the next entity's vkGetInstanceProcAddr used |
| 1088 | by a layer. |
| 1089 | - The VkLayerDeviceLink contains the next entity's vkGetInstanceProcAddr and |
| 1090 | vkGetDeviceProcAddr used by a layer. |
| 1091 | - Given the above structures set up by the loader, layer must initialize their |
| 1092 | dispatch table as follows: |
| 1093 | - Find the VkLayerInstanceCreateInfo/VkLayerDeviceCreateInfo structure in |
| 1094 | the VkInstanceCreateInfo/VkDeviceCreateInfo structure. |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1095 | - Get the next entity's vkGet*ProcAddr from the "pLayerInfo" field. |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1096 | - For CreateInstance get the next entity's vkCreateInstance by calling the |
| 1097 | "pfnNextGetInstanceProcAddr": |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1098 | pfnNextGetInstanceProcAddr(NULL, "vkCreateInstance"). |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1099 | - For CreateDevice get the next entity's vkCreateDevice by calling the |
| 1100 | "pfnNextGetInstanceProcAddr": |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1101 | pfnNextGetInstanceProcAddr(NULL, "vkCreateDevice"). |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1102 | - Advanced the linked list to the next node: pLayerInfo = pLayerInfo->pNext. |
| 1103 | - Call down the chain either CreateDevice or CreateInstance |
Courtney Goeltzenleuchter | a147376 | 2016-02-14 09:31:24 -0700 | [diff] [blame] | 1104 | - Initialize your layer dispatch table by calling the next entity's |
| 1105 | Get*ProcAddr function once for each Vulkan command needed in your dispatch |
| 1106 | table |
Jon Ashburn | cc300a2 | 2016-02-11 14:57:30 -0700 | [diff] [blame] | 1107 | |
| 1108 | Example code for CreateInstance: |
| 1109 | Example code for CreateDevice |
| 1110 | #### Special Considerations |
| 1111 | Wrapping versus maps. |
| 1112 | create dispatchable objects |
Jon Ashburn | c297268 | 2016-02-08 15:42:01 -0700 | [diff] [blame] | 1113 | |