// Version 3 - Add ICD creation/destruction of KHR_surface objects.
// Version 4 - Add unknown physical device extension qyering via
// vk_icdGetPhysicalDeviceProcAddr.
-#define CURRENT_LOADER_ICD_INTERFACE_VERSION 4
+// Version 5 - Tells ICDs that the loader is now paying attention to the
+// application version of Vulkan passed into the ApplicationInfo
+// structure during vkCreateInstance. This will tell the ICD
+// that if the loader is older, it should automatically fail a
+// call for any API version > 1.0. Otherwise, the loader will
+// manually determine if it can support the expected version.
+#define CURRENT_LOADER_ICD_INTERFACE_VERSION 5
#define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0
#define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4
typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion);
##### ABI Versioning
+
The Vulkan loader library will be distributed in various ways including Vulkan
SDKs, OS package distributions and Independent Hardware Vendor (IHV) driver
packages. These details are beyond the scope of this document. However, the name
* [Windows and Linux ICD Negotiation](#windows-and-linux-icd-negotiation)
* [Version Negotiation Between Loader and ICDs](#version-negotiation-between-loader-and-icds)
* [Interfacing With Legacy ICDs or Loader](#interfacing-with-legacy-icds-or-loader)
+ * [Loader Version 5 Interface Requirements](#loader-version-5-interface-requirements)
* [Loader Version 4 Interface Requirements](#loader-version-4-interface-requirements)
* [Loader Version 3 Interface Requirements](#loader-version-3-interface-requirements)
* [Loader Version 2 Interface Requirements](#loader-version-2-interface-requirements)
the loader only supports version 0.
+##### Loader Version 5 Interface Requirements
+
+Version 5 of the loader/ICD interface has no changes to the actual interface.
+If the loader requests interface version 5 or greater, it is simply
+an indication to ICDs that the loader is now evaluating if the API Version info
+passed into vkCreateInstance is a valid version for the loader. If it is not,
+the loader will catch this during vkCreateInstance and fail with a
+VK_ERROR_INCOMPATIBLE_DRIVER error.
+
+On the other hand, if version 5 or newer is not requested by the loader, then it
+indicates to the ICD that the loader is ignorant of the API version being
+requested. Because of this, it falls on the ICD to validate that the API
+Version is not greater than major = 1 and minor = 0. If it is, then the ICD
+should automatically fail with a VK_ERROR_INCOMPATIBLE_DRIVER error since the
+loader is a 1.0 loader, and is unaware of the version.
+
+Here is a table of the expected behaviors:
+
+| Loader Supports I/f Version | ICD Supports I/f Version | Result |
+| :---: |:---:|------------------------|
+| <= 4 | <= 4 | ICD must fail with `VK_ERROR_INCOMPATIBLE_DRIVER` for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0 because both the loader and ICD support interface version <= 4. Otherwise, the ICD should behave as normal. |
+| <= 4 | >= 5 | ICD must fail with `VK_ERROR_INCOMPATIBLE_DRIVER` for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0 because the loader is still at interface version <= 4. Otherwise, the ICD should behave as normal. |
+| >= 5 | <= 4 | Loader will fail with `VK_ERROR_INCOMPATIBLE_DRIVER` if it can't handle the apiVersion. ICD may pass for all apiVersions, but since it's interface is <= 4, it is best if it assumes it needs to do the work of rejecting anything > Vulkan 1.0 and fail with `VK_ERROR_INCOMPATIBLE_DRIVER`. Otherwise, the ICD should behave as normal. |
+| >= 5 | >= 5 | Loader will fail with `VK_ERROR_INCOMPATIBLE_DRIVER` if it can't handle the apiVersion, and ICDs should fail with `VK_ERROR_INCOMPATIBLE_DRIVER` **only if** they can not support the specified apiVersion. Otherwise, the ICD should behave as normal. |
+
##### Loader Version 4 Interface Requirements
The major change to version 4 of the loader/ICD interface is the support of
of discovery.
| Environment Variable | Behavior | Example Format |
-|----------------|---------------------|----------------------|
+|:---:|---------------------|----------------------|
| VK_ICD_FILENAMES | Force the loader to use the specific ICD JSON files. The value should contain a list of delimited full path listings to ICD JSON Manifest files. **NOTE:** If you fail to use the global path to a JSON file, you may encounter issues. | `export VK_ICD_FILENAMES=<folder_a>\intel.json:<folder_b>\amd.json`<br/><br/>`set VK_ICD_FILENAMES=<folder_a>\nvidia.json;<folder_b>\mesa.json` |
| VK_INSTANCE_LAYERS | Force the loader to add the given layers to the list of Enabled layers normally passed into `vkCreateInstance`. These layers are added first, and the loader will remove any duplicate layers that appear in both this list as well as that passed into `ppEnabledLayerNames`. | `export VK_INSTANCE_LAYERS=<layer_a>:<layer_b>`<br/><br/>`set VK_INSTANCE_LAYERS=<layer_a>;<layer_b>` |
| VK_LAYER_PATH | Override the loader's standard Layer library search folders and use the provided delimited folders to search for layer Manifest files. | `export VK_LAYER_PATH=<path_a>:<path_b>`<br/><br/>`set VK_LAYER_PATH=<path_a>;<pathb>` |
## Glossary of Terms
| Field Name | Field Value |
-|----------------|--------------------|
+|:---:|--------------------|
| Android Loader | The loader designed to work primarily for the Android OS. This is generated from a different code-base than the desktop loader. But, in all important aspects, should be functionally equivalent. |
| Desktop Loader | The loader designed to work on both Windows and Linux. This is generated from a different [code-base](#https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers) than the Android loader. But in all important aspects, should be functionally equivalent. |
| Core Function | A function that is already part of the Vulkan core specification and not an extension. For example, vkCreateDevice(). |
bool ext_unsupported = wsi_unsupported_instance_extension(&ext_props[i]);
if (!ext_unsupported) {
- (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_MAJOR(ext_props[i].specVersion),
- VK_MINOR(ext_props[i].specVersion), VK_PATCH(ext_props[i].specVersion));
+ (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_VERSION_MAJOR(ext_props[i].specVersion),
+ VK_VERSION_MINOR(ext_props[i].specVersion), VK_VERSION_PATCH(ext_props[i].specVersion));
loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Instance Extension: %s (%s) version %s", ext_props[i].extensionName,
lib_name, spec_version);
for (i = 0; i < count; i++) {
char spec_version[64];
-
- (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_MAJOR(ext_props[i].specVersion),
- VK_MINOR(ext_props[i].specVersion), VK_PATCH(ext_props[i].specVersion));
+ (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_VERSION_MAJOR(ext_props[i].specVersion),
+ VK_VERSION_MINOR(ext_props[i].specVersion), VK_VERSION_PATCH(ext_props[i].specVersion));
loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Device Extension: %s (%s) version %s", ext_props[i].extensionName,
phys_dev_term->this_icd_term->scanned_icd->lib_name, spec_version);
res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
}
for (i = 0; i < count; i++) {
char spec_version[64];
-
- (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_MAJOR(ext_props[i].specVersion),
- VK_MINOR(ext_props[i].specVersion), VK_PATCH(ext_props[i].specVersion));
+ (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_VERSION_MAJOR(ext_props[i].specVersion),
+ VK_VERSION_MINOR(ext_props[i].specVersion), VK_VERSION_PATCH(ext_props[i].specVersion));
loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Device Extension: %s (%s) version %s", ext_props[i].extensionName,
lib_name, spec_version);
res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
#define DEBUG_DISABLE_APP_ALLOCATORS 0
#define MAX_STRING_SIZE 1024
-#define VK_MAJOR(version) (version >> 22)
-#define VK_MINOR(version) ((version >> 12) & 0x3ff)
-#define VK_PATCH(version) (version & 0xfff)
// This is defined in vk_layer.h, but if there's problems we need to create the define
// here.
loader_platform_thread_once(&once_init, loader_initialize);
+ // Fail if the requested Vulkan apiVersion is > 1.0 since the loader only supports 1.0.
+ // Having pCreateInfo == NULL, pCreateInfo->pApplication == NULL, or
+ // pCreateInfo->pApplicationInfo->apiVersion == 0 all indicate that the application is
+ // only requesting a 1.0 instance, which this loader will always support.
+ uint32_t loader_major_version = 1;
+ uint32_t loader_minor_version = 0;
+ if (NULL != pCreateInfo && NULL != pCreateInfo->pApplicationInfo &&
+ pCreateInfo->pApplicationInfo->apiVersion >= VK_MAKE_VERSION(loader_major_version, loader_minor_version + 1, 0)) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateInstance: Called with invalid API version %d.%d. Loader only supports %d.%d",
+ VK_VERSION_MAJOR(pCreateInfo->pApplicationInfo->apiVersion),
+ VK_VERSION_MINOR(pCreateInfo->pApplicationInfo->apiVersion), loader_major_version, loader_minor_version);
+ res = VK_ERROR_INCOMPATIBLE_DRIVER;
+ goto out;
+ }
+
#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
{
#else