blob: 7781c7922603bd684637ebb119d8a822bf3f55ec [file] [log] [blame] [view]
Jon Ashburnc2972682016-02-08 15:42:01 -07001# Vulkan Loader Specification and Architecture Overview
2
3
4Goals of this document
5----------------------
6
7Specify necessary functions and expected behavior of interface between the loader library and ICDs and layers for Windows, Linux and Android based systems. Also describe the application visible behaviors of the loader.
8
9Audience
10--------
11
12Application, Vulkan driver and Vulkan layer developers.
13
14Any developers interested in understanding more about loader and layer behavior and architecture.
15
16
17Loader goals
18------------
19
20- Support multiple ICDs (Installable Client Drivers) to co-exist on a system without interfering with each other.
21
22- Support optional modules (layers) that can be enabled by an application, developer or the system and have no impact when not enabled.
23
24- Negligible performance cost for an application calling through the loader to an ICD entry point.
25
26Architectural overview of layers and loader
27-------------------------------------------
28
29Vulkan is layered architecture. Layers can hook (intercept) Vulkan commands to achieve various functionality that a Vulkan driver (aka ICD) or loader doesn’t support. Functionality such as Vulkan API tracing and debugging, API usage validation, and other tools such as framebuffer overlays are all natural candidates for Vulkan layers. Layers are implemented as libraries that are inserted between the application and the driver.
30
31Not only is Vulkan a layered architecture but it also supports multiple GPUs and their drivers. Vulkan commands called by an application may wind up calling into a diverse set of modules: loader, layers, and ICDs. The loader is critical to managing the proper dispatching of Vulkan commands to the appropriate set of layers and ICDs. The loader inserts layers into a call chain so they can intercept Vulkan commands prior to the proper ICD being called. To achieve proper dispatching of Vulkan command to layers and ICDs the loader uses the Vulkan object model.
32
33Vulkan uses an object model to control the scope of a particular action / operation. The object to be acted on is always the first parameter of a Vulkan call and is a dispatchable object (see Vulkan specification section 2.2 Object Model). Under the covers, the dispatchable object handle is a pointer to a structure that contains a pointer to a dispatch table maintained by the loader. This dispatch table contains pointers to the Vulkan functions appropriate to that object. I.e. a VkInstance object’s dispatch table will point to Vulkan functions such as vkEnumeratePhysicalDevices, vkDestroyInstance, vkCreateInstance, etc.
34
35Device objects have a separate dispatch table containing the appropriate function pointers.
36
37These instance and device dispatch tables are constructed when the application calls vkCreateInstance and vkCreateDevice. At that time the application and/or system can specify optional layers to be included. The loader will initialize the specified layers to create a call chain for each Vulkan function and each entry of the dispatch table will point to the first element of that chain. Thus, the loader builds an instance call chain for each VkInstance that is created and a device call chain for each VkDevice that is created.
38
39For example, the diagram below represents what happens in the call chain for vkCreateInstance. After initializing the chain, the loader will call into the first layer’s vkCreateInstance which will call the next finally terminating in the loader again where this function calls every ICD’s vkCreateInstance and saves the results. This allows every enabled layer for this chain to set up what it needs based on the VkInstanceCreateInfo structure from the application.
40
41This also highlights some of the complexity the loader must manage when using instance chains. As shown here, the loader must aggregate information from multiple devices when they are present. This means that the loader has to know about instance level extensions to aggregate them correctly.
42
43Device chains are created at vkCreateDevice and are generally simpler because they deal with only a single device and the ICD can always be the terminator of the chain. The below diagram also illustrates how layers (either device or instance) can skip intercepting any given Vulkan entry point.
44
45Application interface to loader
46-------------------------------
47
48In this section we’ll discuss how an application interacts with the loader.
49
50- Linking to loader library for core and WSI extension symbols.
51
52- Dynamic Vulkan command lookup & application dispatch table.
53
54- Loader library filenames for linking to different Vulkan ABI versions.
55
56- Layers
57
58- Extensions
59
60- vkGetInstanceProcAddr, vkGetDeviceProcAddr
61
62The loader library on Windows, Linux and Android will export all core Vulkan and all appropriate Window System Interface (WSI) extensions. This is done to make it simpler to get started with Vulkan development. When an application links directly to the loader library in this way, the Vulkan calls are simple trampoline functions that jump to the appropriate dispatch table entry for the object they are given.
63
64Applications are not required to link directly to the loader library, instead they can use the appropriate platform specific dynamic symbol lookup on the loader library to initialize the application’s own dispatch table. This allows an application to fail gracefully if the loader cannot be found and provide the fastest mechanism for the application to call Vulkan functions. An application will only need to query (via system calls such as dlsym()) the address of vkGetInstanceProcAddr from the loader library. Using vkGetInstanceProcAddr the application can then discover the address of all instance and global functions and extensions, such as vkCreateInstance, vkEnumerateInstanceExtensionProperties and vkEnumerateInstanceLayerProperties in a platform independent way.
65
66The Vulkan loader library will be distributed in various ways including Vulkan SDKs, OS package distributions and IHV driver packages. These details are beyond the scope of this document. However, the name and versioning of the Vulkan loader library is specified so an app can link to the correct Vulkan ABI library version. Vulkan versioning is such that ABI backwards compatibility is guaranteed for all versions with the same major number (eg 1.0 and 1.1). On Windows, the loader library encodes the ABI version in its name such that multiple ABI incompatible versions of the loader can peacefully coexist on a given system. The vulkan loader library key name is “vulkan-<ABI version>”. For example, for Vulkan version 1.X on Windows the library filename is vulkan-1.dll. And this library file can typically be found in the windows/system32 directory.
67
Jon Ashburncc300a22016-02-11 14:57:30 -070068For Linux, shared libraries are versioned based on a suffix. Thus, the ABI number is not encoded in the base of the library filename as on Windows. On Linux an application wanting to link to the latest Vulkan ABI version would just link to the name vulkan (libvulkan.so). A specific Vulkan ABI version can also be linked to by applications (eg libvulkan.so.1).
Jon Ashburnc2972682016-02-08 15:42:01 -070069
Jon Ashburncc300a22016-02-11 14:57:30 -070070Applications desiring Vulkan functionality beyond what the core API offers may use various layers or extensions. A layer cannot add new or modify existing Vulkan commands, but may offer extensions that do. A common use of layers is for API validation. A developer can use validation layers during application development, but during production the layers can be disabled by the application. Thus, eliminating the overhead of validating the applications usage of the API. Layers discovered by the loader can be reported to the application via vkEnumerateInstanceLayerProperties and vkEnumerateDeviceLayerProperties, for instance and device layers respectively. Instance layers are enabled at vkCreateInstance; device layers are enabled at vkCreateDevice. For example, the ppEnabledLayerNames array in the VkDeviceCreateInfo structure is used by the application to list the device layer names to be enabled at vkCreateDevice. At vkCreateInstance and vkCreateDevice, the loader will construct call chains that include the application specified (enabled) layers. Order is important in the ppEnabledLayerNames array; array element 0 is the topmost (closest to the application) layer inserted in the chain and the last array element is closest to the driver.
Jon Ashburnc2972682016-02-08 15:42:01 -070071
Jon Ashburncc300a22016-02-11 14:57:30 -070072Developers may want to enable layers that are not enabled by the given application they are using. On Linux and Windows, the environment variables “VK\_INSTANCE\_LAYERS” and “VK\_DEVICE\_LAYERS” can be used to enable additional layers which are not specified (enabled) by the application at vkCreateInstance/vkCreateDevice. VK\_INSTANCE\_LAYERS is a colon (Linux)/semi-colon (Windows) separated list of layer names to enable. Order is relevant with the first layer in the list being the topmost layer (closest to the application) and the last layer in the list being the bottommost layer (closest to the driver).
Jon Ashburnc2972682016-02-08 15:42:01 -070073
74Application specified layers and user specified layers (via environment variables) are aggregated and duplicates removed by the loader when enabling layers. Layers specified via environment variable are topmost (closest to the application) while layers specified by the application are bottommost.
75
Jon Ashburncc300a22016-02-11 14:57:30 -070076An example of using these environment variables to activate the validation layer VK\_LAYER\_LUNARG\_param\_checker on Windows or Linux is as follows:
Jon Ashburnc2972682016-02-08 15:42:01 -070077
78```
Jon Ashburncc300a22016-02-11 14:57:30 -070079> $ export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_param_checker
Jon Ashburnc2972682016-02-08 15:42:01 -070080
Jon Ashburncc300a22016-02-11 14:57:30 -070081> $ export VK_DEVICE_LAYERS=VK_LAYER_LUNARG_param_checker
Jon Ashburnc2972682016-02-08 15:42:01 -070082```
83
84**Note**: Many layers, including all LunarG validation layers are “global” (i.e. both instance and device) layers and *must* be enabled on both the instance and device chains to function properly. This is required for “global” layers regardless of which method is used to enable the layer (application or environment variable).
85
Jon Ashburncc300a22016-02-11 14:57:30 -070086Some platforms, including Linux and Windows, support layers which are enabled automatically by the loader rather than explicitly by the application (or via environment variable). Explicit layers are those layers enabled by the application (or environment variable) by providing the layer name. Implicit layers are those layers enabled by the loader automatically. Any implicit layers the loader discovers on the system in the appropriate location will be enabled (subject to environment variable overrides described later). Discovery of properly installed implicit and explicit layers is described later. Explicitly enabling a layer that is implicitly enabled has no additional effect: the layer will still be enabled implicitly by the loader.
Jon Ashburnc2972682016-02-08 15:42:01 -070087
88Extensions are optional functionality provided by a layer, the loader or an ICD. Extensions can modify the behavior of the Vulkan API and need to be specified and registered with Khronos.
89
Jon Ashburncc300a22016-02-11 14:57:30 -070090Instance extensions can be discovered via vkEnumerateInstanceExtensionProperties. Device extensions can be discovered via vkEnumerateDeviceExtensionProperties. The loader discovers and aggregates all extensions from layers (both explicit and implicit), ICDs and the loader before reporting them to the application in vkEnumerate\*ExtensionProperties. The pLayerName parameter in these functions are used to select either a single layer or the Vulkan platform implementation. If pLayerName is NULL, extensions from Vulkan implementation components (including loader, implicit layers, and ICDs) are enumerated. If pLayerName is equal to a discovered layer module name then any extensions from that layer (which may be implicit or explicit) are enumerated. Duplicate extensions (eg an implicit layer and ICD might report support for the same extension) are eliminated by the loader. Extensions must be enabled (in vkCreateInstance or vkCreateDevice) before they can be used.
Jon Ashburnc2972682016-02-08 15:42:01 -070091
Jon Ashburncc300a22016-02-11 14:57:30 -070092Extension command entry points should be queried via vkGetInstanceProcAddr or vkGetDeviceProcAddr. vkGetDeviceProcAddr can only be used to query for device extension or core device entry points. Device entry points include any command that uses a VkDevice as the first parameter or a dispatchable object that is a child of a VkDevice (currently this includes VkQueue and VkCommandBuffer). vkGetInstanceProcAddr can be used to query either device or instance extension entry points in addition to all core entry points.
Jon Ashburnc2972682016-02-08 15:42:01 -070093
94VkGetDeviceProcAddr is particularly interesting because it will provide the most efficient way to call into the ICD. For example, the diagram below shows what could happen if the application were to use vkGetDeviceProcAddr for the function “vkGetDeviceQueue” and “vkDestroyDevice” but not “vkAllocateMemory”. The resulting function pointer (fpGetDeviceQueue) would be the ICD’s entry point if the loader and any enabled layers do not need to see that call. Even if an enabled layer intercepts the call (eg vkDestroyDevice) the loader trampoline code is skipped for function pointers obtained via vkGetDeviceProcAddr. This also means that function pointers obtained via vkGetDeviceProcAddr will only work with the specific VkDevice it was created for, using it with another device has undefined results. For extensions, Get\*ProcAddr will often be the only way to access extension API features.
95
96
97Vulkan Installable Client Driver interface with the loader
98----------------------------------------------------------
99
100### ICD discovery
101
102Vulkan allows multiple drivers each with one or more devices (represented by a Vulkan VkPhysicalDevice object) to be used collectively. The loader is responsible for discovering available Vulkan ICDs on the system. Given a list of available ICDs, the loader can enumerate all the physical devices available for an application and return this information to the application. The process in which the loader discovers the available Installable Client Drivers (ICDs) on a system is platform dependent. Windows, Linux and Android ICD discovery details are listed below.
103
104#### Windows
105
106##### Properly-Installed ICDs
107
108In order to find properly-installed ICDs, the Vulkan loader will scan the values in the following Windows registry key:
109
110HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers
111
Jon Ashburncc300a22016-02-11 14:57:30 -0700112For each value in this key which has DWORD data set to 0, the loader opens the JSON format text information file (a.k.a. "manifest file") specified by the name of the value. Each name must be a full pathname to the text manifest file. The Vulkan loader will open each manifest file to obtain the name or pathname of an ICD shared library (".dll") file. For example:
Jon Ashburnc2972682016-02-08 15:42:01 -0700113
Jon Ashburncc300a22016-02-11 14:57:30 -0700114 ```
115 {
Jon Ashburnc2972682016-02-08 15:42:01 -0700116 "file_format_version": "1.0.0",
117 "ICD": {
118 "library_path": "path to ICD library",
Tony Barbourcd489512016-02-10 15:59:32 -0700119 "api_version": "1.0.3"
Jon Ashburnc2972682016-02-08 15:42:01 -0700120 }
121 }
Jon Ashburncc300a22016-02-11 14:57:30 -0700122 ```
Jon Ashburnc2972682016-02-08 15:42:01 -0700123
124
Jon Ashburncc300a22016-02-11 14:57:30 -0700125The "library\_path" specifies either a filename, a relative pathname, or a full pathname to an ICD shared library file, which the loader will attempt to load using LoadLibrary(). If the ICD is specified via a filename, the shared library lives in the system's DLL search path (e.g. in the "C:\\\\Windows\\\\System32" folder). If the ICD is specified via a relative pathname, it is relative to the path of the manifest file. Relative pathnames are those that do not start with a drive specifier (e.g. "C:"), nor with a directory separator (i.e. the '\\' character), but do contain at least one directory separator.
Jon Ashburnc2972682016-02-08 15:42:01 -0700126
Jon Ashburncc300a22016-02-11 14:57:30 -0700127The "file\_format\_version" specifies a major.minor.patch version number in case the format of the text information file changes in the future. If the same ICD shared library supports multiple, incompatible versions of text manifest file format versions, it must have multiple text info files (all of which may point to the same shared library).
Jon Ashburnc2972682016-02-08 15:42:01 -0700128
129The “api\_version” specifies the major.minor.patch version number of the Vulkan API that the shared library (referenced by "library\_path") was built with.
130
Jon Ashburncc300a22016-02-11 14:57:30 -0700131There are no rules about the name of the text information files (except the .json suffix).
Jon Ashburnc2972682016-02-08 15:42:01 -0700132
Jon Ashburncc300a22016-02-11 14:57:30 -0700133There are no rules about the name of the ICD shared library files. For example, if the registry contains the following values,
Jon Ashburnc2972682016-02-08 15:42:01 -0700134
Jon Ashburncc300a22016-02-11 14:57:30 -0700135```
136[HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\]
Jon Ashburnc2972682016-02-08 15:42:01 -0700137
Jon Ashburncc300a22016-02-11 14:57:30 -0700138"C:\vendor a\vk\_vendora.json"=dword:00000000
Jon Ashburnc2972682016-02-08 15:42:01 -0700139
Jon Ashburncc300a22016-02-11 14:57:30 -0700140"C:\windows\system32\vendorb\_vk.json"=dword:00000000
Jon Ashburnc2972682016-02-08 15:42:01 -0700141
Jon Ashburncc300a22016-02-11 14:57:30 -0700142"C:\windows\system32\vendorc\_icd.json"=dword:00000000
143```
Jon Ashburnc2972682016-02-08 15:42:01 -0700144then the loader will open the following text information files, with the specified contents:
145
Jon Ashburncc300a22016-02-11 14:57:30 -0700146| Text File Name | Text File Contents |
147|-------------------------------------|
148|vk\_vendora.json | "ICD": { "library\_path": "C:\\\\VENDORA\\\\vk\_vendora.dll", "api_version": "1.0.3" } |
149| vendorb\_vk.json | "ICD": { "library\_path": "vendorb\_vk.dll", "api_version": "1.0.3" } |
150|vendorc\_icd.json | "ICD": { "library\_path": "vedorc\_icd.dll", "api_version": "1.0.3" }|
Jon Ashburnc2972682016-02-08 15:42:01 -0700151
Jon Ashburncc300a22016-02-11 14:57:30 -0700152Then the loader will open the three files mentioned in the "Text File Contents" column, and then try to load and use the three shared libraries indicated by the ICD.library\_path value.
Jon Ashburnc2972682016-02-08 15:42:01 -0700153
154##### Using Pre-Production ICDs
155
156IHV developers (and sometimes other developers) need to use special, pre-production ICDs. In some cases, a pre-production ICD may be in an installable package. In other cases, a pre-production ICD may simply be a shared library in the developer's build tree. In this latter case, we want to allow developers to point to such an ICD without modifying the properly-installed ICD(s) on their system.
157
Jon Ashburncc300a22016-02-11 14:57:30 -0700158This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, which will override the mechanism used for finding properly-installed ICDs. In other words, only the ICDs listed in "VK\_ICD\_FILENAMES" will be used. The "VK\_ICD\_FILENAMES" environment variable is a semi-colon-separated list of ICD text information files (aka manifest files), containing the following:
Jon Ashburnc2972682016-02-08 15:42:01 -0700159
Jon Ashburncc300a22016-02-11 14:57:30 -0700160- A full pathname (e.g. "C:\\my\_build\\my\_icd.json")
Jon Ashburnc2972682016-02-08 15:42:01 -0700161
162Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info file for a developer-built ICD. A semi-colon is only used if more than one ICD is listed.
163
164For example, if a developer wants to refer to one ICD that they built, they could set the "VK\_ICD\_FILENAMES" environment variable to:
165
Jon Ashburncc300a22016-02-11 14:57:30 -0700166C:\\my\_build\\my\_icd.json
Jon Ashburnc2972682016-02-08 15:42:01 -0700167
168If a developer wants to refer to two ICDs, one of which is a properly-installed ICD, they can use the full pathname of the text file:
169
Jon Ashburncc300a22016-02-11 14:57:30 -0700170C:\\Windows\\System32\\vendorc\_icd.json;C:\\my\_build\\my\_icd.json
Jon Ashburnc2972682016-02-08 15:42:01 -0700171
Jon Ashburncc300a22016-02-11 14:57:30 -0700172Notice the semi-colon between "C:\\Windows\\System32\\vendorc\_icd.json" and "C:\\my\_build\\my\_icd.json".
Jon Ashburnc2972682016-02-08 15:42:01 -0700173
174#### Linux
175
176##### Properly-Installed ICDs
177
178In order to find properly-installed ICDs, the Vulkan loader will scan the files in the following Linux directories:
179
180/usr/share/vulkan/icd.d
Jon Ashburnc2972682016-02-08 15:42:01 -0700181/etc/vulkan/icd.d
182
Jon Ashburncc300a22016-02-11 14:57:30 -0700183These directories will contain text information files (a.k.a. "manifest files"), that use a JSON format.
Jon Ashburnc2972682016-02-08 15:42:01 -0700184
Jon Ashburncc300a22016-02-11 14:57:30 -0700185The Vulkan loader will open each manifest file found to obtain the name or pathname of an ICD shared library (".so") file. For example:
Jon Ashburnc2972682016-02-08 15:42:01 -0700186
Jon Ashburncc300a22016-02-11 14:57:30 -0700187```
188{
Jon Ashburnc2972682016-02-08 15:42:01 -0700189 "file_format_version": "1.0.0",
190 "ICD": {
191 "library_path": "path to ICD library",
Tony Barbourcd489512016-02-10 15:59:32 -0700192 "api_version": "1.0.3"
Jon Ashburnc2972682016-02-08 15:42:01 -0700193 }
194}
Jon Ashburncc300a22016-02-11 14:57:30 -0700195```
Jon Ashburnc2972682016-02-08 15:42:01 -0700196The "library\_path" specifies either a filename, a relative pathname, or a full pathname to an ICD shared library file. If the ICD is specified via a filename, the loader will attempt to open that file as a shared object using dlopen(), and the file must be in a directory that dlopen is configured to look in (Note: various distributions are configured differently). A distribution is free to create Vulkan-specific system directories (e.g. ".../vulkan/icd"), but is not required to do so. If the ICD is specified via a relative pathname, it is relative to the path of the info file. Relative pathnames are those that do not start with, but do contain at least one directory separator (i.e. the '/' character). For example, "lib/vendora.so" and "./vendora.so" are examples of relative pathnames.
197
Jon Ashburncc300a22016-02-11 14:57:30 -0700198The "file\_format\_version" provides a major.minor.patch version number in case the format of the manifest file changes in the future. If the same ICD shared library supports multiple, incompatible versions of manifest file format versions, it must have multiple manifest files (all of which may point to the same shared library).
Jon Ashburnc2972682016-02-08 15:42:01 -0700199
200The “api\_version” specifies the major.minor.patch version number of the Vulkan API that the shared library (referenced by "library\_path") was built with.
201
202The "/usr/share/vulkan/icd.d" directory is for ICDs that are installed from Linux-distribution-provided packages. The "/etc/vulkan/icd.d" directory is for ICDs that are installed from non-Linux-distribution-provided packages.
203
204There are no rules about the name of the text files (except the .json suffix).
205
206There are no rules about the name of the ICD shared library files. For example, if the "/usr/share/vulkan/icd.d" directory contain the following files, with the specified contents:
207
Jon Ashburncc300a22016-02-11 14:57:30 -0700208| Text File Name | Text File Contents |
209|-----------------|--------------------|
210|vk\_vendora.json | "ICD": { "library\_path": "vendora.so", "api_version": "1.0.3" } |
211| vendorb\_vk.json | "ICD": { "library\_path": "vendorb\_vulkan\_icd.so", "api_version": "1.0.3" } |
212| vendorc\_icd.json | "ICD": { "library\_path": "/usr/lib/VENDORC/icd.so", "api_version": "1.0.1" }|
Jon Ashburnc2972682016-02-08 15:42:01 -0700213
Jon Ashburncc300a22016-02-11 14:57:30 -0700214then the loader will open the three files mentioned in the "Text File Contents" column, and then try to load and use the three shared libraries indicated by the ICD.library\_path value.
Jon Ashburnc2972682016-02-08 15:42:01 -0700215
216##### Using Pre-Production ICDs
217
218IHV developers (and sometimes other developers) need to use special, pre-production ICDs. In some cases, a pre-production ICD may be in an installable package. In other cases, a pre-production ICD may simply be a shared library in the developer's build tree. In this latter case, we want to allow developers to point to such an ICD without modifying the properly-installed ICD(s) on their system.
219
220This need is met with the use of the "VK\_ICD\_FILENAMES" environment variable, which will override the mechanism used for finding properly-installed ICDs. In other words, only the ICDs listed in "VK\_ICD\_FILENAMES" will be used.
221
Jon Ashburncc300a22016-02-11 14:57:30 -0700222The "VK\_ICD\_FILENAMES" environment variable is a colon-separated list of ICD manifest files, containing the following:
Jon Ashburnc2972682016-02-08 15:42:01 -0700223
224- A filename (e.g. "libvkicd.json") in the "/usr/share/vulkan/icd.d" or "/etc/vulkan/icd.d" system directories
225
226- A full pathname (e.g. "/my\_build/my\_icd.json")
227
228Typically, "VK\_ICD\_FILENAMES" will only contain a full pathname to one info file for a developer-built ICD. A colon is only used if more than one ICD is listed.
229
230For example, if a developer wants to refer to one ICD that they built, they could set the "VK\_ICD\_FILENAMES" environment variable to:
231
232/my\_build/my\_icd.json
233
234If a developer wants to refer to two ICDs, one of which is a properly-installed ICD, they can use the name of the text file in the system directory:
235
236vendorc\_vulkan.json:/my\_build/my\_icd.json
237
238Notice the colon between "vendorc\_vulkan.json" and "/my\_build/my\_icd.json".
239
240NOTE: this environment variable will be ignored for suid programs.
241
242#### Android
243
244TODO: Fill out this section
245
246
Jon Ashburncc300a22016-02-11 14:57:30 -0700247ICD interface requirements
248----------------------------------------
Jon Ashburnc2972682016-02-08 15:42:01 -0700249
250Generally, for all Vulkan commands issued by an application, the loader can be viewed as a pass through. That is, the loader generally doesn’t modified the commands or their parameters but simply calls the ICDs entry point for that command. Thus, the loader to ICD interface requirements will be specified by covering two areas: 1) Obtaining ICD Vulkan entry points; 2) Specifying requirements for a given Vulkan command(s) over and above the Vulkan specification requirements.
251
252#### Windows and Linux
253
254##### Obtaining ICD entry points
255
256Currently, two methods of the loader finding ICD entry points are supported on Linux and Windows:
257
2581) Recommended
259
Jon Ashburncc300a22016-02-11 14:57:30 -0700260- vk\_icdGetInstanceProcAddr exported in the ICD library and it returns valid function pointers for all the global level and instance level Vulkan commands, and also vkGetDeviceProcAddr. Global level commands are those which contain no dispatchable object as the first parameter, such as vkCreateInstance and vkEnumerateInstanceExtensionProperties. The ICD must support querying global level entry points by calling vk\_icdGetInstanceProcAddr with a NULL VkInstance parameter. Instance level commands are those that have either VkInstance, or VkPhysicalDevice as the first parameter dispatchable object. Both core entry points and any instance extension entry points the ICD supports should be available via vk\_icdGetInstanceProcAddr. Future Vulkan instance extensions may define and use new instance level dispatchable objects other than VkInstance and VkPhysicalDevice, in which case, extensions entry points using these newly defined dispatchable oibjects must be queryable via vk\_icdGetInstanceProcAddr.
Jon Ashburnc2972682016-02-08 15:42:01 -0700261
Jon Ashburncc300a22016-02-11 14:57:30 -0700262- All other Vulkan entry points must either NOT be exported from the ICD library or else NOT use the official Vulkan function names if they are exported. This requirement is for ICD libraries that include other functionality (such as OpenGL library) and thus could be loaded by the application prior to when the Vulkan loader library is loaded by the application. In other words, the ICD library exported Vulkan symbols must not clash with the loader's exported Vulkan symbols.
Jon Ashburnc2972682016-02-08 15:42:01 -0700263
2642) Deprecated
265
266- vkGetInstanceProcAddr exported in the ICD library and returns valid function pointers for all the Vulkan API entrypoints.
267
268- vkCreateInstance exported in the ICD library;
269
270- vkEnumerateInstanceExtensionProperties exported in the ICD library;
271
272##### Loader specific requirements for Vulkan commands
273
274Normally, ICDs handle object creation and destruction for various Vulkan objects. The WSI surface extensions for Linux and Windows (VK\_KHR\_win32\_surface, VK\_KHR\_xcb\_surface, VK\_KHR\_xlib\_surface, VK\_KHR\_mir\_surface, VK\_KHR\_wayland\_surface, and VK\_KHR\_surface) are handled differently. For these extensions, the VkSurfaceKHR object creation and destruction is handled by the loader as follows:
275
Jon Ashburncc300a22016-02-11 14:57:30 -07002761. Loader handles the vkCreate\*SurfaceKHR() and vkDestroySurfaceKHR() functions including creating/destroying the VkSurfaceKHR object.
Jon Ashburnc2972682016-02-08 15:42:01 -0700277
Jon Ashburncc300a22016-02-11 14:57:30 -07002782. VkSurfaceKHR objects have the underlying structure (VkIcdSurface\*) as defined in include/vulkan/vk\_icd.h.
Jon Ashburnc2972682016-02-08 15:42:01 -0700279
Jon Ashburncc300a22016-02-11 14:57:30 -07002803. ICDs can cast any VkSurfaceKHR object to a pointer to the appropriate VkIcdSurface\* structure.
Jon Ashburnc2972682016-02-08 15:42:01 -0700281
Jon Ashburncc300a22016-02-11 14:57:30 -07002824. VkIcdSurface\* structures include VkIcdSurfaceWin32, VkIcdSurfaceXcb, VkIcdSurfaceXlib, VkIcdSurfaceMir, and VkIcdSurfaceWayland. The first field in the structure is a VkIcdSurfaceBase enumerant that indicates westher the surface object is Win32, Xcb, Xlib, Mir, or Wayland.
Jon Ashburnc2972682016-02-08 15:42:01 -0700283
284As previously covered, the loader requires dispatch tables to be accessible within Vulkan dispatchable objects, which include VkInstance, VkPhysicalDevice, VkDevice, VkQueue, and VkCommandBuffer. The specific requirements on all dispatchable objects created by ICDs are as follows:
285
Jon Ashburncc300a22016-02-11 14:57:30 -0700286- All dispatchable objects created by an ICD can be cast to void \*\*
Jon Ashburnc2972682016-02-08 15:42:01 -0700287
Jon Ashburncc300a22016-02-11 14:57:30 -0700288- The loader will replace the first entry with a pointer to the dispatch table which is owned by the loader. This implies three things for ICD drivers:
Jon Ashburnc2972682016-02-08 15:42:01 -0700289
Jon Ashburncc300a22016-02-11 14:57:30 -07002901. The ICD must return a pointer for the opaque dispatchable object handle.
Jon Ashburnc2972682016-02-08 15:42:01 -0700291
Jon Ashburncc300a22016-02-11 14:57:30 -07002922. This pointer points to a regular C structure with the first entry being a pointer. Note: for any C\++ ICD's that implement VK objects directly as C\++ classes. The C\++ compiler may put a vtable at offset zero if your class is virtual. In this case use a regular C structure (see below).
Jon Ashburnc2972682016-02-08 15:42:01 -0700293
Jon Ashburncc300a22016-02-11 14:57:30 -07002943. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the created dispatchable objects, as follows (see include/vulkan/vk\_icd.h):
Jon Ashburnc2972682016-02-08 15:42:01 -0700295
296```
297
Jon Ashburncc300a22016-02-11 14:57:30 -0700298#include "vk_icd.h"
Jon Ashburnc2972682016-02-08 15:42:01 -0700299
Jon Ashburncc300a22016-02-11 14:57:30 -0700300union _VK_LOADER_DATA {
301 uintptr loadermagic;
302 void *loaderData;
303} VK_LOADER_DATA;
Jon Ashburnc2972682016-02-08 15:42:01 -0700304
Jon Ashburncc300a22016-02-11 14:57:30 -0700305vkObj alloc_icd_obj()
Jon Ashburnc2972682016-02-08 15:42:01 -0700306{
Jon Ashburncc300a22016-02-11 14:57:30 -0700307 vkObj *newObj = alloc_obj();
308 ...
309 // Initialize pointer to loader's dispatch table with ICD_LOADER_MAGIC
Jon Ashburnc2972682016-02-08 15:42:01 -0700310
Jon Ashburncc300a22016-02-11 14:57:30 -0700311 set_loader_magic_value(newObj);
312 ...
313 return newObj;
Jon Ashburnc2972682016-02-08 15:42:01 -0700314}
Jon Ashburnc2972682016-02-08 15:42:01 -0700315```
316
317Additional Notes:
318
Jon Ashburncc300a22016-02-11 14:57:30 -0700319- The loader will filter out extensions requested in vkCreateInstance and vkCreateDevice before calling into the ICD; Filtering will be of extensions advertised by entities (eg layers) different from the ICD in question.
320- The loader will not call ICD for vkEnumerate\*LayerProperties() as layer properties are obtained from the layer libraries and layer JSON files.
321- If an ICD library wants to implement a layer it can do so by having the appropriate layer JSON manifest file refer to the ICD library file.
322- The loader will not call ICD for vkEnumerate\*ExtensionProperties(pLayerName != NULL).
Jon Ashburnc2972682016-02-08 15:42:01 -0700323- The ICD may or may not implement a dispatch table.
324
325#### Android
326
327TODO: Fill out this section
328
329Vulkan layer interface with the loader
330--------------------------------------
331
332### Layer discovery
333
334#### Windows
335
336##### Properly-Installed Layers
337
Jon Ashburncc300a22016-02-11 14:57:30 -0700338In order to find properly-installed layers, the Vulkan loader will use a similar mechanism as used for ICDs. Text information files (aka manifest files), that use a JSON format, are read in order to identify the names and attributes of layers and their extensions. The use of manifest files allows the loader to avoid loading any shared library files when the application does not query nor request any extensions. Layers and extensions have additional complexity, and so their manifest files contain more information than ICD info files. For example, a layer shared library file may contain multiple layers/extensions (perhaps even an ICD).
Jon Ashburnc2972682016-02-08 15:42:01 -0700339
340In order to find properly-installed layers, the Vulkan loader will scan the values in the following Windows registry keys:
341
342HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers
343
344HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers
345
346Explicit layers are those which are enabled by an application (e.g. with the vkCreateInstance function), or by an environment variable (as mentioned previously).
347
348Implicit layers are those which are enabled by their existence. For example, certain application environments (e.g. Steam or an automotive infotainment system) may have layers which they always want enabled for all applications that they start. Other implicit layers may be for all applications started on a given system (e.g. layers that overlay frames-per-second). Implicit layers are enabled automatically, whereas explicit layers must be enabled explicitly. What distinguishes a layer as implicit or explicit is by which registry key its layer information file is referenced by.
349
Jon Ashburncc300a22016-02-11 14:57:30 -0700350For each value in these keys which has DWORD data set to 0, the loader opens the JSON manifest file specified by the name of the value. Each name must be a full pathname to the manifest file.
Jon Ashburnc2972682016-02-08 15:42:01 -0700351
352The Vulkan loader will open each info file to obtain information about the layer, including the name or pathname of a shared library (".dll") file.
353
Jon Ashburncc300a22016-02-11 14:57:30 -0700354This manifest file is in the JSON format and contains the following information:
Jon Ashburnc2972682016-02-08 15:42:01 -0700355
356- (required) "file\_format\_version" - same as for ICDs, except that the format version can vary independently for ICDs and layers.
357
358- (required) "name" - layer name
359
360- (required) "type" - which layer chains should the layer be activated on.
Jon Ashburnc2972682016-02-08 15:42:01 -0700361Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate on both device and instance chains.
362
Jon Ashburncc300a22016-02-11 14:57:30 -0700363- (required) "library\_path" - filename / full path / relative path to the library file
Jon Ashburnc2972682016-02-08 15:42:01 -0700364
365- (required) "api\_version" - same as for ICDs.
366
367- (required) "implementation\_version" - layer version, a single number increasing with backward compatible changes.
368
369- (required) "description" - informative description of the layer.
370
371- (optional) "device\_extensions" or "instance\_extensions" - array of extension information as follows
372
Jon Ashburncc300a22016-02-11 14:57:30 -0700373 - (required) extension "name" - Vulkan registered name
Jon Ashburnc2972682016-02-08 15:42:01 -0700374
Jon Ashburncc300a22016-02-11 14:57:30 -0700375 - (required) extension "spec\_version" - extension specification version, a single number, increasing with backward compatible changes.
Jon Ashburnc2972682016-02-08 15:42:01 -0700376
Jon Ashburncc300a22016-02-11 14:57:30 -0700377 - (required for device\_extensions with entry points) extension "entrypoints" - array of device extension entrypoints; not used for instance extensions
Jon Ashburnc2972682016-02-08 15:42:01 -0700378
379- (sometimes required) "functions" - mapping list of function entry points. If multiple layers exist within the same shared library (or if a layer is in the same shared library as an ICD), this must be specified to allow each layer to have its own vkGet\*ProcAddr entrypoints that can be found by the loader. At this time, only the following two functions are required:
380
Jon Ashburncc300a22016-02-11 14:57:30 -0700381 - "vkGetInstanceProcAddr" name
Jon Ashburnc2972682016-02-08 15:42:01 -0700382
Jon Ashburncc300a22016-02-11 14:57:30 -0700383 - "vkGetDeviceProcAddr" name
Jon Ashburnc2972682016-02-08 15:42:01 -0700384
385- (optional for implicit layers) "enable\_environment" requirement(s) - environment variable and value required to enable an implicit layer. This environment variable (which should vary with each "version" of the layer, as in "ENABLE\_LAYER\_FOO\_1") must be set to the given value or else the implicit layer is not loaded. This is for application environments (e.g. Steam) which want to enable a layer(s) only for applications that they launch, and allows for applications run outside of an application environment to not get that implicit layer(s).
386
387- (required for implicit layers) "disable\_environment" requirement(s) - environment variable and value required to disable an implicit layer. Note: in rare cases of an application not working with an implicit layer, the application can set this environment variable (before calling Vulkan functions) in order to "blacklist" the layer. This environment variable (which should vary with each "version" of the layer, as in "DISABLE\_LAYER\_FOO\_1") must be set (not particularly to any value). If both the "enable\_environment" and "disable\_environment" variables are set, the implicit layer is disabled.
388
389For example:
390
Jon Ashburncc300a22016-02-11 14:57:30 -0700391```
Jon Ashburnc2972682016-02-08 15:42:01 -0700392{
Jon Ashburncc300a22016-02-11 14:57:30 -0700393"file_format_version" : "1.0.0",
394"layer": {
395 "name": "VK_LAYER_LUNARG_OverlayLayer",
396 "type": "DEVICE",
397 "library_path": "vkOverlayLayer.dll"
398 "api_version" : "1.0.3",
399 "implementation_version" : "2",
400 "description" : "LunarG HUD layer",
401 "functions": {
402 "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
403 "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
404 },
405 instance_extensions": [
406 {
407 "name": "VK_debug_report_EXT",
408 "spec_version": "1"
409 },
410 {
411 "name": "VK_VENDOR_DEBUG_X",
412 "spec_version": "3"
413 }
414 ],
415 device_extensions": [
416 {
417 "name": "VK_LUNARG_DEBUG_MARKER",
418 "spec_version": "1",
419 "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
420 }
421 ],
422 "disable_environment": {
423 "DISABLE_LAYER_OVERLAY_1": ""
424 }
Jon Ashburnc2972682016-02-08 15:42:01 -0700425}
Jon Ashburnc2972682016-02-08 15:42:01 -0700426}
Jon Ashburncc300a22016-02-11 14:57:30 -0700427```
Jon Ashburnc2972682016-02-08 15:42:01 -0700428
Jon Ashburncc300a22016-02-11 14:57:30 -0700429The "library\_path" specifies either a filename, a relative pathname, or a full pathname to a layer shared library (".dll") file, which the loader will attempt to load using LoadLibrary(). If the layer is specified via a relative pathname, it is relative to the path of the info file (e.g. for cases when an application provides a layer that is in the same folder hierarchy as the rest of the application files). If the layer is specified via a filename, the shared library lives in the system's DLL search path (e.g. in the "C:\\Windows\\System32" folder).
Jon Ashburnc2972682016-02-08 15:42:01 -0700430
431There are no rules about the name of the text files (except the .json suffix).
432
433There are no rules about the name of the layer shared library files.
434
435##### Using Pre-Production Layers
436
437As with ICDs, developers may need to use special, pre-production layers, without modifying the properly-installed layers. This need is met with the use of the "VK\_LAYER\_PATH" environment variable, which will override the mechanism using for finding properly-installed layers. Because many layers may exist on a system, this environment variable is a semi-colon-separated list of folders that contain layer info files. Only the folder listed in "VK\_LAYER\_PATH" will be scanned for info files. Each semi-colon-separated entry is:
438
439- The full pathname of a folder containing layer info files
440
441#### Linux
442
443##### Properly-Installed Layers
444
445In order to find properly-installed layers, the Vulkan loader will use a similar mechanism as used for ICDs. Text information files, that use a JSON format, are read in order to identify the names and attributes of layers and their extensions. The use of text info files allows the loader to avoid loading any shared library files when the application does not query nor request any extensions. Layers and extensions have additional complexity, and so their info files contain more information than ICD info files. For example, a layer shared library file may contain multiple layers/extensions (perhaps even an ICD).
446
447The Vulkan loader will scan the files in the following Linux directories:
448
449/usr/share/vulkan/explicit\_layer.d
Jon Ashburnc2972682016-02-08 15:42:01 -0700450/usr/share/vulkan/implicit\_layer.d
Jon Ashburnc2972682016-02-08 15:42:01 -0700451/etc/vulkan/explicit\_layer.d
Jon Ashburnc2972682016-02-08 15:42:01 -0700452/etc/vulkan/implicit\_layer.d
453
454Explicit layers are those which are enabled by an application (e.g. with the vkCreateInstance function), or by an environment variable (as mentioned previously). Implicit layers are those which are enabled by their existence. For example, certain application environments (e.g. Steam or an automotive infotainment system) may have layers which they always want enabled for all applications that they start. Other implicit layers may be for all applications started on a given system (e.g. layers that overlay frames-per-second). Implicit layers are enabled automatically, whereas explicit layers must be enabled explicitly. What distinguishes a layer as implicit or explicit is by which directory its layer information file exists in.
455
Jon Ashburncc300a22016-02-11 14:57:30 -0700456The "/usr/share/vulkan/\*\_layer.d" directories are for layers that are installed from Linux-distribution-provided packages. The "/etc/vulkan/\*\_layer.d" directories are for layers that are installed from non-Linux-distribution-provided packages.
Jon Ashburnc2972682016-02-08 15:42:01 -0700457
458The information file is in the JSON format and contains the following information:
459
460- (required) "file\_format\_version" – same as for ICDs, except that the format version can vary independently for ICDs and layers.
461
462- (required) "name" - layer name
463
464- (required) "type" - which layer chains should the layer be activated on. Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate on both device and instance chains.
465
466- (required) "library\_path" - filename / full path / relative path to the text file
467
468- (required) "api\_version" – same as for ICDs.
469
470- (required) "implementation\_version" – layer version, a single number increasing with backward compatible changes.
471
472- (required) "description" – informative decription of the layer.
473
474- (optional) "device\_extensions" or "instance\_extensions" - array of extension information as follows
475
Jon Ashburncc300a22016-02-11 14:57:30 -0700476 - (required) extension "name" - Vulkan registered name
Jon Ashburnc2972682016-02-08 15:42:01 -0700477
Jon Ashburncc300a22016-02-11 14:57:30 -0700478 - (required) extension "spec\_version" - extension specification version, a single number, increasing with backward compatible changes.
Jon Ashburnc2972682016-02-08 15:42:01 -0700479
Jon Ashburncc300a22016-02-11 14:57:30 -0700480 - (required for device extensions with entry points) extension "entrypoints" - array of device extension entrypoints; not used for instance extensions
Jon Ashburnc2972682016-02-08 15:42:01 -0700481
482- (sometimes required) "functions" - mapping list of function entry points. If multiple layers exist within the same shared library (or if a layer is in the same shared library as an ICD), this must be specified to allow each layer to have its own vkGet\*ProcAddr entrypoints that can be found by the loader. At this time, only the following two functions are required:
Jon Ashburncc300a22016-02-11 14:57:30 -0700483 - "vkGetInstanceProcAddr" name
484 - "vkGetDeviceProcAddr" name
Jon Ashburnc2972682016-02-08 15:42:01 -0700485
486- (optional for implicit layers) "enable\_environment" requirement(s) - environment variable and value required to enable an implicit layer. This environment variable (which should vary with each "version" of the layer, as in "ENABLE\_LAYER\_FOO\_1") must be set to the given value or else the implicit layer is not loaded. This is for application environments (e.g. Steam) which want to enable a layer(s) only for applications that they launch, and allows for applications run outside of an application environment to not get that implicit layer(s).
487
488- (required for implicit layers) "disable\_environment" requirement(s) - environment variable and value required to disable an implicit layer. Note: in rare cases of an application not working with an implicit layer, the application can set this environment variable (before calling Vulkan functions) in order to "blacklist" the layer. This environment variable (which should vary with each "version" of the layer, as in "DISABLE\_LAYER\_FOO\_1") must be set (not particularly to any value). If both the "enable\_environment" and "disable\_environment" variables are set, the implicit layer is disabled.
489
490For example:
Jon Ashburncc300a22016-02-11 14:57:30 -0700491```
Jon Ashburnc2972682016-02-08 15:42:01 -0700492{
Jon Ashburncc300a22016-02-11 14:57:30 -0700493"file_format_version" : "1.0.0",
Jon Ashburnc2972682016-02-08 15:42:01 -0700494"layer": {
Jon Ashburncc300a22016-02-11 14:57:30 -0700495 "name": "VK_LAYER_LUNARG_OverlayLayer",
496 "type": "DEVICE",
497 "library_path": "vkOverlayLayer.dll"
498 "api_version" : "1.0.3",
499 "implementation_version" : "2",
500 "description" : "LunarG HUD layer",
501 "functions": {
502 "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
503 "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
504 },
505 instance_extensions": [
506 {
507 "name": "VK_debug_report_EXT",
508 "spec_version": "1"
509 },
510 {
511 "name": "VK_VENDOR_DEBUG_X",
512 "spec_version": "3"
513 }
514 ],
515 device_extensions": [
516 {
517 "name": "VK_LUNARG_DEBUG_MARKER",
518 "spec_version": "1",
519 "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
520 }
521 ],
522 "disable_environment": {
523 "DISABLE_LAYER_OVERLAY_1": ""
524 }
Jon Ashburnc2972682016-02-08 15:42:01 -0700525}
Jon Ashburnc2972682016-02-08 15:42:01 -0700526}
Jon Ashburncc300a22016-02-11 14:57:30 -0700527```
Jon Ashburnc2972682016-02-08 15:42:01 -0700528The "library\_path" specifies either a filename, a relative pathname, or a full pathname to a layer shared library (".so") file, which the loader will attempt to load using dlopen(). If the layer is specified via a filename, the loader will attempt to open that file as a shared object using dlopen(), and the file must be in a directory that dlopen is configured to look in (Note: various distributions are configured differently). A distribution is free to create Vulkan-specific system directories (e.g. ".../vulkan/layers"), but is not required to do so. If the layer is specified via a relative pathname, it is relative to the path of the info file (e.g. for cases when an application provides a layer that is in the same directory hierarchy as the rest of the application files).
529
530There are no rules about the name of the text files (except the .json suffix).
531
532There are no rules about the name of the layer shared library files.
533
534##### Using Pre-Production Layers
535
536As with ICDs, developers may need to use special, pre-production layers, without modifying the properly-installed layers. This need is met with the use of the "VK\_LAYER\_PATH" environment variable, which will override the mechanism using for finding properly-installed layers. Because many layers may exist on a system, this environment variable is a colon-separated list of directories that contain layer info files. Only the directories listed in "VK\_LAYER\_PATH" will be scanned for info files. Each colon-separated entry is:
537
538- The full pathname of a directory containing layer info files
539
540NOTE: these environment variables will be ignored for suid programs.
541
542#### Android
543
544TODO: Fill out this section
545
Jon Ashburncc300a22016-02-11 14:57:30 -0700546Layer interface requirements
547------------------------------------------------------
Jon Ashburnc2972682016-02-08 15:42:01 -0700548
549#### Architectural interface overview
550
551There are two key architectural features that drive the loader to layer library interface: 1) separate and distinct instance and device call chains, and 2) distributed dispatch. First these architectural features will be described and then the detailed interface will be specified.
552
553Call chains are the links of calls for a given Vulkan command from layer module to layer module with the loader and or the ICD being the bottom most command. Call chains are constructed at both the instance level and the device level by the loader with cooperation from the layer libraries. Instance call chains are constructed by the loader when layers are enabled at vkCreateInstance. Device call chains are constructed by the loader when layers are enabled at CreateDevice. A layer can intercept Vulkan instance commands, device commands or both. For a layer to intercept instance commands, it must participate in the instance call chain. For a layer to intercept device commands, it must participate in the device chain. Layers which participate in intercepting calls in both the intance and device chains are called global layers.
554
555Normally, when a layer intercepts a given Vulkan command, it will call down the instance or device chain as needed. The loader and all layer libraries that participate in a call chain cooperate to ensure the correct sequencing of calls from one entity to the next. This group effort for call cahin sequencing is hereinafter referred to as disitributed dispatch. In distributed dispatch, since each layer is responsible for properly calling the next entity in the device or instance chain, a dispatch mechanism is required for all Vulkan commands a layer intercepts. For Vulkan commands that are not intercepted by a layer, or if the layer chooses to terminate a given Vulkman command by not calling down the chain, then no dispatch mechanism is needed for that particular Vulkan command. Only for those Vulkan commands, which may be a subset of all Vulkan commands, that a layer intercepts is a dispatching mechanism by the layer needed. The loader is responsible for dispatching all core and instance extension Vulkan commands to the first entity in the chain.
556
557Instance level Vulkan commands are those that have the disapatchable objects VkInstance, or VkPhysicalDevice as the first parameter and alos includes vkCreateInstance.
558Device level Vulkan commands are those that use VkDevice, VkQueue or VkCommandBuffer as the first parameter and also include vkCreateDevice. Future extensions may introduce new instance or device level dispatchable objects, so the above lists may be extended in the future.
559
560#### Discovery of layer entrypoints
561For the layer libraries that have been discovered by the loader, their intercepting entry points that will participate in a device or instance call chain need to be available to the loader or whatever layer is before them in the chain. Layers having the following requirements in this area.
562- A layer intercepting instance level Vulkan commands (aka an instance level layer) must implement a vkGetInstanceProcAddr type of function.
563- This vkGetInstanceProcAddr type function must be exported by the layer library. The name of this function is specified in various ways: 1) the layer manifest JSON file in the "functions", "vkGetInstanceProcAddr" node (Linux/Windows); 2) it is named "vkGetInstanceProcAddr"; 3) it is "<layerName>GetInstanceProcAddr (Android).
564- A layer intercepting device level Vulkan commands (aka a device level layer) must implement a vkGetDeviceProcAddr type of function.
565- This vkGetDeviceProcAddr type function must be exported by the layer library. The name of this function is specified in various ways: 1) the layer manifest JSON file in the "functions", "vkGetDeviceProcAddr" node (Linux/Windows); 2) it is named "vkGetDeviceProcAddr"; 3) it is "<layerName>GetDeviceProcAddr (Android).
566- A layer's vkGetInstanceProcAddr function (irregardless of it's name) must return the local entry points for all instance level Vulkan commands it intercepts. At a minimum, this includes vkGetInstanceProcAddr and vkCreateInstance.
567- A layer's vkGetDeviceProcAddr function (irregardless of it's name) must return the entry points for all device level Vulkan commands it intercepts. At a minimum, this includes vkGetDeviceProcAddr and vkCreateDevice.
568- There are no requirements on the names of the intercepting functions a layer implements except those listed above for vkGetInstanceProcAddr and vkGetDeviceProcAddr.
569- Currently a layer's VkGetInstanceProcAddr must be able to handle a VkInstance parameter equal to NULL for
570instance level commands it intercepts including vkCreateDevice.
571- Currently a layer's VkGetDeviceProcAddr must be able to handle a VkDevice parameter equal to NULL for device level commands it intercepts.
572
573#### Layer intercept requirements
574- Layers intercept a Vulkan command by defining a C/C++ function with signature identical to the Vulkan API for that command.
575- Other than the two vkGet*ProcAddr, all other functions intercepted by a layer need NOT be exported by the layer.
576- For any Vulkan command a layer intercepts which has a non-void return value, an appropriate value must be returned by the layer intercept function.
577- The layer intercept function must call down the chain to the corresponding Vulkan command in the next entity. Undefined results will occur if a layer doesn't propagate calls down the chain. The two exceptions to this requirement are vkGetInstanceProcAddr and vkGetDeviceProcAddr which only call down the chain for Vulkan commands that they do not intercept.
578- Layer intercept functions may insert extra calls to Vulkan commands in addition to the intercept. For example, a layer intercepting vkQueueSubmit may want to add a call to vkQueueWaitIdle after calling down the chain for vkQueueSubmit. Any additional calls inserted by a layer must be on the same chain. They should call down the chain.
579
580#### Distributed dispatching requirements
581- For each entry point a layer intercepts, it must keep track of the entry point residing in the next entity in the chain it will call down into. In other words, the layer must have a list of pointers to functions of the appropriate type to call into the next entity. This can be implemented in various ways but for clarity will be referred to as a dispatch table.
582- A layer can use the VkLayerDispatchTable structure as a device dispatch table (see include/vulkan/vk_layer.h).
583- A layer can use the VkLayerInstanceDispatchTable structure as a instance dispatch table (see include/vulkan/vk_layer.h).
584- Layers vkGetInstanceProcAddr function uses the next entity's vkGetInstanceProcAddr to call down the chain for unknown (ie non-intercepted) functions.
585- Layers vkGetDeviceProcAddr function uses the next entity's vkGetDeviceProcAddr to call down the chain for unknown (ie non-intercepted) functions.
586
587#### Layer dispatch initialization
588- A layer intializes it's instance dispatch table within it's vkCreateInstance function.
589- A layer intializes it's device dispatch table within it's vkCreateDevice function.
590- The loader passes a linked list of initialization structures to layers via the "pNext" field in the VkInstanceCreateInfo and VkDeviceCreateInfo structures for vkCreateInstance and VkCreateDevice respectively.
591- The head node in this linked list is of type VkLayerInstanceCreateInfo for instance and VkLayerDeviceCreateInfo for device. See file include/vulkan/vk_layer.h for details.
592- A VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO is used by the loader for the "sType" field in VkLayerInstanceCreateInfo.
593- A VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO is used by the loader for the "sType" field in VkLayerDeviceCreateInfo.
594- The "function" field indicates how the union field "u" should be interpreted within VkLayer*CreateInfo. The loader will set the "function" field to VK_LAYER_LINK_INFO. This indicates "u" field should be VkLayerInstanceLink or VkLayerDeviceLink.
595- The VkLayerInstanceLink and VkLayerDeviceLink structures are the list nodes.
596- The VkLayerInstanceLink contains the next entity's vkGetInstanceProcAddr used by a layer.
597- The VkLayerDeviceLink contains the next entity's vkGetInstanceProcAddr and vkGetDeviceProcAddr used by a layer.
598- Given the above structures set up by the loader, layer must initialize their dispatch table as follows:
Jon Ashburncc300a22016-02-11 14:57:30 -0700599 - Find the VkLayerInstanceCreateInfo/VkLayerDeviceCreateInfo structure in the VkInstanceCreateInfo/VkDeviceCreateInfo structure.
600 - Get the next entity's vkGet*ProcAddr from the "pLayerInfo" field.
601 - For CreateInstance get the next entity's vkCreateInstance by calling the "pfnNextGetInstanceProcAddr":
Jon Ashburnc2972682016-02-08 15:42:01 -0700602 pfnNextGetInstanceProcAddr(NULL, "vkCreateInstance").
Jon Ashburncc300a22016-02-11 14:57:30 -0700603 - For CreateDevice get the next entity's vkCreateDevice by calling the "pfnNextGetInstanceProcAddr":
Jon Ashburnc2972682016-02-08 15:42:01 -0700604 pfnNextGetInstanceProcAddr(NULL, "vkCreateDevice").
Jon Ashburncc300a22016-02-11 14:57:30 -0700605 - Advanced the linked list to the next node: pLayerInfo = pLayerInfo->pNext.
606 - Call down the chain either CreateDevice or CreateInstance
607 - Initialize your layer dispatch table by calling the next entity's Get*ProcAddr function once for each Vulkan command needed in your dispatch table
608
609Example code for CreateInstance:
610Example code for CreateDevice
611#### Special Considerations
612Wrapping versus maps.
613create dispatchable objects
Jon Ashburnc2972682016-02-08 15:42:01 -0700614