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` environment variable. 476 477The `VK_LAYER_PATH` environment variable can contain multiple paths separated by 478the 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. 485Each directory listed should be the full pathname of a folder containing layer 486manifest files. 487 488See the 489[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) 490in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md) 491for more details. 492 493 494#### Exception for Elevated Privileges 495 496For security reasons, `VK_LAYER_PATH` is ignored if running with elevated 497privileges. 498Because of this, `VK_LAYER_PATH` can only be used for applications that do not 499use elevated privileges. 500 501For more information see 502[Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats) 503in the top-level 504[LoaderInterfaceArchitecture.md][LoaderInterfaceArchitecture.md] document. 505 506 507### Forcing Layers to be Enabled on Windows, Linux and macOS 508 509Developers may want to enable layers that are not enabled by the given 510application they are using. 511 512This can be also be accomplished in one of two ways: 513 514 1. Selecting specific layers using the 515[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md) 516tool shipped with the Vulkan SDK. 517 2. Directing the loader to look for additional layers by name using the 518`VK_INSTANCE_LAYERS` environment variable. 519 520Both can be used to enable additional layers which are not specified (enabled) 521by the application at `vkCreateInstance`. 522 523The `VK_INSTANCE_LAYERS` environment variable is a list of layer names to enable 524separated by the operating-system specific path separator. 525On Windows, this is a semicolon (`;`), while on Linux and macOS it is a colon 526(`:`). 527The order of the names is relevant with the first layer name in the list being 528the top-most layer (closest to the application) and the last layer name in the 529list being the bottom-most layer (closest to the driver). 530See the [Overall Layer Ordering](#overall-layer-ordering) section for more 531information. 532 533Application specified layers and user specified layers (via environment 534variables) are aggregated and duplicates removed by the loader when enabling 535layers. 536Layers specified via environment variable are top-most (closest to the 537application) while layers specified by the application are bottom-most. 538 539An example of using these environment variables to activate the validation 540layer `VK_LAYER_KHRONOS_validation` on Linux or macOS is as follows: 541 542``` 543> $ export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation 544``` 545 546See the 547[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) 548in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md) 549for more details. 550 551 552### Overall Layer Ordering 553 554The overall ordering of all layers by the loader based on the above looks 555as follows: 556 557 558 559Ordering may also be important internally to the list of explicit layers. 560Some layers may be dependent on other behavior being implemented before 561or after the loader calls it. 562For example: An overlay layer may want to use `VK_LAYER_KHRONOS_validation` 563to verify that the overlay layer is behaving appropriately. 564This requires putting the overlay layer closer to the application so that the 565validation layer can intercept any Vulkan API calls the overlay layer needs to 566make to function. 567 568 569### Debugging Possible Layer Issues 570 571If it is possible that a layer is causing issues, there are several things that 572can be tried which are documented in the 573[Debugging Possible Layer Issues](LoaderDebugging.md#debugging-possible-layer-issues) 574section of the [LoaderDebugging.mg](LoaderDebugging.md) document in the docs 575folder. 576 577 578## Application Usage of Extensions 579 580Extensions are optional functionality provided by a layer, the loader, or a 581driver. 582Extensions can modify the behavior of the Vulkan API and need to be specified 583and registered with Khronos. 584These extensions can be implemented by a Vulkan driver, the loader, or a layer 585to expose functionality not available in the core API. 586Information about various extensions can be found in the Vulkan Spec, and 587vulkan.h header file. 588 589 590### Instance and Device Extensions 591 592As hinted at in the 593[Instance Versus Device](LoaderInterfaceArchitecture.md#instance-versus-device) 594section of the main 595[LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) document, 596there are two types of extensions: 597 * Instance Extensions 598 * Device Extensions 599 600An instance extension modifies existing behavior or implements new behavior on 601instance-level objects, such as `VkInstance` and `VkPhysicalDevice`. 602A device extension does the same for device-level objects, such as `VkDevice`, 603`VkQueue`, and `VkCommandBuffer` as well as any children of those objects. 604 605It is **very** important to know what the type of an extension is because 606instance extensions must be enabled with `vkCreateInstance` while device 607extensions are enabled with `vkCreateDevice`. 608 609When calling `vkEnumerateInstanceExtensionProperties` and 610`vkEnumerateDeviceExtensionProperties`, the loader discovers and aggregates all 611extensions of their respective type from layers (both explicit and implicit), 612drivers, and the loader before reporting them to the application. 613 614Looking at `vulkan.h`, both functions are very similar, 615for example, the `vkEnumerateInstanceExtensionProperties` prototype looks as 616follows: 617 618``` 619VkResult 620 vkEnumerateInstanceExtensionProperties( 621 const char *pLayerName, 622 uint32_t *pPropertyCount, 623 VkExtensionProperties *pProperties); 624``` 625 626While the `vkEnumerateDeviceExtensionProperties` prototype looks like: 627 628``` 629VkResult 630 vkEnumerateDeviceExtensionProperties( 631 VkPhysicalDevice physicalDevice, 632 const char *pLayerName, 633 uint32_t *pPropertyCount, 634 VkExtensionProperties *pProperties); 635``` 636 637The "pLayerName" parameter in these functions is used to select either a single 638layer or the Vulkan platform implementation. 639If "pLayerName" is NULL, extensions from Vulkan implementation components 640(including loader, implicit layers, and drivers) are enumerated. 641If "pLayerName" is equal to a discovered layer module name then only extensions 642from that layer (which may be implicit or explicit) are enumerated. 643 644**Note:** While device layers are deprecated, the instance enabled layers are 645still present in the device call-chain. 646 647Duplicate extensions (e.g. an implicit layer and driver might report support for 648the same extension) are eliminated by the loader. 649For duplicates, the driver version is reported and the layer version is culled. 650 651Also, extensions **must be enabled** (in `vkCreateInstance` or `vkCreateDevice`) 652before the functions associated with the extensions can be used. 653If an extension function is queried using either `vkGetInstanceProcAddr` or 654`vkGetDeviceProcAddr`, but the extension has not been enabled, undefined behavior 655could result. 656The Validation layers will catch this invalid API usage. 657 658 659### WSI Extensions 660 661Khronos-approved WSI extensions are available and provide Windows System 662Integration support for various execution environments. 663It is important to understand that some WSI extensions are valid for all 664targets, but others are particular to a given execution environment (and 665loader). 666This Khronos loader (currently targeting Windows, Linux, macOS, Stadia, and 667Fuchsia) only enables and directly exports those WSI extensions that are 668appropriate to the current environment. 669For the most part, the selection is done in the loader using compile-time 670preprocessor flags. 671All versions of the Khronos loader currently expose at least the following WSI 672extension support: 673- VK_KHR_surface 674- VK_KHR_swapchain 675- VK_KHR_display 676 677In addition, each of the following OS targets for the loader support target- 678specific extensions: 679 680| Windowing System | Extensions available | 681| ---------------- | ------------------------------------------ | 682| Windows | VK_KHR_win32_surface | 683| Linux (Wayland) | VK_KHR_wayland_surface | 684| Linux (X11) | VK_KHR_xcb_surface and VK_KHR_xlib_surface | 685| macOS (MoltenVK) | VK_MVK_macos_surface | 686| QNX (Screen) | VK_QNX_screen_surface | 687 688It is important to understand that while the loader may support the various 689entry-points for these extensions, there is a handshake required to actually 690use them: 691* At least one physical device must support the extension(s) 692* The application must use such a physical device when creating a logical 693device 694* The application must request the extension(s) be enabled while creating the 695instance or logical device (this depends on whether or not the given extension 696works with an instance or a device) 697 698Only then can the WSI extension be properly used in a Vulkan program. 699 700 701### Unknown Extensions 702 703With the ability to expand Vulkan so easily, extensions will be created that 704the loader knows nothing about. 705If the extension is a device extension, the loader will pass the unknown 706entry-point down the device call chain ending with the appropriate 707driver entry-points. 708The same thing will happen if the extension is an instance extension which 709takes a physical device parameter as its first component. 710However, for all other instance extensions the loader will fail to load it. 711 712*But why doesn't the loader support unknown instance extensions?* 713<br/> 714Let's look again at the instance call chain: 715 716 717 718Notice that for a normal instance function call, the loader has to handle 719passing along the function call to the available drivers. 720If the loader has no idea of the parameters or return value of the instance 721call, it can't properly pass information along to the drivers. 722There may be ways to do this, which will be explored in the future. 723However, for now, the loader does not support instance extensions which don't 724expose entry points that take a physical device as their first parameter. 725 726Because the device call-chain does not normally pass through the loader 727*terminator*, this is not a problem for device extensions. 728Additionally, since a physical device is associated with one driver, the loader 729can use a generic *terminator* pointing to one driver. 730This is because both of these extensions terminate directly in the 731driver they are associated with. 732 733*Is this a big problem?* 734<br/> 735No! 736Most extension functionality only affects either a physical or logical device 737and not an instance. 738Thus, the overwhelming majority of extensions should be supported with direct 739loader support. 740 741### Filtering Out Unknown Instance Extension Names 742 743In some cases, a driver may support instance extensions that are not supported 744by the loader. 745For the above reasons, the loader will filter out the names of these unknown 746instance extensions when an application calls 747`vkEnumerateInstanceExtensionProperties`. 748Additionally, this behavior will cause the loader to emit an error during 749`vkCreateInstance` if the application still attempts to use one of these 750extensions. 751The intent is to protect applications so that they don't inadvertently use 752functionality which could lead to a crash. 753 754On the other hand, if the extension must be forced on, the filtering may be 755disabled by defining the `VK_LOADER_DISABLE_INST_EXT_FILTER` environment 756variable to a non-zero number. 757This will effectively disable the loader's filtering of instance extension 758names. 759 760## Physical Device Ordering 761 762Prior to the 1.3.204 loader, physical devices on Linux could be returned in an 763inconsistent order. 764To remedy this, the Vulkan loader will now sort devices once they have been 765received from the drivers (before returning the information to any enabled 766layers) in the following fashion: 767 * Sort based on device type (Discrete, Integrated, Virtual, all others) 768 * Sort internal to the types based on PCI information (Domain, Bus, Device, and 769 Function). 770 771This allows for a consistent physical device order from run to run on the same 772system, unless the actual underlying hardware changes. 773 774A new environment variable is defined to give users the ability to force a 775specific device, `VK_LOADER_DEVICE_SELECT`. 776This environment variable should be set to the desired devices hex value for 777Vendor Id and Device Id (as returned from `vkGetPhysicalDeviceProperties` in 778the `VkPhysicalDeviceProperties` structure). 779It should look like the following: 780 781``` 782set VK_LOADER_DEVICE_SELECT=0x10de:0x1f91 783``` 784 785This will force on the device with a vendor ID of "0x10de" and a device ID 786of "0x1f91". 787If that device is not found, this is simply ignored. 788 789All device selection work done in the loader can be disabled by setting the 790environment variable `VK_LOADER_DISABLE_SELECT` to a non-zero value. 791This is intended for debug purposes to narrow down any issues with the loader 792device selection mechanism, but can be used by others. 793 794[Return to the top-level LoaderInterfaceArchitecture.md file.](LoaderInterfaceArchitecture.md) 795