1# Vulkan Loader Specification and Architecture Overview 2 3 4Goals of this document 5---------------------- 6 7Specify necessary functions and expected behavior of interface between the 8loader library and ICDs and layers for Windows, Linux and Android based 9systems. Also describe the application visible behaviors of the loader. 10 11Audience 12-------- 13 14Application, Vulkan driver and Vulkan layer developers. 15 16Any developers interested in understanding more about loader and layer behavior 17and architecture. 18 19 20Loader goals 21------------ 22 23- Support multiple ICDs (Installable Client Drivers) to co-exist on a system 24without interfering with each other. 25 26- Support optional modules (layers) that can be enabled by an application, 27developer or the system and have no impact when not enabled. 28 29- Negligible performance cost for an application calling through the loader 30to an ICD entry point. 31 32Architectural overview of layers and loader 33------------------------------------------- 34 35Vulkan is a layered architecture. Layers can hook (intercept) Vulkan commands to 36achieve various functionality that a Vulkan driver (aka ICD) or loader doesn’t 37support. Functionality such as Vulkan API tracing and debugging, API usage 38validation, and other tools such as framebuffer overlays are all natural 39candidates for Vulkan layers. Layers are implemented as libraries that are 40inserted between the application and the driver. 41 42Not only is Vulkan a layered architecture but it also supports multiple GPUs 43and their drivers. Vulkan commands called by an application may wind up calling 44into a diverse set of modules: loader, layers, and ICDs. The loader is critical 45to managing the proper dispatching of Vulkan commands to the appropriate set of 46layers and ICDs. The Vulkan object model allows the loader to insert layers 47into a call chain so the layers can process Vulkan commands prior to the 48ICD being called. 49 50Vulkan uses an object model to control the scope of a particular action / 51operation. The object to be acted on is always the first parameter of a Vulkan 52call and is a dispatchable object (see Vulkan specification section 2.2 Object 53Model). Under the covers, the dispatchable object handle is a pointer to a 54structure that contains a pointer to a dispatch table maintained by the loader. 55This dispatch table contains pointers to the Vulkan functions appropriate to 56that object. There are two types of dispatch tables the loader maintains, 57Instance and Device. I.e. a VkInstance object’s dispatch table will point to Vulkan 58functions such as vkEnumeratePhysicalDevices, vkDestroyInstance, 59vkCreateInstance, etc. Instance functions take a VkInstance or VkPhysicalDevice as 60their first argument. 61 62Device objects have a separate dispatch table containing the appropriate 63function pointers. The device dispatch table is used for all functions that 64take a VkDevice, VkQueue or VkCommandBuffer as their first argument. 65 66These instance and device dispatch tables are constructed when the application 67calls vkCreateInstance and vkCreateDevice. At that time the application and/or 68system can specify optional layers to be included. The loader will initialize 69the specified layers to create a call chain for each Vulkan function and each 70entry of the dispatch table will point to the first element of that chain. 71Thus, the loader builds an instance call chain for each VkInstance that is 72created and a device call chain for each VkDevice that is created. 73 74For example, the diagram below represents what happens in the call chain for 75vkCreateInstance. After initializing the chain, the loader will call into the 76first layer’s vkCreateInstance which will call the next finally terminating in 77the loader again where this function calls every ICD’s vkCreateInstance and 78saves the results. This allows every enabled layer for this chain to set up 79what it needs based on the VkInstanceCreateInfo structure from the application. 80![Instance call chain](instance_call_chain.png) 81 82This also highlights some of the complexity the loader must manage when using 83instance chains. As shown here, the loader must aggregate information from 84multiple devices when they are present. This means that the loader has to know 85about instance level extensions to aggregate them correctly. 86 87Device chains are created at vkCreateDevice and are generally simpler because 88they deal with only a single device and the ICD can always be the terminator of 89the chain. The below diagram also illustrates how layers (either device or 90instance) can skip intercepting any given Vulkan entry point. 91![Chain skipping layers](chain_skipping_layers.png) 92 93Application interface to loader 94------------------------------- 95 96In this section we’ll 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 110The loader library on Windows, Linux and Android will export all core Vulkan 111and all appropriate Window System Interface (WSI) extensions. This is done to 112make it simpler to get started with Vulkan development. When an application 113links directly to the loader library in this way, the Vulkan calls are simple 114trampoline functions that jump to the appropriate dispatch table entry for the 115object they are given. 116 117Applications are not required to link directly to the loader library, instead 118they can use the appropriate platform specific dynamic symbol lookup on the 119loader library to initialize the application’s own dispatch table. This allows 120an application to fail gracefully if the loader cannot be found, and it 121provides the fastest mechanism for the application to call Vulkan functions. An 122application will only need to query (via system calls such as dlsym()) the 123address of vkGetInstanceProcAddr from the loader library. Using 124vkGetInstanceProcAddr the application can then discover the address of all 125instance and global functions and extensions, such as vkCreateInstance, 126vkEnumerateInstanceExtensionProperties and vkEnumerateInstanceLayerProperties 127in a platform independent way. 128 129The Vulkan loader library will be distributed in various ways including Vulkan 130SDKs, OS package distributions and IHV driver packages. These details are 131beyond the scope of this document. However, the name and versioning of the 132Vulkan loader library is specified so an app can link to the correct Vulkan ABI 133library version. Vulkan versioning is such that ABI backwards compatibility is 134guaranteed for all versions with the same major number (e.g. 1.0 and 1.1). On 135Windows, the loader library encodes the ABI version in its name such that 136multiple ABI incompatible versions of the loader can peacefully coexist on a 137given system. The Vulkan loader library file name is “vulkan-<ABI 138version>.dll”. For example, for Vulkan version 1.X on Windows the library 139filename is vulkan-1.dll. And this library file can typically be found in the 140windows/system32 directory. 141 142For Linux, shared libraries are versioned based on a suffix. Thus, the ABI 143number is not encoded in the base of the library filename as on Windows. On 144Linux an application wanting to link to the latest Vulkan ABI version would 145just link to the name vulkan (libvulkan.so). A specific Vulkan ABI version can 146also be linked to by applications (e.g. libvulkan.so.1). 147 148Applications desiring Vulkan functionality beyond what the core API offers may 149use various layers or extensions. A layer cannot add new or modify existing 150Vulkan commands, but may offer extensions that do. A common use of layers is 151for API validation. A developer can use validation layers during application 152development, but during production the layers can be disabled by the 153application. Thus, eliminating the overhead of validating the application's 154usage of the API. Layers discovered by the loader can be reported to the 155application via vkEnumerateInstanceLayerProperties and 156vkEnumerateDeviceLayerProperties, for instance and device layers respectively. 157Instance layers are enabled at vkCreateInstance; device layers are enabled at 158vkCreateDevice. For example, the ppEnabledLayerNames array in the 159VkDeviceCreateInfo structure is used by the application to list the device 160layer names to be enabled at vkCreateDevice. At vkCreateInstance and 161vkCreateDevice, the loader will construct call chains that include the 162application specified (enabled) layers. Order is important in the 163ppEnabledLayerNames array; array element 0 is the topmost (closest to the 164application) layer inserted in the chain and the last array element is closest 165to the driver. 166 167Developers may want to enable layers that are not enabled by the given 168application they are using. On Linux and Windows, the environment variables 169“VK\_INSTANCE\_LAYERS” and “VK\_DEVICE\_LAYERS” can be used to enable 170additional layers which are not specified (enabled) by the application at 171vkCreateInstance/vkCreateDevice. VK\_INSTANCE\_LAYERS is a colon 172(Linux)/semi-colon (Windows) separated list of layer names to enable. Order is 173relevant with the first layer in the list being the topmost layer (closest to 174the application) and the last layer in the list being the bottommost layer 175(closest to the driver). 176 177Application specified layers and user specified layers (via environment 178variables) are aggregated and duplicates removed by the loader when enabling 179layers. Layers specified via environment variable are topmost (closest to the 180application) while layers specified by the application are bottommost. 181 182An example of using these environment variables to activate the validation 183layer 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 193instance and device chains to function properly. This is required for “global” 194layers regardless of which method is used to enable the layer (application or 195environment variable). 196 197Some platforms, including Linux and Windows, support layers which are enabled 198automatically by the loader rather than explicitly by the application (or via 199environment variable). Explicit layers are those layers enabled by the 200application (or environment variable) by providing the layer name. Implicit 201layers are those layers enabled by the loader automatically. Any implicit 202layers the loader discovers on the system in the appropriate location will be 203enabled (subject to environment variable overrides described later). Discovery 204of properly installed implicit and explicit layers is described later. 205Explicitly enabling a layer that is implicitly enabled has no additional 206effect: the layer will still be enabled implicitly by the loader. 207 208Extensions are optional functionality provided by a layer, the loader or an 209ICD. Extensions can modify the behavior of the Vulkan API and need to be 210specified and registered with Khronos. 211 212Instance extensions can be discovered via 213vkEnumerateInstanceExtensionProperties. Device extensions can be discovered via 214vkEnumerateDeviceExtensionProperties. The loader discovers and aggregates all 215extensions from layers (both explicit and implicit), ICDs and the loader before 216reporting them to the application in vkEnumerate\*ExtensionProperties. The 217pLayerName parameter in these functions is used to select either a single layer 218or the Vulkan platform implementation. If pLayerName is NULL, extensions from 219Vulkan implementation components (including loader, implicit layers, and ICDs) 220are enumerated. If pLayerName is equal to a discovered layer module name then 221any extensions from that layer (which may be implicit or explicit) are 222enumerated. Duplicate extensions (e.g. an implicit layer and ICD might report 223support for the same extension) are eliminated by the loader. For duplicates, the 224ICD version is reported and the layer version is culled. Extensions must 225be enabled (in vkCreateInstance or vkCreateDevice) before they can be used. 226 227Extension command entry points should be queried via vkGetInstanceProcAddr or 228vkGetDeviceProcAddr. vkGetDeviceProcAddr can only be used to query for device 229extension or core device entry points. Device entry points include any command 230that uses a VkDevice as the first parameter or a dispatchable object that is a 231child of a VkDevice (currently this includes VkQueue and VkCommandBuffer). 232vkGetInstanceProcAddr can be used to query either device or instance extension 233entry points in addition to all core entry points. 234 235VkGetDeviceProcAddr is particularly interesting because it will provide the 236most efficient way to call into the ICD. For example, the diagram below shows 237what could happen if the application were to use vkGetDeviceProcAddr for the 238function “vkGetDeviceQueue” and “vkDestroyDevice” but not “vkAllocateMemory”. 239The resulting function pointer (fpGetDeviceQueue) would be the ICD’s entry 240point if the loader and any enabled layers do not need to see that call. Even 241if an enabled layer intercepts the call (e.g. vkDestroyDevice) the loader 242trampoline code is skipped for function pointers obtained via 243vkGetDeviceProcAddr. This also means that function pointers obtained via 244vkGetDeviceProcAddr will only work with the specific VkDevice it was created 245for, using it with another device has undefined results. For extensions, 246Get\*ProcAddr will often be the only way to access extension API features. 247 248![Get*ProcAddr efficiency](get_proc_addr.png) 249 250 251Vulkan Installable Client Driver interface with the loader 252---------------------------------------------------------- 253 254### ICD discovery 255 256Vulkan allows multiple drivers each with one or more devices (represented by a 257Vulkan VkPhysicalDevice object) to be used collectively. The loader is 258responsible for discovering available Vulkan ICDs on the system. Given a list 259of available ICDs, the loader can enumerate all the physical devices available 260for an application and return this information to the application. The process 261in which the loader discovers the available Installable Client Drivers (ICDs) 262on a system is platform dependent. Windows, Linux and Android ICD discovery 263details are listed below. 264 265#### Windows 266 267##### Properly-Installed ICDs 268 269In order to find properly-installed ICDs, the Vulkan loader will scan the 270values in the following Windows registry key: 271 272HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers 273 274For each value in this key which has DWORD data set to 0, the loader opens the 275JSON format text information file (a.k.a. "manifest file") specified by the 276name of the value. Each name must be a full pathname to the text manifest file. 277The Vulkan loader will open each manifest file to obtain the name or pathname 278of 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 291The "library\_path" specifies either a filename, a relative pathname, or a full 292pathname to an ICD shared library file, which the loader will attempt to load 293using LoadLibrary(). If the ICD is specified via a filename, the shared library 294lives in the system's DLL search path (e.g. in the "C:\\\\Windows\\\\System32" 295folder). If the ICD is specified via a relative pathname, it is relative to the 296path of the manifest file. Relative pathnames are those that do not start with 297a drive specifier (e.g. "C:"), nor with a directory separator (i.e. the '\\' 298character), but do contain at least one directory separator. 299 300The "file\_format\_version" specifies a major.minor.patch version number in 301case the format of the text information file changes in the future. If the same 302ICD shared library supports multiple, incompatible versions of text manifest 303file format versions, it must have multiple text info files (all of which may 304point to the same shared library). 305 306The “api\_version” specifies the major.minor.patch version number of the Vulkan 307API that the shared library (referenced by "library\_path") was built with. 308 309There are no rules about the name of the text information files (except the 310.json suffix). 311 312There are no rules about the name of the ICD shared library files. For example, 313if 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``` 324then the loader will open the following text information files, with the 325specified 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 333Then the loader will open the three files mentioned in the "Text File Contents" 334column, and then try to load and use the three shared libraries indicated by 335the ICD.library\_path value. 336 337##### Using Pre-Production ICDs 338 339IHV developers (and sometimes other developers) need to use special, 340pre-production ICDs. In some cases, a pre-production ICD may be in an 341installable package. In other cases, a pre-production ICD may simply be a 342shared library in the developer's build tree. In this latter case, we want to 343allow developers to point to such an ICD without modifying the 344properly-installed ICD(s) on their system. 345 346This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, 347which will override the mechanism used for finding properly-installed ICDs. In 348other 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 350text information files (aka manifest files), containing the following: 351 352- A full pathname (e.g. "C:\\my\_build\\my\_icd.json") 353 354Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info 355file for a developer-built ICD. A semi-colon is only used if more than one ICD 356is listed. 357 358For example, if a developer wants to refer to one ICD that they built, they 359could set the "VK\_ICD\_FILENAMES" environment variable to: 360 361C:\\my\_build\\my\_icd.json 362 363If a developer wants to refer to two ICDs, one of which is a properly-installed 364ICD, they can use the full pathname of the text file: 365 366C:\\Windows\\System32\\vendorc\_icd.json;C:\\my\_build\\my\_icd.json 367 368Notice 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 375In order to find properly-installed ICDs, the Vulkan loader will scan the files 376in the following Linux directories: 377 378/usr/share/vulkan/icd.d 379/etc/vulkan/icd.d 380$HOME/.local/share/vulkan/icd.d 381 382Where $HOME is the current home directory of the application's user id; this 383path will be ignored for suid programs. 384 385These directories will contain text information files (a.k.a. "manifest 386files"), that use a JSON format. 387 388The Vulkan loader will open each manifest file found to obtain the name or 389pathname 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``` 400The "library\_path" specifies either a filename, a relative pathname, or a full 401pathname to an ICD shared library file. If the ICD is specified via a filename, 402the loader will attempt to open that file as a shared object using dlopen(), 403and the file must be in a directory that dlopen is configured to look in (Note: 404various distributions are configured differently). A distribution is free to 405create Vulkan-specific system directories (e.g. ".../vulkan/icd"), but is not 406required to do so. If the ICD is specified via a relative pathname, it is 407relative to the path of the info file. Relative pathnames are those that do not 408start with, but do contain at least one directory separator (i.e. the '/' 409character). For example, "lib/vendora.so" and "./vendora.so" are examples of 410relative pathnames. 411 412The "file\_format\_version" provides a major.minor.patch version number in case 413the format of the manifest file changes in the future. If the same ICD shared 414library supports multiple, incompatible versions of manifest file format 415versions, it must have multiple manifest files (all of which may point to the 416same shared library). 417 418The “api\_version” specifies the major.minor.patch version number of the Vulkan 419API that the shared library (referenced by "library\_path") was built with. 420 421The "/usr/share/vulkan/icd.d" directory is for ICDs that are installed from 422Linux-distribution-provided packages. The "/etc/vulkan/icd.d" directory is for 423ICDs that are installed from non-Linux-distribution-provided packages. 424 425There are no rules about the name of the text files (except the .json suffix). 426 427There are no rules about the name of the ICD shared library files. For example, 428if the "/usr/share/vulkan/icd.d" directory contain the following files, with 429the 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 437then the loader will open the three files mentioned in the "Text File Contents" 438column, and then try to load and use the three shared libraries indicated by 439the ICD.library\_path value. 440 441##### Using Pre-Production ICDs 442 443IHV developers (and sometimes other developers) need to use special, 444pre-production ICDs. In some cases, a pre-production ICD may be in an 445installable package. In other cases, a pre-production ICD may simply be a 446shared library in the developer's build tree. In this latter case, we want to 447allow developers to point to such an ICD without modifying the 448properly-installed ICD(s) on their system. 449 450This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, 451which will override the mechanism used for finding properly-installed ICDs. In 452other words, only the ICDs listed in "VK\_ICD\_FILENAMES" will be used. 453 454The "VK\_ICD\_FILENAMES" environment variable is a colon-separated list of ICD 455manifest 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 461Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info 462file for a developer-built ICD. A colon is only used if more than one ICD is 463listed. 464 465For example, if a developer wants to refer to one ICD that they built, they 466could set the "VK\_ICD\_FILENAMES" environment variable to: 467 468/my\_build/my\_icd.json 469 470If a developer wants to refer to two ICDs, one of which is a properly-installed 471ICD, they can use the name of the text file in the system directory: 472 473vendorc\_vulkan.json:/my\_build/my\_icd.json 474 475Notice the colon between "vendorc\_vulkan.json" and "/my\_build/my\_icd.json". 476 477NOTE: this environment variable will be ignored for suid programs. 478 479#### Android 480 481The Android loader lives in the system library folder. The location cannot be 482changed. The loader will load the driver/ICD via hw_get_module with the ID 483of "vulkan". Due to security policies in Android none of this can be modified 484under normal use. 485 486 487ICD interface requirements 488---------------------------------------- 489 490Generally, for all Vulkan commands issued by an application, the loader can be 491viewed as a pass through. That is, the loader generally doesn’t modified the 492commands or their parameters but simply calls the ICDs entry point for that 493command. Thus, the loader to ICD interface requirements will be specified by 494covering two areas: 1) Obtaining ICD Vulkan entry points; 2) Specifying 495requirements for a given Vulkan command(s) over and above the Vulkan 496specification requirements. 497 498#### Windows and Linux 499 500##### Obtaining ICD entry points 501 502Currently, two methods of the loader finding ICD entry points are supported on 503Linux and Windows: 504 5051) 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 5352) 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 546Normally, ICDs handle object creation and destruction for various Vulkan 547objects. The WSI surface extensions for Linux and Windows 548(VK\_KHR\_win32\_surface, VK\_KHR\_xcb\_surface, VK\_KHR\_xlib\_surface, 549VK\_KHR\_mir\_surface, VK\_KHR\_wayland\_surface, and VK\_KHR\_surface) are 550handled differently. For these extensions, the VkSurfaceKHR object creation and 551destruction is handled by the loader as follows: 552 5531. Loader handles the vkCreate\*SurfaceKHR() and vkDestroySurfaceKHR() 554 functions including creating/destroying the VkSurfaceKHR object. 555 5562. VkSurfaceKHR objects have the underlying structure (VkIcdSurface\*) as 557 defined in include/vulkan/vk\_icd.h. 558 5593. ICDs can cast any VkSurfaceKHR object to a pointer to the appropriate 560 VkIcdSurface\* structure. 561 5624. 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 567As previously covered, the loader requires dispatch tables to be accessible 568within Vulkan dispatchable objects, which include VkInstance, VkPhysicalDevice, 569VkDevice, VkQueue, and VkCommandBuffer. The specific requirements on all 570dispatchable 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 5771. The ICD must return a pointer for the opaque dispatchable object handle. 578 5792. 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 5853. 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 592union _VK_LOADER_DATA { 593 uintptr loadermagic; 594 void *loaderData; 595} VK_LOADER_DATA; 596 597vkObj 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 609Additional Notes: 610 611- The loader will filter out extensions requested in vkCreateInstance and 612vkCreateDevice before calling into the ICD; Filtering will be of extensions 613advertised by entities (e.g. layers) different from the ICD in question. 614- The loader will not call the ICD for vkEnumerate\*LayerProperties() as layer 615properties 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 617appropriate 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 623The Android loader uses the same protocol for initializing the dispatch 624table as described above. The only difference is that the Android 625loader queries layer and extension information directly from the 626respective libraries and does not use the json manifest files used 627by the Windows and Linux loaders. 628 629Vulkan layer interface with the loader 630-------------------------------------- 631 632### Layer discovery 633 634#### Windows 635 636##### Properly-Installed Layers 637 638In order to find properly-installed layers, the Vulkan loader will use a 639similar mechanism as used for ICDs. Text information files (aka manifest 640files), that use a JSON format, are read in order to identify the names and 641attributes of layers and their extensions. The use of manifest files allows the 642loader to avoid loading any shared library files when the application does not 643query nor request any extensions. Layers and extensions have additional 644complexity, and so their manifest files contain more information than ICD info 645files. For example, a layer shared library file may contain multiple 646layers/extensions (perhaps even an ICD). 647 648In order to find properly-installed layers, the Vulkan loader will scan the 649values in the following Windows registry keys: 650 651HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers 652 653HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers 654 655Explicit layers are those which are enabled by an application (e.g. with the 656vkCreateInstance function), or by an environment variable (as mentioned 657previously). 658 659Implicit layers are those which are enabled by their existence. For example, 660certain application environments (e.g. Steam or an automotive infotainment 661system) may have layers which they always want enabled for all applications 662that they start. Other implicit layers may be for all applications started on a 663given system (e.g. layers that overlay frames-per-second). Implicit layers are 664enabled automatically, whereas explicit layers must be enabled explicitly. What 665distinguishes a layer as implicit or explicit is by which registry key its 666layer information file is referenced by. 667 668For each value in these keys which has DWORD data set to 0, the loader opens 669the JSON manifest file specified by the name of the value. Each name must be a 670full pathname to the manifest file. 671 672The Vulkan loader will open each info file to obtain information about the 673layer, including the name or pathname of a shared library (".dll") file. 674 675This manifest file is in the JSON format and contains the following 676information: 677 678- (required) "file\_format\_version" - same as for ICDs, except that the format 679version 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. 684Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate on 685both device and instance chains. 686 687- (required) "library\_path" - filename / full path / relative path to the 688library file 689 690- (required) "api\_version" - same as for ICDs. 691 692- (required) "implementation\_version" - layer version, a single number 693increasing with backward compatible changes. 694 695- (required) "description" - informative description of the layer. 696 697- (optional) "device\_extensions" or "instance\_extensions" - array of 698extension information as follows 699 700 - (required) extension "name" - Vulkan registered name 701 702 - (required) extension "spec\_version" - extension specification version, a 703single 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 707extensions 708 709- (sometimes required) "functions" - mapping list of function entry points. If 710multiple layers exist within the same shared library (or if a layer is in the 711same shared library as an ICD), this must be specified to allow each layer to 712have its own vkGet\*ProcAddr entry points that can be found by the loader. At 713this 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) - 720environment variable and value required to enable an implicit layer. This 721environment 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 723layer is not loaded. This is for application environments (e.g. Steam) which 724want to enable a layer(s) only for applications that they launch, and allows 725for applications run outside of an application environment to not get that 726implicit layer(s). 727 728- (required for implicit layers) "disable\_environment" requirement(s) - 729environment variable and value required to disable an implicit layer. Note: in 730rare cases of an application not working with an implicit layer, the 731application can set this environment variable (before calling Vulkan functions) 732in order to "blacklist" the layer. This environment variable (which should vary 733with 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 737For 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 777The "library\_path" specifies either a filename, a relative pathname, or a full 778pathname to a layer shared library (".dll") file, which the loader will attempt 779to load using LoadLibrary(). If the layer is specified via a relative pathname, 780it is relative to the path of the info file (e.g. for cases when an application 781provides a layer that is in the same folder hierarchy as the rest of the 782application files). If the layer is specified via a filename, the shared 783library lives in the system's DLL search path (e.g. in the 784"C:\\Windows\\System32" folder). 785 786There are no rules about the name of the text files (except the .json suffix). 787 788There are no rules about the name of the layer shared library files. 789 790##### Using Pre-Production Layers 791 792As with ICDs, developers may need to use special, pre-production layers, 793without modifying the properly-installed layers. This need is met with the use 794of the "VK\_LAYER\_PATH" environment variable, which will override the 795mechanism using for finding properly-installed layers. Because many layers may 796exist on a system, this environment variable is a semi-colon-separated list of 797folders that contain layer info files. Only the folder listed in 798"VK\_LAYER\_PATH" will be scanned for info files. Each semi-colon-separated 799entry is: 800 801- The full pathname of a folder containing layer info files 802 803#### Linux 804 805##### Properly-Installed Layers 806 807In order to find properly-installed layers, the Vulkan loader will use a 808similar mechanism as used for ICDs. Text information files, that use a JSON 809format, are read in order to identify the names and attributes of layers and 810their extensions. The use of text info files allows the loader to avoid loading 811any shared library files when the application does not query nor request any 812extensions. Layers and extensions have additional complexity, and so their info 813files contain more information than ICD info files. For example, a layer shared 814library file may contain multiple layers/extensions (perhaps even an ICD). 815 816The 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 825Where $HOME is the current home directory of the application's user id; this 826path will be ignored for suid programs. 827 828Explicit layers are those which are enabled by an application (e.g. with the 829vkCreateInstance function), or by an environment variable (as mentioned 830previously). Implicit layers are those which are enabled by their existence. 831For example, certain application environments (e.g. Steam or an automotive 832infotainment system) may have layers which they always want enabled for all 833applications that they start. Other implicit layers may be for all applications 834started on a given system (e.g. layers that overlay frames-per-second). 835Implicit layers are enabled automatically, whereas explicit layers must be 836enabled explicitly. What distinguishes a layer as implicit or explicit is by 837which directory its layer information file exists in. 838 839The "/usr/share/vulkan/\*\_layer.d" directories are for layers that are 840installed from Linux-distribution-provided packages. The 841"/etc/vulkan/\*\_layer.d" directories are for layers that are installed from 842non-Linux-distribution-provided packages. 843 844The information file is in the JSON format and contains the following 845information: 846 847- (required) "file\_format\_version" – same as for ICDs, except that the format 848version 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. 853Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate on 854both device and instance chains. 855 856- (required) "library\_path" - filename / full path / relative path to the text 857file 858 859- (required) "api\_version" – same as for ICDs. 860 861- (required) "implementation\_version" – layer version, a single number 862increasing with backward compatible changes. 863 864- (required) "description" – informative description of the layer. 865 866- (optional) "device\_extensions" or "instance\_extensions" - array of 867extension information as follows 868 869 - (required) extension "name" - Vulkan registered name 870 871 - (required) extension "spec\_version" - extension specification version, a 872single 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 876extensions 877 878- (sometimes required) "functions" - mapping list of function entry points. If 879multiple layers exist within the same shared library (or if a layer is in the 880same shared library as an ICD), this must be specified to allow each layer to 881have its own vkGet\*ProcAddr entry points that can be found by the loader. At 882this time, only the following two functions are required: 883 - "vkGetInstanceProcAddr" name 884 - "vkGetDeviceProcAddr" name 885 886- (optional for implicit layers) "enable\_environment" requirement(s) - 887environment variable and value required to enable an implicit layer. This 888environment 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 890layer is not loaded. This is for application environments (e.g. Steam) which 891want to enable a layer(s) only for applications that they launch, and allows 892for applications run outside of an application environment to not get that 893implicit layer(s). 894 895- (required for implicit layers) "disable\_environment" requirement(s) - 896environment variable and value required to disable an implicit layer. Note: in 897rare cases of an application not working with an implicit layer, the 898application can set this environment variable (before calling Vulkan functions) 899in order to "blacklist" the layer. This environment variable (which should vary 900with 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 904For 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``` 942The "library\_path" specifies either a filename, a relative pathname, or a full 943pathname to a layer shared library (".so") file, which the loader will attempt 944to load using dlopen(). If the layer is specified via a filename, the loader 945will attempt to open that file as a shared object using dlopen(), and the file 946must be in a directory that dlopen is configured to look in (Note: various 947distributions are configured differently). A distribution is free to create 948Vulkan-specific system directories (e.g. ".../vulkan/layers"), but is not 949required to do so. If the layer is specified via a relative pathname, it is 950relative to the path of the info file (e.g. for cases when an application 951provides a layer that is in the same directory hierarchy as the rest of the 952application files). 953 954There are no rules about the name of the text files (except the .json suffix). 955 956There are no rules about the name of the layer shared library files. 957 958##### Using Pre-Production Layers 959 960As with ICDs, developers may need to use special, pre-production layers, 961without modifying the properly-installed layers. This need is met with the use 962of the "VK\_LAYER\_PATH" environment variable, which will override the 963mechanism using for finding properly-installed layers. Because many layers may 964exist on a system, this environment variable is a colon-separated list of 965directories that contain layer info files. Only the directories listed in 966"VK\_LAYER\_PATH" will be scanned for info files. Each colon-separated entry 967is: 968 969- The full pathname of a directory containing layer info files 970 971NOTE: these environment variables will be ignored for suid programs. 972 973#### Android 974 975The recommended way to enable layers is for applications 976to programatically enable them. The layers are provided by the application 977and must live in the application's library folder. The application 978enables the layers at vkCreateInstance and vkCreateDevice as any Vulkan 979application would. 980An application enabled for debug has more options. It can enumerate and enable 981layers located in /data/local/vulkan/debug. 982 983Layer interface requirements 984------------------------------------------------------ 985 986#### Architectural interface overview 987 988There are two key architectural features that drive the loader to layer library 989interface: 1) separate and distinct instance and device call chains, and 2) 990distributed dispatch. First these architectural features will be described and 991then the detailed interface will be specified. 992 993Call chains are the links of calls for a given Vulkan command from layer module 994to layer module with the loader and or the ICD being the bottom most command. 995Call chains are constructed at both the instance level and the device level by 996the loader with cooperation from the layer libraries. Instance call chains are 997constructed by the loader when layers are enabled at vkCreateInstance. Device 998call chains are constructed by the loader when layers are enabled at 999CreateDevice. A layer can intercept Vulkan instance commands, device commands 1000or both. For a layer to intercept instance commands, it must participate in the 1001instance call chain. For a layer to intercept device commands, it must 1002participate in the device chain. Layers which participate in intercepting calls 1003in both the instance and device chains are called global layers. 1004 1005Normally, when a layer intercepts a given Vulkan command, it will call down the 1006instance or device chain as needed. The loader and all layer libraries that 1007participate in a call chain cooperate to ensure the correct sequencing of calls 1008from one entity to the next. This group effort for call chain sequencing is 1009hereinafter referred to as distributed dispatch. In distributed dispatch, since 1010each layer is responsible for properly calling the next entity in the device or 1011instance chain, a dispatch mechanism is required for all Vulkan commands a 1012layer intercepts. For Vulkan commands that are not intercepted by a layer, or 1013if the layer chooses to terminate a given Vulkan command by not calling down 1014the chain, then no dispatch mechanism is needed for that particular Vulkan 1015command. Only for those Vulkan commands, which may be a subset of all Vulkan 1016commands, that a layer intercepts is a dispatching mechanism by the layer 1017needed. The loader is responsible for dispatching all core and instance 1018extension Vulkan commands to the first entity in the chain. 1019 1020Instance level Vulkan commands are those that have the dispatchable objects 1021VkInstance, or VkPhysicalDevice as the first parameter and also includes 1022vkCreateInstance. 1023 1024Device level Vulkan commands are those that use VkDevice, VkQueue or 1025VkCommandBuffer as the first parameter and also include vkCreateDevice. Future 1026extensions may introduce new instance or device level dispatchable objects, so 1027the above lists may be extended in the future. 1028 1029#### Discovery of layer entry points 1030 1031For the layer libraries that have been discovered by the loader, their 1032intercepting entry points that will participate in a device or instance call 1033chain need to be available to the loader or whatever layer is before them in 1034the chain. Layers have the following requirements in this area. 1035- A layer intercepting instance level Vulkan commands (aka an instance level 1036layer) must implement a vkGetInstanceProcAddr type of function. 1037- This vkGetInstanceProcAddr type function must be exported by the layer 1038library. The name of this function is specified in various ways: 1) the layer 1039manifest 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) 1043must implement a vkGetDeviceProcAddr type of function. 1044- This vkGetDeviceProcAddr type function must be exported by the layer library. 1045The name of this function is specified in various ways: 1) the layer manifest 1046JSON file in the "functions", "vkGetDeviceProcAddr" node (Linux/Windows); 2) it 1047is named "vkGetDeviceProcAddr"; 3) it is "<layerName>GetDeviceProcAddr" 1048(Android). 1049- A layer's vkGetInstanceProcAddr function (regardless of its name) must return 1050the local entry points for all instance level Vulkan commands it intercepts. At 1051a minimum, this includes vkGetInstanceProcAddr and vkCreateInstance. 1052- A layer's vkGetDeviceProcAddr function (regardless of its name) must return 1053the entry points for all device level Vulkan commands it intercepts. At a 1054minimum, this includes vkGetDeviceProcAddr and vkCreateDevice. 1055- There are no requirements on the names of the intercepting functions a layer 1056implements except those listed above for vkGetInstanceProcAddr and 1057vkGetDeviceProcAddr. 1058- Currently a layer's VkGetInstanceProcAddr must be able to handle a VkInstance 1059parameter equal to NULL for 1060instance level commands it intercepts including vkCreateDevice. 1061- Currently a layer's VkGetDeviceProcAddr must be able to handle a VkDevice 1062parameter 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 1067identical to the Vulkan API for that command. 1068- Other than the two vkGet*ProcAddr, all other functions intercepted by a layer 1069need NOT be exported by the layer. 1070- For any Vulkan command a layer intercepts which has a non-void return value, 1071an appropriate value must be returned by the layer intercept function. 1072- The layer intercept function must call down the chain to the corresponding 1073Vulkan command in the next entity. Undefined results will occur if a layer 1074doesn't propagate calls down the chain. The two exceptions to this requirement 1075are vkGetInstanceProcAddr and vkGetDeviceProcAddr which only call down the 1076chain for Vulkan commands that they do not intercept. 1077- Layer intercept functions may insert extra calls to Vulkan commands in 1078addition to the intercept. For example, a layer intercepting vkQueueSubmit may 1079want to add a call to vkQueueWaitIdle after calling down the chain for 1080vkQueueSubmit. Any additional calls inserted by a layer must be on the same 1081chain. 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 1086point residing in the next entity in the chain it will call down into. In other 1087words, the layer must have a list of pointers to functions of the appropriate 1088type to call into the next entity. This can be implemented in various ways but 1089for 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 1093dispatch table (see include/vulkan/vk_layer.h). 1094- Layers vkGetInstanceProcAddr function uses the next entity's 1095vkGetInstanceProcAddr to call down the chain for unknown (i.e. non-intercepted) 1096functions. 1097- Layers vkGetDeviceProcAddr function uses the next entity's 1098vkGetDeviceProcAddr to call down the chain for unknown (i.e. non-intercepted) 1099functions. 1100 1101#### Layer dispatch initialization 1102 1103- A layer initializes its instance dispatch table within its vkCreateInstance 1104function. 1105- A layer initializes its device dispatch table within its vkCreateDevice 1106function. 1107- The loader passes a linked list of initialization structures to layers via 1108the "pNext" field in the VkInstanceCreateInfo and VkDeviceCreateInfo structures 1109for vkCreateInstance and VkCreateDevice respectively. 1110- The head node in this linked list is of type VkLayerInstanceCreateInfo for 1111instance and VkLayerDeviceCreateInfo for device. See file 1112include/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 1118within VkLayer*CreateInfo. The loader will set the "function" field to 1119VK_LAYER_LINK_INFO. This indicates "u" field should be VkLayerInstanceLink or 1120VkLayerDeviceLink. 1121- The VkLayerInstanceLink and VkLayerDeviceLink structures are the list nodes. 1122- The VkLayerInstanceLink contains the next entity's vkGetInstanceProcAddr used 1123by a layer. 1124- The VkLayerDeviceLink contains the next entity's vkGetInstanceProcAddr and 1125vkGetDeviceProcAddr used by a layer. 1126- Given the above structures set up by the loader, layer must initialize their 1127dispatch table as follows: 1128 - Find the VkLayerInstanceCreateInfo/VkLayerDeviceCreateInfo structure in 1129the 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 1140Get*ProcAddr function once for each Vulkan command needed in your dispatch 1141table 1142 1143#### Example code for CreateInstance 1144 1145```cpp 1146VkResult 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 1202VkResult 1203vkCreateDevice( 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 1255A layer may want to associate it's own private data with one or more Vulkan 1256objects. 1257Two common methods to do this are hash maps and object wrapping. The loader 1258supports layers wrapping any Vulkan object including dispatchable objects. 1259Layers which wrap objects should ensure they always unwrap objects before 1260passing them down the chain. This implies the layer must intercept every Vulkan 1261command which uses the object in question. Layers above the object wrapping 1262layer will see the wrapped object. Layers which wrap dispatchable objects must 1263ensure that the first field in the wrapping structure is a pointer to a dispatch table 1264as defined in vk_layer.h. Specifically, an instance wrapped dispatchable object 1265could be as follows: 1266``` 1267struct my_wrapped_instance_obj_ { 1268 VkLayerInstanceDispatchTable *disp; 1269 // whatever data layer wants to add to this object 1270}; 1271``` 1272A device wrapped dispatchable object could be as follows: 1273``` 1274struct my_wrapped_instance_obj_ { 1275 VkLayerDispatchTable *disp; 1276 // whatever data layer wants to add to this object 1277}; 1278``` 1279 1280Alternatively, a layer may want to use a hash map to associate data with a 1281given object. The key to the map could be the object. Alternatively, for 1282dispatchable objects at a given level (eg device or instance) the layer may 1283want data associated with the VkDevice or VkInstance objects. Since 1284there are multiple dispatchable objects for a given VkInstance or VkDevice, the 1285VkDevice or VkInstance object is not a great map key. Instead the layer should 1286use the dispatch table pointer within the VkDevice or VkInstance since that 1287will be unique for a given VkInstance or VkDevice. 1288 1289Layers which create dispatchable objects take special care. Remember that loader 1290trampoline code normally fills in the dispatch table pointer in the newly 1291created object. Thus, the layer must fill in the dispatch table pointer if the 1292loader trampoline will not do so. Common cases where a layer (or ICD) may create a 1293dispatchable 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 1297intercept from the application 1298- ICDs which add extensions that create dispatchable objects 1299 1300To fill in the dispatch table pointer in newly created dispatchable object, 1301the 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 1302device). 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