1<!-- markdownlint-disable MD041 --> 2[![Khronos Vulkan][1]][2] 3 4[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/" 5[2]: https://www.khronos.org/vulkan/ 6 7# Application Interface to Loader <!-- omit from toc --> 8[![Creative Commons][3]][4] 9 10<!-- Copyright © 2015-2023 LunarG, Inc. --> 11 12[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License" 13[4]: https://creativecommons.org/licenses/by-nd/4.0/ 14 15## Table of Contents <!-- omit from toc --> 16 17- [Overview](#overview) 18- [Interfacing with Vulkan Functions](#interfacing-with-vulkan-functions) 19 - [Vulkan Direct Exports](#vulkan-direct-exports) 20 - [Directly Linking to the Loader](#directly-linking-to-the-loader) 21 - [Dynamic Linking](#dynamic-linking) 22 - [Static Linking](#static-linking) 23 - [Indirectly Linking to the Loader](#indirectly-linking-to-the-loader) 24 - [Best Application Performance Setup](#best-application-performance-setup) 25 - [ABI Versioning](#abi-versioning) 26 - [Windows Dynamic Library Usage](#windows-dynamic-library-usage) 27 - [Linux Dynamic Library Usage](#linux-dynamic-library-usage) 28 - [MacOs Dynamic Library Usage](#macos-dynamic-library-usage) 29 - [Bundling the Loader With An Application](#bundling-the-loader-with-an-application) 30- [Application Layer Usage](#application-layer-usage) 31 - [Meta-Layers](#meta-layers) 32 - [Implicit vs Explicit Layers](#implicit-vs-explicit-layers) 33 - [Override Layer](#override-layer) 34 - [Forcing Layer Source Folders](#forcing-layer-source-folders) 35 - [Exception for Elevated Privileges](#exception-for-elevated-privileges) 36 - [Forcing Layers to be Enabled on Windows, Linux and macOS](#forcing-layers-to-be-enabled-on-windows-linux-and-macos) 37 - [Overall Layer Ordering](#overall-layer-ordering) 38 - [Debugging Possible Layer Issues](#debugging-possible-layer-issues) 39- [Application Usage of Extensions](#application-usage-of-extensions) 40 - [Instance and Device Extensions](#instance-and-device-extensions) 41 - [WSI Extensions](#wsi-extensions) 42 - [Unknown Extensions](#unknown-extensions) 43 - [Filtering Out Unknown Instance Extension Names](#filtering-out-unknown-instance-extension-names) 44- [Physical Device Ordering](#physical-device-ordering) 45 46## Overview 47 48This is the Application-centric view of working with the Vulkan loader. 49For the complete overview of all sections of the loader, please refer 50to the [LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) file. 51 52## Interfacing with Vulkan Functions 53 54There are several ways Vulkan functions may be interfaced through the loader: 55 56 57### Vulkan Direct Exports 58 59The loader library on Windows, Linux, Android, and macOS will export all core 60Vulkan entry-points and all appropriate Window System Interface (WSI) 61entry-points. 62This is done to make it simpler to get started with Vulkan development. 63When an application links directly to the loader library in this way, the 64Vulkan calls are simple *trampoline* functions that jump to the appropriate 65dispatch table entry for the object they are given. 66 67 68### Directly Linking to the Loader 69 70#### Dynamic Linking 71 72The loader is distributed as a dynamic library (.dll on Windows or .so on Linux 73or .dylib on macOS) which gets installed to the system path for dynamic 74libraries. 75Furthermore, the dynamic library is generally installed to Windows 76systems as part of driver installation and is generally provided on Linux 77through the system package manager. 78This means that applications can usually expect a copy of the loader to be 79present on a system. 80If applications want to be completely sure that a loader is present, they can 81include a loader or runtime installer with their application. 82 83#### Static Linking 84 85In previous versions of the loader, it was possible to statically link the 86loader. 87**This was removed and is no longer possible.** 88The decision to remove static linking was because of changes to the driver 89which made older applications that statically linked unable to find newer 90drivers. 91 92Additionally, static linking posed several problems: 93 - The loader can never be updated without re-linking the application 94 - The possibility that two included libraries could contain different versions 95 of the loader 96 - Could cause conflicts between the different loader versions 97 98The only exception to this is for macOS, but is not supported or tested. 99 100### Indirectly Linking to the Loader 101 102Applications are not required to link directly to the loader library, instead 103they can use the appropriate platform-specific dynamic symbol lookup on the 104loader library to initialize the application's own dispatch table. 105This allows an application to fail gracefully if the loader cannot be found. 106It also provides the fastest mechanism for the application to call Vulkan 107functions. 108An application only needs to query (via system calls such as `dlsym`) the 109address of `vkGetInstanceProcAddr` from the loader library. 110The application then uses `vkGetInstanceProcAddr` to load all functions 111available, such as `vkCreateInstance`, `vkEnumerateInstanceExtensionProperties` 112and `vkEnumerateInstanceLayerProperties` in a platform-independent way. 113 114### Best Application Performance Setup 115 116To get the best possible performance in a Vulkan application, the application 117should set up its own dispatch table for every Vulkan API entry-point. 118For every instance-level Vulkan command in the dispatch table, the function pointer 119should be queried and filled in by using the results of `vkGetInstanceProcAddr`. 120Additionally, for every device-level Vulkan command, the function pointer 121should be queried and filled in using the results of `vkGetDeviceProcAddr`. 122 123*Why do this?* 124 125The answer comes in how the call chain of instance functions are implemented 126versus the call chain of a device functions. 127Remember, a [Vulkan instance is a high-level construct used to provide Vulkan 128system-level information](LoaderInterfaceArchitecture.md#instance-specific). 129Because of this, instance functions need to be broadcast to every available 130driver on the system. 131The following diagram shows an approximate view of an instance call chain with 132three enabled layers: 133 134 135 136This is also how a Vulkan device function call chain looks if queried 137using `vkGetInstanceProcAddr`. 138On the other hand, a device function doesn't need to worry about the broadcast 139because it knows specifically which associated driver and which associated 140physical device the call should terminate at. 141Because of this, the loader doesn't need to get involved between any enabled 142layers and the driver. 143Thus, using a loader-exported Vulkan device function, the call chain 144in the same scenario as above would look like: 145 146 147 148An even better solution would be for an application to perform a 149`vkGetDeviceProcAddr` call on all device functions. 150This further optimizes the call chain by removing the loader all-together under 151most scenarios: 152 153 154 155Also, notice if no layers are enabled, the application function pointers point 156**directly to the driver**. 157With many function calls, the lack of indirection in each adds up to non-trivial 158performance savings. 159 160**NOTE:** There are some device functions which still require the loader to 161intercept them with a *trampoline* and *terminator*. 162There are very few of these, but they are typically functions which the loader 163wraps with its own data. 164In those cases, even the device call chain will continue to look like the 165instance call chain. 166One example of a device function requiring a *terminator* is 167`vkCreateSwapchainKHR`. 168For that function, the loader needs to potentially convert the KHR_surface 169object into an driver-specific KHR_surface object prior to passing down the rest 170of the function's information to the driver. 171 172Remember: 173 * `vkGetInstanceProcAddr` is used to query instance and physical device 174 functions, but can query all functions. 175 * `vkGetDeviceProcAddr` is only used to query device functions. 176 177 178### ABI Versioning 179 180The Vulkan loader library will be distributed in various ways including Vulkan 181SDKs, OS package distributions and Independent Hardware Vendor (IHV) driver 182packages. 183These details are beyond the scope of this document. 184However, the name and versioning of the Vulkan loader library is specified so 185an app can link to the correct Vulkan ABI library version. 186ABI backwards compatibility is guaranteed for all versions with the same major 187number (e.g. 1.0 and 1.1). 188 189#### Windows Dynamic Library Usage 190 191On Windows, the loader library encodes the ABI version in its name such that 192multiple ABI incompatible versions of the loader can peacefully coexist on a 193given system. 194The Vulkan loader library file name is `vulkan-<ABI version>.dll`. 195For example, for Vulkan version 1.X on Windows the library filename is 196`vulkan-1.dll`. 197This library file can typically be found in the `windows\system32` 198directory (on 64-bit Windows installs, the 32-bit version of the loader with 199the same name can be found in the `windows\sysWOW64` directory). 200 201#### Linux Dynamic Library Usage 202 203For Linux, shared libraries are versioned based on a suffix. 204Thus, the ABI number is not encoded in the base of the library filename as on 205Windows. 206 207On Linux, applications that have a hard dependency on Vulkan should request 208linking to the unversioned name `libvulkan.so` in their build system. 209For example by importing the CMake target `Vulkan::Vulkan` or by using the 210output of `pkg-config --cflags --libs vulkan` as compiler flags. 211As usual for Linux libraries, the compiler and linker will resolve this to 212a dependency on the correct versioned SONAME, currently `libvulkan.so.1`. 213Linux applications that load Vulkan-Loader dynamically at runtime do not 214benefit from this mechanism, and should instead make sure to pass the 215versioned name such as `libvulkan.so.1` to `dlopen()`, to ensure that they 216load a compatible version. 217 218#### MacOs Dynamic Library Usage 219 220MacOs linking is similar to Linux, with the exception being that the standard 221dynamic library is named `libvulkan.dylib` and the ABI versioned library is 222currently named `libvulkan.1.dylib`. 223 224 225### Bundling the Loader With An Application 226 227The Khronos loader is typically installed on platforms either in a 228platform-specific way (i.e. packages on Linux) or as part of a driver install 229(i.e. using the Vulkan Runtime installer on Windows). 230Applications or engines may desire to install the Vulkan loader locally to their 231execution tree as part of their own installation process. 232This may be because providing the specific loader: 233 234 1) Guarantees certain Vulkan API exports are available in the loader 235 2) Ensures certain loader behavior is well-known 236 3) Provides consistency across user installation 237 238However, this is **strongly discouraged** because: 239 240 1) The packaged loader may not be compatible with future driver revisions 241(this can be especially true on Windows where driver install locations can 242change during updates to the OS) 243 2) It can prevent the application/engine from taking advantage of new Vulkan 244API version/extension exports 245 3) The application/engine will miss out on important loader bug-fixes 246 4) The packaged loader will not contain useful feature updates (like 247improved loader debugability) 248 249Of course, even if an application/engine does initially release with a specific 250version of the Khronos loader, it may chose to update or remove that loader at 251some point in the future. 252This could be due to the exposure of needed functionality in the loader as time 253progresses. 254But, that relies upon end-users correctly performing whatever update process is 255necessary at that future time which may result in different behavior across 256different user's systems. 257 258One better alternative, at least on Windows, is to package the Vulkan Runtime 259installer for the desired version of the Vulkan loader with your product. 260Then, the installation process can use that to ensure the end-user's system 261is up to date. 262The Runtime installer will detect the version already installed and will only 263install a newer runtime if necessary. 264 265Another alternative is to write the application so it can fallback to earlier 266versions of Vulkan yet display a warning indicating functionality is disabled 267until the user updates their system to a specific runtime/driver. 268 269 270## Application Layer Usage 271 272Applications desiring Vulkan functionality beyond what Vulkan drivers 273on their system already expose, may use various layers to augment the API. 274A layer cannot add new Vulkan core API entry-points that are not exposed in 275Vulkan.h. 276However, layers may offer implementations of extensions that introduce 277additional entry-points beyond what is available without those layers. 278These additional extension entry-points can be queried through the Vulkan 279extension interface. 280 281A common use of layers is for API validation which can be enabled during 282application development and left out when releasing the application. 283This allows easy control of the overhead resulting from enabling validation of 284the application's usage of the API, which wasn't always possible in previous 285graphics APIs. 286 287To find out what layers are available to an application, use 288`vkEnumerateInstanceLayerProperties`. 289This will report all layers that have been discovered by the loader. 290The loader looks in various locations to find layers on the system. 291For more information see the 292[Layer discovery](LoaderLayerInterface.md#layer-discovery) 293section in the 294[LoaderLayerInterface.md document](LoaderLayerInterface.md) document. 295 296To enable specific layers, simply pass the names of the layers to 297enable in the `ppEnabledLayerNames` field of the `VkInstanceCreateInfo` during 298a call to `vkCreateInstance`. 299Once done, the layers that have been enabled will be active for all Vulkan functions 300using the created `VkInstance`, and any of its child objects. 301 302**NOTE:** Layer ordering is important in several cases since some layers 303interact with each other. 304Be careful when enabling layers as this may be the case. 305See the [Overall Layer Ordering](#overall-layer-ordering) section for more 306information. 307 308The following code section shows how to go about enabling the 309`VK_LAYER_KHRONOS_validation` layer. 310 311``` 312char *instance_layers[] = { 313 "VK_LAYER_KHRONOS_validation" 314}; 315const VkApplicationInfo app = { 316 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 317 .pNext = NULL, 318 .pApplicationName = "TEST_APP", 319 .applicationVersion = 0, 320 .pEngineName = "TEST_ENGINE", 321 .engineVersion = 0, 322 .apiVersion = VK_API_VERSION_1_0, 323}; 324VkInstanceCreateInfo inst_info = { 325 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 326 .pNext = NULL, 327 .pApplicationInfo = &app, 328 .enabledLayerCount = 1, 329 .ppEnabledLayerNames = (const char *const *)instance_layers, 330 .enabledExtensionCount = 0, 331 .ppEnabledExtensionNames = NULL, 332}; 333err = vkCreateInstance(&inst_info, NULL, &demo->inst); 334if (VK_ERROR_LAYER_NOT_PRESENT == err) { 335 // Couldn't find the validation layer 336} 337``` 338 339At `vkCreateInstance` and `vkCreateDevice`, the loader constructs call chains 340that include the application specified (enabled) layers. 341Order is important in the `ppEnabledLayerNames` array; array element 0 is the 342topmost (closest to the application) layer inserted in the chain and the last 343array element is closest to the driver. 344See the [Overall Layer Ordering](#overall-layer-ordering) section for more 345information on layer ordering. 346 347**NOTE:** *Device Layers Are Now Deprecated* 348> `vkCreateDevice` originally was able to select layers in a similar manner to 349`vkCreateInstance`. 350> This led to the concept of "instance layers" and "device layers". 351> It was decided by Khronos to deprecate the "device layer" functionality and 352> only consider "instance layers". 353> Therefore, `vkCreateDevice` will use the layers specified at 354`vkCreateInstance`. 355> Because of this, the following items have been deprecated: 356> * `VkDeviceCreateInfo` fields: 357> * `ppEnabledLayerNames` 358> * `enabledLayerCount` 359> * The `vkEnumerateDeviceLayerProperties` function 360 361 362### Meta-Layers 363 364Meta-layers are layers which contain an ordered list of other layers to enable. 365This is to allow grouping layers together in a specified order so that they can 366interact properly. 367Originally, this was used to group together the individual Vulkan Validation 368layers in the proper order to avoid conflicts. 369It was necessary because instead of a single Validation layer, validation was 370split into multiple component layers. 371The new `VK_LAYER_KHRONOS_validation` layer pulled everything into a single 372layer, dropping the need for meta layers. 373While not necessary for validation anymore, VkConfig does use meta layers to 374group layers together based on user's preferences. 375More can be found out about this functionality through both the 376[VkConfig documentation](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md) 377and the section later on the [Override Layer](#override-layer). 378 379Meta-layers are detailed more in the 380[Meta-Layers](LoaderLayerInterface.md#meta-layers) section of the 381[LoaderLayerInterface.md](LoaderLayerInterface.md) file in this folder. 382 383 384### Implicit vs Explicit Layers 385 386 387 388Explicit layers are layers which are enabled by an application (e.g. with the 389vkCreateInstance function as mentioned previously). 390 391Implicit layers are enabled automatically by their very existence, unless 392requiring an additional manual enable step, unlike explicit layers that must be 393enabled explicitly. 394For example, certain application environments (e.g. Steam or an automotive 395infotainment system) may have layers which they always want enabled for all 396applications that they start. 397Other implicit layers may be for all applications started on a given system 398(e.g. layers that overlay frames-per-second). 399 400Implicit layers have an additional requirement over explicit layers in that 401they require being able to be disabled by an environmental variable. 402This is due to the fact that they are not visible to the application and could 403cause issues. 404A good principle to keep in mind would be to define both an enable and disable 405environment variable so the users can deterministically enable the 406functionality. 407On Desktop platforms (Windows, Linux, and macOS), these enable/disable settings 408are defined in the layer's JSON file. 409 410Discovery of system-installed implicit and explicit layers is described later 411in the [Layer discovery](LoaderLayerInterface.md#layer-discovery) 412section in the 413[LoaderLayerInterface.md](LoaderLayerInterface.md) document. 414 415Implicit and explicit layers may be found in different locations based on the 416underlying operating system. 417The table below details more information: 418 419<table style="width:100%"> 420 <tr> 421 <th>Operating System</th> 422 <th>Implicit Layer Identification</th> 423 </tr> 424 <tr> 425 <td>Windows</td> 426 <td>Implicit layers are located in a different Windows registry location 427 than explicit layers.</td> 428 </tr> 429 <tr> 430 <td>Linux</td> 431 <td>Implicit layers are located in a different directory location than 432 explicit layers.</td> 433 </tr> 434 <tr> 435 <td>Android</td> 436 <td>There is **No Support For Implicit Layers** on Android.</td> 437 </tr> 438 <tr> 439 <td>macOS</td> 440 <td>Implicit layers are located in a different directory location than 441 explicit layers.</td> 442 </tr> 443</table> 444 445 446#### Override Layer 447 448The "Override Layer" is a special implicit meta-layer created by the 449[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md) 450tool and available by default when the tool is running. 451Once VkConfig exits, the override layer is removed, and the system should 452return to standard Vulkan behavior. 453Whenever the override layer is present in the layer search path, the loader will 454pull it into the layer call stack with the standard implicit layers along with 455all layers contained in the list of layers to load. 456This allows an end-user or developer to easily force on any number of layers 457and settings via VkConfig. 458 459The override layer is discussed more in the 460[Override Meta-Layer](LoaderLayerInterface.md#override-meta-layer) section of the 461[LoaderLayerInterface.md](LoaderLayerInterface.md) file in this folder. 462 463 464### Forcing Layer Source Folders 465 466Developers may need to use special, pre-production layers, without modifying 467the system-installed layers. 468 469This can be accomplished in one of two ways: 470 471 1. Selecting specific layer paths using the 472[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md) 473tool shipped with the Vulkan SDK. 474 2. Directing the loader to look for layers in specific files and/or folders by using the 475`VK_LAYER_PATH` and/or `VK_IMPLICIT_LAYER_PATH` environment variables. 476 477The `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` environment variables can contain multiple 478paths separated by the operating-system specific path separator. 479On Windows, this is a semicolon (`;`), while on Linux and macOS it is a colon 480(`:`). 481 482If `VK_LAYER_PATH` exists, the files and/or folders listed will be scanned for explicit 483layer manifest files. 484Implicit layer discovery is unaffected by this environment variable. 485 486If `VK_IMPLICIT_LAYER_PATH` exists, the files and/or folders listed will be scanned for 487implicit layer manifest files. 488Explicit layer discovery is unaffected by this environment variable. 489 490Each directory listed in `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` should be the full 491pathname of a folder containing layer manifest files. 492 493See the 494[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) 495in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md) 496for more details. 497 498 499#### Exception for Elevated Privileges 500 501For security reasons, `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` are ignored if running 502with elevated privileges. 503Because of this, the environment variables can only be used for applications that do not 504use elevated privileges. 505 506For more information see 507[Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats) 508in the top-level 509[LoaderInterfaceArchitecture.md][LoaderInterfaceArchitecture.md] document. 510 511 512### Forcing Layers to be Enabled on Windows, Linux and macOS 513 514Developers may want to enable layers that are not enabled by the given 515application they are using. 516 517This can be also be accomplished in one of two ways: 518 519 1. Selecting specific layers using the 520[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md) 521tool shipped with the Vulkan SDK. 522 2. Directing the loader to look for additional layers by name using the 523`VK_INSTANCE_LAYERS` environment variable. 524 525Both can be used to enable additional layers which are not specified (enabled) 526by the application at `vkCreateInstance`. 527 528The `VK_INSTANCE_LAYERS` environment variable is a list of layer names to enable 529separated by the operating-system specific path separator. 530On Windows, this is a semicolon (`;`), while on Linux and macOS it is a colon 531(`:`). 532The order of the names is relevant with the first layer name in the list being 533the top-most layer (closest to the application) and the last layer name in the 534list being the bottom-most layer (closest to the driver). 535See the [Overall Layer Ordering](#overall-layer-ordering) section for more 536information. 537 538Application specified layers and user specified layers (via environment 539variables) are aggregated and duplicates removed by the loader when enabling 540layers. 541Layers specified via environment variable are top-most (closest to the 542application) while layers specified by the application are bottom-most. 543 544An example of using these environment variables to activate the validation 545layer `VK_LAYER_KHRONOS_validation` on Linux or macOS is as follows: 546 547``` 548> $ export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation 549``` 550 551See the 552[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) 553in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md) 554for more details. 555 556 557### Overall Layer Ordering 558 559The overall ordering of all layers by the loader based on the above looks 560as follows: 561 562 563 564Ordering may also be important internally to the list of explicit layers. 565Some layers may be dependent on other behavior being implemented before 566or after the loader calls it. 567For example: An overlay layer may want to use `VK_LAYER_KHRONOS_validation` 568to verify that the overlay layer is behaving appropriately. 569This requires putting the overlay layer closer to the application so that the 570validation layer can intercept any Vulkan API calls the overlay layer needs to 571make to function. 572 573 574### Debugging Possible Layer Issues 575 576If it is possible that a layer is causing issues, there are several things that 577can be tried which are documented in the 578[Debugging Possible Layer Issues](LoaderDebugging.md#debugging-possible-layer-issues) 579section of the [LoaderDebugging.mg](LoaderDebugging.md) document in the docs 580folder. 581 582 583## Application Usage of Extensions 584 585Extensions are optional functionality provided by a layer, the loader, or a 586driver. 587Extensions can modify the behavior of the Vulkan API and need to be specified 588and registered with Khronos. 589These extensions can be implemented by a Vulkan driver, the loader, or a layer 590to expose functionality not available in the core API. 591Information about various extensions can be found in the Vulkan Spec, and 592vulkan.h header file. 593 594 595### Instance and Device Extensions 596 597As hinted at in the 598[Instance Versus Device](LoaderInterfaceArchitecture.md#instance-versus-device) 599section of the main 600[LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) document, 601there are two types of extensions: 602 * Instance Extensions 603 * Device Extensions 604 605An instance extension modifies existing behavior or implements new behavior on 606instance-level objects, such as `VkInstance` and `VkPhysicalDevice`. 607A device extension does the same for device-level objects, such as `VkDevice`, 608`VkQueue`, and `VkCommandBuffer` as well as any children of those objects. 609 610It is **very** important to know what the type of an extension is because 611instance extensions must be enabled with `vkCreateInstance` while device 612extensions are enabled with `vkCreateDevice`. 613 614When calling `vkEnumerateInstanceExtensionProperties` and 615`vkEnumerateDeviceExtensionProperties`, the loader discovers and aggregates all 616extensions of their respective type from layers (both explicit and implicit), 617drivers, and the loader before reporting them to the application. 618 619Looking at `vulkan.h`, both functions are very similar, 620for example, the `vkEnumerateInstanceExtensionProperties` prototype looks as 621follows: 622 623``` 624VkResult 625 vkEnumerateInstanceExtensionProperties( 626 const char *pLayerName, 627 uint32_t *pPropertyCount, 628 VkExtensionProperties *pProperties); 629``` 630 631While the `vkEnumerateDeviceExtensionProperties` prototype looks like: 632 633``` 634VkResult 635 vkEnumerateDeviceExtensionProperties( 636 VkPhysicalDevice physicalDevice, 637 const char *pLayerName, 638 uint32_t *pPropertyCount, 639 VkExtensionProperties *pProperties); 640``` 641 642The "pLayerName" parameter in these functions is used to select either a single 643layer or the Vulkan platform implementation. 644If "pLayerName" is NULL, extensions from Vulkan implementation components 645(including loader, implicit layers, and drivers) are enumerated. 646If "pLayerName" is equal to a discovered layer module name then only extensions 647from that layer (which may be implicit or explicit) are enumerated. 648 649**Note:** While device layers are deprecated, the instance enabled layers are 650still present in the device call-chain. 651 652Duplicate extensions (e.g. an implicit layer and driver might report support for 653the same extension) are eliminated by the loader. 654For duplicates, the driver version is reported and the layer version is culled. 655 656Also, extensions **must be enabled** (in `vkCreateInstance` or `vkCreateDevice`) 657before the functions associated with the extensions can be used. 658If an extension function is queried using either `vkGetInstanceProcAddr` or 659`vkGetDeviceProcAddr`, but the extension has not been enabled, undefined behavior 660could result. 661The Validation layers will catch this invalid API usage. 662 663 664### WSI Extensions 665 666Khronos-approved WSI extensions are available and provide Windows System 667Integration support for various execution environments. 668It is important to understand that some WSI extensions are valid for all 669targets, but others are particular to a given execution environment (and 670loader). 671This Khronos loader (currently targeting Windows, Linux, macOS, Stadia, and 672Fuchsia) only enables and directly exports those WSI extensions that are 673appropriate to the current environment. 674For the most part, the selection is done in the loader using compile-time 675preprocessor flags. 676All versions of the Khronos loader currently expose at least the following WSI 677extension support: 678- VK_KHR_surface 679- VK_KHR_swapchain 680- VK_KHR_display 681 682In addition, each of the following OS targets for the loader support target- 683specific extensions: 684 685| Windowing System | Extensions available | 686| ---------------- | ------------------------------------------ | 687| Windows | VK_KHR_win32_surface | 688| Linux (Wayland) | VK_KHR_wayland_surface | 689| Linux (X11) | VK_KHR_xcb_surface and VK_KHR_xlib_surface | 690| macOS (MoltenVK) | VK_MVK_macos_surface | 691| QNX (Screen) | VK_QNX_screen_surface | 692 693It is important to understand that while the loader may support the various 694entry-points for these extensions, there is a handshake required to actually 695use them: 696* At least one physical device must support the extension(s) 697* The application must use such a physical device when creating a logical 698device 699* The application must request the extension(s) be enabled while creating the 700instance or logical device (this depends on whether or not the given extension 701works with an instance or a device) 702 703Only then can the WSI extension be properly used in a Vulkan program. 704 705 706### Unknown Extensions 707 708With the ability to expand Vulkan so easily, extensions will be created that 709the loader knows nothing about. 710If the extension is a device extension, the loader will pass the unknown 711entry-point down the device call chain ending with the appropriate 712driver entry-points. 713The same thing will happen if the extension is an instance extension which 714takes a physical device parameter as its first component. 715However, for all other instance extensions the loader will fail to load it. 716 717*But why doesn't the loader support unknown instance extensions?* 718<br/> 719Let's look again at the instance call chain: 720 721 722 723Notice that for a normal instance function call, the loader has to handle 724passing along the function call to the available drivers. 725If the loader has no idea of the parameters or return value of the instance 726call, it can't properly pass information along to the drivers. 727There may be ways to do this, which will be explored in the future. 728However, for now, the loader does not support instance extensions which don't 729expose entry points that take a physical device as their first parameter. 730 731Because the device call-chain does not normally pass through the loader 732*terminator*, this is not a problem for device extensions. 733Additionally, since a physical device is associated with one driver, the loader 734can use a generic *terminator* pointing to one driver. 735This is because both of these extensions terminate directly in the 736driver they are associated with. 737 738*Is this a big problem?* 739<br/> 740No! 741Most extension functionality only affects either a physical or logical device 742and not an instance. 743Thus, the overwhelming majority of extensions should be supported with direct 744loader support. 745 746### Filtering Out Unknown Instance Extension Names 747 748In some cases, a driver may support instance extensions that are not supported 749by the loader. 750For the above reasons, the loader will filter out the names of these unknown 751instance extensions when an application calls 752`vkEnumerateInstanceExtensionProperties`. 753Additionally, this behavior will cause the loader to emit an error during 754`vkCreateInstance` if the application still attempts to use one of these 755extensions. 756The intent is to protect applications so that they don't inadvertently use 757functionality which could lead to a crash. 758 759On the other hand, if the extension must be forced on, the filtering may be 760disabled by defining the `VK_LOADER_DISABLE_INST_EXT_FILTER` environment 761variable to a non-zero number. 762This will effectively disable the loader's filtering of instance extension 763names. 764 765## Physical Device Ordering 766 767Prior to the 1.3.204 loader, physical devices on Linux could be returned in an 768inconsistent order. 769To remedy this, the Vulkan loader will now sort devices once they have been 770received from the drivers (before returning the information to any enabled 771layers) in the following fashion: 772 * Sort based on device type (Discrete, Integrated, Virtual, all others) 773 * Sort internal to the types based on PCI information (Domain, Bus, Device, and 774 Function). 775 776This allows for a consistent physical device order from run to run on the same 777system, unless the actual underlying hardware changes. 778 779A new environment variable is defined to give users the ability to force a 780specific device, `VK_LOADER_DEVICE_SELECT`. 781This environment variable should be set to the desired devices hex value for 782Vendor Id and Device Id (as returned from `vkGetPhysicalDeviceProperties` in 783the `VkPhysicalDeviceProperties` structure). 784It should look like the following: 785 786``` 787set VK_LOADER_DEVICE_SELECT=0x10de:0x1f91 788``` 789 790This will force on the device with a vendor ID of "0x10de" and a device ID 791of "0x1f91". 792If that device is not found, this is simply ignored. 793 794All device selection work done in the loader can be disabled by setting the 795environment variable `VK_LOADER_DISABLE_SELECT` to a non-zero value. 796This is intended for debug purposes to narrow down any issues with the loader 797device selection mechanism, but can be used by others. 798 799[Return to the top-level LoaderInterfaceArchitecture.md file.](LoaderInterfaceArchitecture.md) 800