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