summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Giessen <charles@lunarg.com>2022-05-17 09:51:24 -0600
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2023-01-16 17:23:45 -0700
commit4b705abe08aa99d9848292f1356a4ff55777cba9 (patch)
treea1f97e38d769fb718921dbfe8a8c00945de44cbe
parentdb10d28693766f9312292cdaa7781d63044b8f31 (diff)
downloadVulkan-Loader-4b705abe08aa99d9848292f1356a4ff55777cba9.tar.gz
Vulkan-Loader-4b705abe08aa99d9848292f1356a4ff55777cba9.tar.bz2
Vulkan-Loader-4b705abe08aa99d9848292f1356a4ff55777cba9.zip
Add Vulkan Loader and Driver Interface Version 7
The changes made by Version 7 are as follows. If a Driver supports any of the following functions, they must be exposed by with vk_icdGetInstanceProcAddr: * vk_icdNegotiateLoaderICDInterfaceVersion * vk_icdGetPhysicalDeviceProcAddr * vk_icdEnumerateAdapterPhysicalDevices (Windows only) This makes it optional for a driver to export these functions. Drivers may still export them for compatibility with older loaders. Loader and Driver Interface Version 7 allows for drivers provided through the VK_LUNARG_direct_driver_loading extension to support the entire Loader and Driver Interface. This commit makes many small fixes to the documentation. Main changes are adding Version 7 of the Loader and Driver Interface, clarifies when the functions associated with this version must be exported, when they can be optionally exported and when they must be exposed through vk_icdGetInstanceProcAddr. This also clarifies LDP_DRIVER_10 to note the exact behavior of drivers that is disallowed. In the process of these documentation changes, the glossary was amended with definitions for Exported Functions, Exposed Functions, and Querying Functions.
-rw-r--r--docs/LoaderDriverInterface.md201
-rw-r--r--docs/LoaderInterfaceArchitecture.md29
-rw-r--r--loader/loader.c59
-rw-r--r--tests/framework/framework_config.h.in4
-rw-r--r--tests/framework/icd/CMakeLists.txt7
-rw-r--r--tests/framework/icd/export_definitions/test_icd_7.def3
-rw-r--r--tests/framework/icd/export_definitions/test_icd_7_with_exports.def6
-rw-r--r--tests/framework/icd/test_icd.cpp117
-rw-r--r--tests/framework/icd/test_icd.h40
-rw-r--r--tests/loader_version_tests.cpp29
-rw-r--r--tests/loader_wsi_tests.cpp7
11 files changed, 351 insertions, 151 deletions
diff --git a/docs/LoaderDriverInterface.md b/docs/LoaderDriverInterface.md
index 8c6f7b0a..f7f501fc 100644
--- a/docs/LoaderDriverInterface.md
+++ b/docs/LoaderDriverInterface.md
@@ -38,7 +38,7 @@
- [Using Pre-Production ICDs or Software Drivers](#using-pre-production-icds-or-software-drivers)
- [Driver Discovery on Android](#driver-discovery-on-android)
- [Driver Manifest File Format](#driver-manifest-file-format)
- - [Driver Manifest File Versions](#driver-manifest-file-versions)
+ - [Driver Manifest File Versions](#driver-manifest-file-versions)
- [Driver Manifest File Version 1.0.0](#driver-manifest-file-version-100)
- [Driver Manifest File Version 1.0.1](#driver-manifest-file-version-101)
- [Driver Vulkan Entry Point Discovery](#driver-vulkan-entry-point-discovery)
@@ -53,18 +53,19 @@
- [Handling KHR Surface Objects in WSI Extensions](#handling-khr-surface-objects-in-wsi-extensions)
- [Loader and Driver Interface Negotiation](#loader-and-driver-interface-negotiation)
- [Windows, Linux and macOS Driver Negotiation](#windows-linux-and-macos-driver-negotiation)
- - [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers)
+ - [Version Negotiation Between the Loader and Drivers](#version-negotiation-between-the-loader-and-drivers)
- [Interfacing With Legacy Drivers or Loaders](#interfacing-with-legacy-drivers-or-loaders)
- - [Loader Version 6 Interface Requirements](#loader-version-6-interface-requirements)
- - [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)
- - [Loader Version 1 Interface Requirements](#loader-version-1-interface-requirements)
- - [Loader Version 0 Interface Requirements](#loader-version-0-interface-requirements)
+ - [Loader and Driver Interface Version 7 Requirements](#loader-and-driver-interface-version-7-requirements)
+ - [Loader and Driver Interface Version 6 Requirements](#loader-and-driver-interface-version-6-requirements)
+ - [Loader and Driver Interface Version 5 Requirements](#loader-and-driver-interface-version-5-requirements)
+ - [Loader and Driver Interface Version 4 Requirements](#loader-and-driver-interface-version-4-requirements)
+ - [Loader and Driver Interface Version 3 Requirements](#loader-and-driver-interface-version-3-requirements)
+ - [Loader and Driver Interface Version 2 Requirements](#loader-and-driver-interface-version-2-requirements)
+ - [Loader and Driver Interface Version 1 Requirements](#loader-and-driver-interface-version-1-requirements)
+ - [Loader and Driver Interface Version 0 Requirements](#loader-and-driver-interface-version-0-requirements)
- [Additional Interface Notes:](#additional-interface-notes)
- [Android Driver Negotiation](#android-driver-negotiation)
-- [Loader implementation of VK_KHR_portability_enumeration](#loader-implementation-of-vk_khr_portability_enumeration)
+- [Loader implementation of VK\_KHR\_portability\_enumeration](#loader-implementation-of-vk_khr_portability_enumeration)
- [Loader and Driver Policy](#loader-and-driver-policy)
- [Number Format](#number-format)
- [Android Differences](#android-differences)
@@ -813,11 +814,17 @@ missing support for this extension.
## Driver Unknown Physical Device Extensions
Drivers that implement entrypoints which take a `VkPhysicalDevice` as the first
-parameter *should* support `vk_icdGetPhysicalDeviceProcAddr`. This function
-is added to the Driver Interface Version 4 and allows the loader to distinguish
-between entrypoints which take `VkDevice` and `VkPhysicalDevice` as the first
-parameter. This allows the loader to properly support entrypoints that are
-unknown to it gracefully.
+parameter *should* support `vk_icdGetPhysicalDeviceProcAddr`.
+This function is added to the Loader and Driver Driver Interface Version 4,
+allowing the loader to distinguish between entrypoints which take `VkDevice`
+and `VkPhysicalDevice` as the first parameter.
+This allows the loader to properly support entrypoints that are unknown to it
+gracefully.
+This entry point is not a part of the Vulkan API itself, only a private
+interface between the loader and drivers.
+Note: Loader and Driver Interface Version 7 makes exporting
+`vk_icdGetPhysicalDeviceProcAddr` optional.
+Instead, drivers *must* expose it through `vk_icdGetInstanceProcAddr`.
```cpp
PFN_vkVoidFunction
@@ -853,7 +860,9 @@ function.
If a driver does implement this support, it must export the function from the
driver library using the name `vk_icdGetPhysicalDeviceProcAddr` so that the
-symbol can be located through the platform's dynamic linking utilities.
+symbol can be located through the platform's dynamic linking utilities, or if
+the driver supports Loader and Driver Interface Version 7, exposed through
+`vk_icdGetInstanceProcAddr` instead.
The behavior of the loader's `vkGetInstanceProcAddr` with support for the
`vk_icdGetPhysicalDeviceProcAddr` function is as follows:
@@ -919,10 +928,15 @@ preference will be listed first.
This mechanism does not force an application to use any particular GPU &mdash;
it merely changes the order in which they are presented.
-This mechanism requires that a driver provide version 6 of the loader/driver
-interface.
-Version 6 of this interface defines a new exported function that the driver may
-provide on Windows:
+This mechanism requires that a driver provide The Loader and Driver Interface
+Version 6.
+This version defines a new exported function, `vk_icdEnumerateAdapterPhysicalDevices`,
+detailed below, that Drivers may provide on Windows.
+This entry point is not a part of the Vulkan API itself, only a private
+interface between the loader and drivers.
+Note: Loader and Driver Interface Version 7 makes exporting
+`vk_icdEnumerateAdapterPhysicalDevices` optional.
+Instead, drivers *must* expose it through `vk_icdGetInstanceProcAddr`.
```c
VKAPI_ATTR VkResult VKAPI_CALL
@@ -933,6 +947,7 @@ VKAPI_ATTR VkResult VKAPI_CALL
VkPhysicalDevice* pPhysicalDevices);
```
+
This function takes an adapter LUID as input, and enumerates all Vulkan physical
devices that are associated with that LUID.
This works in the same way as other Vulkan enumerations &mdash; if
@@ -1045,8 +1060,8 @@ appropriate `VkIcdSurfaceXXX` structure.
The driver may choose to handle `VkSurfaceKHR` object creation instead.
If a driver desires to handle creating and destroying it must do the following:
- 1. Support version 3 or newer of the loader/driver interface.
- 2. Export and handle all functions that take in a `VkSurfaceKHR` object,
+ 1. Support Loader and Driver Interface Version 3 or newer.
+ 2. Expose and handle all functions that take in a `VkSurfaceKHR` object,
including:
* `vkCreateXXXSurfaceKHR`
* `vkGetPhysicalDeviceSurfaceSupportKHR`
@@ -1089,13 +1104,16 @@ These additional requirements are versioned to allow flexibility in the future.
### Windows, Linux and macOS Driver Negotiation
-#### Version Negotiation Between Loader and Drivers
+#### Version Negotiation Between the Loader and Drivers
-All drivers (supporting interface version 2 or higher) must export the
-following function that is used for determination of the interface version that
-will be used.
+All drivers supporting Loader and Driver Interface Version 2 or higher must
+export the following function that is used for determination of the interface
+version that will be used.
This entry point is not a part of the Vulkan API itself, only a private
interface between the loader and drivers.
+Note: Loader and Driver Interface Version 7 makes exporting
+`vk_icdGetInstanceProcAddr` optional.
+Instead, drivers *must* expose it through `vk_icdGetInstanceProcAddr`.
```cpp
VKAPI_ATTR VkResult VKAPI_CALL
@@ -1139,19 +1157,50 @@ during enumeration.
#### Interfacing With Legacy Drivers or Loaders
-If a loader sees that a driver does not export the
+If a loader sees that a driver does not export or expose the
`vk_icdNegotiateLoaderICDInterfaceVersion` function, then the loader assumes the
corresponding driver only supports either interface version 0 or 1.
From the other side of the interface, if a driver sees a call to
`vk_icdGetInstanceProcAddr` before a call to
-`vk_icdNegotiateLoaderICDInterfaceVersion`, then it knows that loader making the
-calls is a legacy loader supporting version 0 or 1.
-If the loader calls `vk_icdGetInstanceProcAddr` first, it supports at least
-version 1.
+`vk_icdNegotiateLoaderICDInterfaceVersion`, then the loader is either a legacy
+loader with only support for interface version 0 or 1, or the loader is using
+interface version 7 or newer.
+
+If the first call to `vk_icdGetInstanceProcAddr` is to query for
+`vk_icdNegotiateLoaderICDInterfaceVersion`, then that means the loader is using
+interface version 7.
+This only occurs when the driver does not export
+`vk_icdNegotiateLoaderICDInterfaceVersion`.
+Drivers which export `vk_icdNegotiateLoaderICDInterfaceVersion` will have it
+called first.
+
+If the first call to `vk_icdGetInstanceProcAddr` is **not** querying for
+`vk_icdNegotiateLoaderICDInterfaceVersion`, then loader is a legacy loader only
+which supports version 0 or 1.
+In this case, if the loader calls `vk_icdGetInstanceProcAddr` first, it supports
+at least interface version 1.
Otherwise, the loader only supports version 0.
-#### Loader Version 6 Interface Requirements
+#### Loader and Driver Interface Version 7 Requirements
+
+Version 7 relaxes the requirement that Loader and Driver Interface functions
+must be exported.
+Instead, it only requires that those functions be queryable through
+`vk_icdGetInstanceProcAddr`.
+The functions are:
+ `vk_icdNegotiateLoaderICDInterfaceVersion`
+ `vk_icdGetPhysicalDeviceProcAddr`
+ `vk_icdEnumerateAdapterPhysicalDevices` (Windows only)
+These functions are considered global for the purposes of retrieval, so the
+`VkInstance` parameter of `vk_icdGetInstanceProcAddr` will be **NULL**.
+While exporting these functions is no longer a requirement, drivers may still
+export them for compatibility with older loaders.
+The changes in this version allow drivers provided through the
+`VK_LUNARG_direct_driver_loading` extension to support the entire Loader and
+Driver Interface.
+
+#### Loader and Driver Interface Version 6 Requirements
Version 6 provides a mechanism to allow the loader to sort physical devices.
The loader will only attempt to sort physical devices on a driver if version 6
@@ -1159,9 +1208,9 @@ of the interface is supported.
This version provides the `vk_icdEnumerateAdapterPhysicalDevices` function
defined earlier in this document.
-#### Loader Version 5 Interface Requirements
+#### Loader and Driver Interface Version 5 Requirements
-Version 5 of the loader/driver interface has no changes to the actual interface.
+This interface version has no changes to the actual interface.
If the loader requests interface version 5 or greater, it is simply
an indication to drivers that the loader is now evaluating whether the API
Version info passed into vkCreateInstance is a valid version for the loader.
@@ -1218,10 +1267,9 @@ Here is a table of the expected behaviors:
</tr>
</table>
-#### Loader Version 4 Interface Requirements
+#### Loader and Driver Interface Version 4 Requirements
-The major change to version 4 of the loader/driver interface is the
-support of
+The major change to version 4 of this interface version is the support of
[Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions)
using the `vk_icdGetPhysicalDeviceProcAddr` function.
This function is purely optional.
@@ -1231,16 +1279,16 @@ Otherwise, the loader will continue to treat any unknown functions as VkDevice
functions and cause invalid behavior.
-#### Loader Version 3 Interface Requirements
+#### Loader and Driver Interface Version 3 Requirements
-The primary change that occurred in version 3 of the loader/driver interface was
-to allow a driver to handle creation/destruction of their own KHR_surfaces.
+The primary change that occurred in this interface version is to allow a driver
+to handle creation and destruction of their own KHR_surfaces.
Up until this point, the loader created a surface object that was used by all
drivers.
-However, some drivers may want to provide their own surface handles.
-If a driver chooses to enable this support, it must export support for version 3
-of the loader/driver interface, as well as any Vulkan function that uses a
-KHR_surface handle, such as:
+However, some drivers *may* want to provide their own surface handles.
+If a driver chooses to enable this support, it must support Loader and Driver
+Interface Version 3, as well as any Vulkan function that uses a `VkSurfaceKHR`
+handle, such as:
- `vkCreateXXXSurfaceKHR` (where XXX is the platform-specific identifier [i.e.
`vkCreateWin32SurfaceKHR` for Windows])
- `vkDestroySurfaceKHR`
@@ -1250,25 +1298,24 @@ KHR_surface handle, such as:
- `vkGetPhysicalDeviceSurfaceFormatsKHR`
- `vkGetPhysicalDeviceSurfacePresentModesKHR`
-A driver can still choose to not take advantage of this functionality
-by simply not exposing the above `vkCreateXXXSurfaceKHR` and
+A driver which does not participate in this functionality can opt out by
+simply not exposing the above `vkCreateXXXSurfaceKHR` and
`vkDestroySurfaceKHR` functions.
-#### Loader Version 2 Interface Requirements
+#### Loader and Driver Interface Version 2 Requirements
-Version 2 interface is the first to implement the new
-`vk_icdNegotiateLoaderICDInterfaceVersion` functionality, see
-[Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers) for more details
-on that function.
+Interface Version 2 requires that drivers export
+`vk_icdNegotiateLoaderICDInterfaceVersion`.
+For more information, see [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers).
-Additional, version 2 was the first to define that Vulkan dispatchable objects
-created by drivers must now be created in accordance to the
+Additional, version 2 requires that Vulkan dispatchable objects created by
+drivers must be created in accordance to the
[Driver Dispatchable Object Creation](#driver-dispatchable-object-creation)
section.
-#### Loader Version 1 Interface Requirements
+#### Loader and Driver Interface Version 1 Requirements
Version 1 of the interface added the driver-specific entry-point
`vk_icdGetInstanceProcAddr`.
@@ -1283,14 +1330,14 @@ No other entry-points need to be exported by the driver as the loader will query
the appropriate function pointers using that.
-#### Loader Version 0 Interface Requirements
+#### Loader and Driver Interface Version 0 Requirements
-Version 0 interface does not support either `vk_icdGetInstanceProcAddr` or
+Version 0 does not support either `vk_icdGetInstanceProcAddr` or
`vk_icdNegotiateLoaderICDInterfaceVersion`.
Because of this, the loader will assume the driver supports only version 0 of
the interface unless one of those functions exists.
-Additionally, for version 0, the driver must expose at least the following core
+Additionally, for Version 0, the driver must expose at least the following core
Vulkan entry-points so the loader may build up the interface to the driver:
- The function `vkGetInstanceProcAddr` **must be exported** in the driver
@@ -1372,8 +1419,8 @@ best experience to end-users and developers.
### Number Format
-Loader/Driver policy items start with the prefix `LDP_` (short for
-Loader/Driver Policy) which is followed by an identifier based on what
+Loader and Driver policy items start with the prefix `LDP_` (short for
+Loader and Driver Policy) which is followed by an identifier based on what
component the policy is targeted against.
In this case there are only two possible components:
- Drivers: which will have the string `DRIVER_` as part of the policy number.
@@ -1435,7 +1482,7 @@ Android Vulkan documentation</a>.
<tr>
<td><small><b>LDP_DRIVER_3</b></small></td>
<td>A driver <b>must</b> be able to negotiate a supported version of the
- loader/driver interface with the loader in accordance with the stated
+ Loader and Driver Interface with the loader in accordance with the stated
negotiation process.
</td>
<td>The driver will not be loaded.</td>
@@ -1495,7 +1542,7 @@ Android Vulkan documentation</a>.
<tr>
<td><small><b>LDP_DRIVER_7</b></small></td>
<td>If a driver desires to support Vulkan API 1.1 or newer, it <b>must</b>
- expose support of Vulkan loader/driver interface 5 or newer.
+ expose support for Loader and Driver Interface Version 5 or newer.
</td>
<td>The driver will be used when it shouldn't be and will cause
undefined behavior possibly including crashes or corruption.
@@ -1510,7 +1557,7 @@ Android Vulkan documentation</a>.
<tr>
<td><small><b>LDP_DRIVER_8</b></small></td>
<td>If a driver wishes to handle its own <i>VkSurfaceKHR</i> object
- creation, it <b>must</b> implement loader/driver interface version 3 or
+ creation, it <b>must</b> implement the Loader and Driver Interface Version 3 or
newer and support querying all the relevant surface functions via
<i>vk_icdGetInstanceProcAddr</i>.
</td>
@@ -1524,15 +1571,15 @@ Android Vulkan documentation</a>.
</tr>
<tr>
<td><small><b>LDP_DRIVER_9</b></small></td>
- <td>If a driver negotiation results in it using loader/driver interface
- version 4 or earlier, the driver <b>must</b> verify that the Vulkan API
- version passed into <i>vkCreateInstance</i> (through
+ <td>If version negotiation results in a driver using the Loader
+ and Driver Interface Version 4 or earlier, the driver <b>must</b> verify
+ that the Vulkan API version passed into <i>vkCreateInstance</i> (through
<i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
<i>apiVersion</i>) is supported.
If the requested Vulkan API version can not be supported by the driver,
it <b>must</b> return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>. <br/>
This is not required if the interface version is 5 or newer because the
- responsibility for this check then falls on the loader.
+ loader is responsible for this check.
</td>
<td>The behavior is undefined and may result in crashes or corruption.</td>
<td>No</td>
@@ -1544,11 +1591,13 @@ Android Vulkan documentation</a>.
</tr>
<tr>
<td><small><b>LDP_DRIVER_10</b></small></td>
- <td>If a driver negotiation results in it using loader/driver interface
- version 5 or newer, the driver <b>must</b> ignore the Vulkan API version
+ <td>If version negotiation results in a driver using the Loader and Driver Interface
+ Version 5 or newer, the driver <b>must</b> not return
+ <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if the Vulkan API version
passed into <i>vkCreateInstance</i> (through
<i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
- <i>apiVersion</i>).
+ <i>apiVersion</i>) is not supported by the driver. This check is performed
+ by the loader on the drivers behalf.
</td>
<td>The behavior is undefined and may result in crashes or corruption.</td>
<td>No</td>
@@ -1607,7 +1656,7 @@ They are documented here for reference.
</tr>
<tr>
<td><small><b>LDP_DRIVER_6</b></small></td>
- <td>A driver supporting loader/driver interface version 1 or newer <b>must
+ <td>A driver supporting Loader and Driver Interface Version 1 or newer <b>must
not</b> directly export standard Vulkan entry-points.
<br/>
Instead, it <b>must</b> export only the loader interface functions
@@ -1693,7 +1742,7 @@ They are documented here for reference.
<tr>
<td><small><b>LDP_LOADER_5</b></small></td>
<td>A loader <b>must</b> ignore any driver for which a compatible
- loader/driver interface version can not be negotiated.
+ Loader and Driver Interface Version can not be negotiated.
</td>
<td>The loader would load a driver improperly resulting in undefined
behavior possibly including crashes or corruption.
@@ -1706,16 +1755,16 @@ They are documented here for reference.
</tr>
<tr>
<td><small><b>LDP_LOADER_6</b></small></td>
- <td>If a driver negotiation results in it using loader/driver interface
- version 5 or newer, a loader <b>must</b> verify that the Vulkan API
- version passed into <i>vkCreateInstance</i> (through
+ <td>If a driver negotiation results in the loader using Loader and Driver
+ Interface Version 5 or newer, a loader <b>must</b> verify that the Vulkan
+ API version passed into <i>vkCreateInstance</i> (through
<i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
<i>apiVersion</i>) is supported by at least one driver.
If the requested Vulkan API version can not be supported by any
driver, the loader <b>must</b> return
<b>VK_ERROR_INCOMPATIBLE_DRIVER</b>.<br/>
- This is not required if the interface version is 4 or earlier because
- the responsibility for this check then falls on the drivers.
+ This is not required if the Loader and Driver Interface Version is 4 or
+ earlier because the responsibility for this check falls on the drivers.
</td>
<td>The behavior is undefined and may result in crashes or corruption.</td>
<td>No</td>
diff --git a/docs/LoaderInterfaceArchitecture.md b/docs/LoaderInterfaceArchitecture.md
index 8c203b82..d3dd181c 100644
--- a/docs/LoaderInterfaceArchitecture.md
+++ b/docs/LoaderInterfaceArchitecture.md
@@ -47,6 +47,8 @@
- [Case-Insensitive](#case-insensitive)
- [Environment Variable Priority](#environment-variable-priority)
- [Table of Debug Environment Variables](#table-of-debug-environment-variables)
+ - [Active Environment Variables](#active-environment-variables)
+ - [Deprecated Environment Variables](#deprecated-environment-variables)
- [Glossary of Terms](#glossary-of-terms)
## Overview
@@ -1190,4 +1192,31 @@ may be removed in a future loader release.
for more information.
</td>
</tr>
+ <tr>
+ <td>Exported Function</td>
+ <td>A function which is intended to be obtained through the platform specific
+ dynamic linker, specifically from a Driver or a Layer library.
+ Functions that are required to be exported are primarily the very first
+ functions the Loader calls on a Layer or Driver library. <br/>
+ </td>
+ </tr>
+ <tr>
+ <td>Exposed Function</td>
+ <td>A function which is intended to be obtained through a Querying Function, such as
+ `vkGetInstanceProcAddr`.
+ The exact Querying Function required for a specific exposed function varies
+ between Layers and Drivers, as well as between interface versions. <br/>
+ </td>
+ </tr>
+ <tr>
+ <td>Querying Functions</td>
+ <td>These are functions which allow the Loader to query other functions from
+ drivers and layers. These functions may be in the Vulkan API but also may be
+ from the private Loader and Driver Interface or the Loader and Layer Interface. <br/>
+ These functions are:
+ `vkGetInstanceProcAddr`, `vkGetDeviceProcAddr`,
+ `vk_icdGetInstanceProcAddr`, `vk_icdGetPhysicalDeviceProcAddr`, and
+ `vk_layerGetPhysicalDeviceProcAddr`.
+ </td>
+ </tr>
</table>
diff --git a/loader/loader.c b/loader/loader.c
index bf51d3c2..2a150485 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -1351,11 +1351,11 @@ static VkResult loader_scanned_icd_init(const struct loader_instance *inst, stru
static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
const char *filename, uint32_t api_version, enum loader_layer_library_status *lib_status) {
loader_platform_dl_handle handle = NULL;
- PFN_vkCreateInstance fp_create_inst;
- PFN_vkEnumerateInstanceExtensionProperties fp_get_inst_ext_props;
- PFN_vkGetInstanceProcAddr fp_get_proc_addr;
+ PFN_vkCreateInstance fp_create_inst = NULL;
+ PFN_vkEnumerateInstanceExtensionProperties fp_get_inst_ext_props = NULL;
+ PFN_vkGetInstanceProcAddr fp_get_proc_addr = NULL;
PFN_GetPhysicalDeviceProcAddr fp_get_phys_dev_proc_addr = NULL;
- PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version;
+ PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version = NULL;
#if defined(VK_USE_PLATFORM_WIN32_KHR)
PFN_vk_icdEnumerateAdapterPhysicalDevices fp_enum_dxgi_adapter_phys_devs = NULL;
#endif
@@ -1389,9 +1389,25 @@ static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struc
goto out;
}
- // Get and settle on an ICD interface version
+ // Try to load the driver's exported vk_icdNegotiateLoaderICDInterfaceVersion
fp_negotiate_icd_version = loader_platform_get_proc_address(handle, "vk_icdNegotiateLoaderICDInterfaceVersion");
+ // If it isn't exported, we are dealing with either a v0, v1, or a v7 and up driver
+ if (NULL == fp_negotiate_icd_version) {
+ // Try to load the driver's exported vk_icdGetInstanceProcAddr - if this is a v7 or up driver, we can use it to get
+ // the driver's vk_icdNegotiateLoaderICDInterfaceVersion function
+ fp_get_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetInstanceProcAddr");
+
+ // If we successfully loaded vk_icdGetInstanceProcAddr, try to get vk_icdNegotiateLoaderICDInterfaceVersion
+ if (fp_get_proc_addr) {
+ fp_negotiate_icd_version =
+ (PFN_vk_icdNegotiateLoaderICDInterfaceVersion)fp_get_proc_addr(NULL, "vk_icdNegotiateLoaderICDInterfaceVersion");
+ }
+ }
+
+ // Try to negotiate the Loader and Driver Interface Versions
+ // loader_get_icd_interface_version will check if fp_negotiate_icd_version is NULL, so we don't have to.
+ // If it *is* NULL, that means this driver uses interface version 0 or 1
if (!loader_get_icd_interface_version(fp_negotiate_icd_version, &interface_vers)) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
"loader_scanned_icd_add: ICD %s doesn't support interface version compatible with loader, skip this ICD.",
@@ -1399,13 +1415,19 @@ static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struc
goto out;
}
- fp_get_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetInstanceProcAddr");
+ // If we didn't already query vk_icdGetInstanceProcAddr, try now
+ if (NULL == fp_get_proc_addr) {
+ fp_get_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetInstanceProcAddr");
+ }
+
+ // If vk_icdGetInstanceProcAddr is NULL, this ICD is using version 0 and so we should respond accordingly.
if (NULL == fp_get_proc_addr) {
+ // Exporting vk_icdNegotiateLoaderICDInterfaceVersion but not vk_icdGetInstanceProcAddr violates Version 2's requirements,
+ // as for Version 2 to be supported Version 1 must also be supported
if (interface_vers != 0) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
"loader_scanned_icd_add: ICD %s reports an interface version of %d but doesn't export "
- "vk_icdGetInstanceProcAddr, skip "
- "this ICD.",
+ "vk_icdGetInstanceProcAddr, skip this ICD.",
filename, interface_vers);
goto out;
}
@@ -1438,7 +1460,8 @@ static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struc
goto out;
}
} else {
- // Use newer interface version 1 or later
+ // vk_icdGetInstanceProcAddr was successfully found, we can assume the version is at least one
+ // If vk_icdNegotiateLoaderICDInterfaceVersion was also found, interface_vers must be 2 or greater, so this check is fine
if (interface_vers == 0) {
interface_vers = 1;
}
@@ -1459,9 +1482,23 @@ static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struc
filename);
goto out;
}
- fp_get_phys_dev_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetPhysicalDeviceProcAddr");
+ // Query "vk_icdGetPhysicalDeviceProcAddr" with vk_icdGetInstanceProcAddr if the library reports interface version 7 or
+ // greater, otherwise fallback to loading it from the platform dynamic linker
+ if (interface_vers >= 7) {
+ fp_get_phys_dev_proc_addr =
+ (PFN_vk_icdGetPhysicalDeviceProcAddr)fp_get_proc_addr(NULL, "vk_icdGetPhysicalDeviceProcAddr");
+ }
+ if (NULL == fp_get_phys_dev_proc_addr && interface_vers >= 3) {
+ fp_get_phys_dev_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetPhysicalDeviceProcAddr");
+ }
#if defined(VK_USE_PLATFORM_WIN32_KHR)
- if (interface_vers >= 6) {
+ // Query "vk_icdEnumerateAdapterPhysicalDevices" with vk_icdGetInstanceProcAddr if the library reports interface version 7
+ // or greater, otherwise fallback to loading it from the platform dynamic linker
+ if (interface_vers >= 7) {
+ fp_enum_dxgi_adapter_phys_devs =
+ (PFN_vk_icdEnumerateAdapterPhysicalDevices)fp_get_proc_addr(NULL, "vk_icdEnumerateAdapterPhysicalDevices");
+ }
+ if (NULL == fp_enum_dxgi_adapter_phys_devs && interface_vers >= 6) {
fp_enum_dxgi_adapter_phys_devs = loader_platform_get_proc_address(handle, "vk_icdEnumerateAdapterPhysicalDevices");
}
#endif
diff --git a/tests/framework/framework_config.h.in b/tests/framework/framework_config.h.in
index e7abe0dc..f7b8bf07 100644
--- a/tests/framework/framework_config.h.in
+++ b/tests/framework/framework_config.h.in
@@ -55,6 +55,10 @@
// All possible defines for v6
#define TEST_ICD_PATH_VERSION_6 "$<TARGET_FILE:test_icd_version_6>"
+// Version 7
+#define TEST_ICD_PATH_VERSION_7 "$<TARGET_FILE:test_icd_version_7>"
+#define TEST_ICD_PATH_VERSION_7_WITH_ADDITIONAL_EXPORTS "$<TARGET_FILE:test_icd_version_7_with_additional_exports>"
+
// TestLayer binaries
#define TEST_LAYER_PATH_EXPORT_BASE "$<TARGET_FILE:test_layer_export_base>"
#define TEST_LAYER_PATH_EXPORT_VERSION_0 "$<TARGET_FILE:test_layer_export_version_0>"
diff --git a/tests/framework/icd/CMakeLists.txt b/tests/framework/icd/CMakeLists.txt
index 9deb6d42..cd205936 100644
--- a/tests/framework/icd/CMakeLists.txt
+++ b/tests/framework/icd/CMakeLists.txt
@@ -39,6 +39,13 @@ AddSharedLibrary(test_icd_version_2_export_icd_gpdpa DEF_FILE test_icd_2_gpdpa
AddSharedLibrary(test_icd_version_6 DEF_FILE test_icd_6
SOURCES test_icd.cpp
DEFINITIONS TEST_ICD_EXPORT_ICD_GPDPA=1 TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 ${TEST_ICD_VERSION_2_DEFINES})
+AddSharedLibrary(test_icd_version_7 DEF_FILE test_icd_7
+ SOURCES test_icd.cpp
+ DEFINITIONS TEST_ICD_EXPOSE_VERSION_7=1 ${TEST_ICD_VERSION_2_DEFINES})
+AddSharedLibrary(test_icd_version_7_with_additional_exports DEF_FILE test_icd_7_with_exports
+ SOURCES test_icd.cpp
+ DEFINITIONS TEST_ICD_EXPOSE_VERSION_7=1 TEST_ICD_EXPORT_ICD_GPDPA=1
+ TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 ${TEST_ICD_VERSION_2_DEFINES})
add_custom_command(TARGET test_icd_version_2 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
diff --git a/tests/framework/icd/export_definitions/test_icd_7.def b/tests/framework/icd/export_definitions/test_icd_7.def
new file mode 100644
index 00000000..4414bbea
--- /dev/null
+++ b/tests/framework/icd/export_definitions/test_icd_7.def
@@ -0,0 +1,3 @@
+LIBRARY test_icd_version_7
+EXPORTS
+ vk_icdGetInstanceProcAddr
diff --git a/tests/framework/icd/export_definitions/test_icd_7_with_exports.def b/tests/framework/icd/export_definitions/test_icd_7_with_exports.def
new file mode 100644
index 00000000..78618057
--- /dev/null
+++ b/tests/framework/icd/export_definitions/test_icd_7_with_exports.def
@@ -0,0 +1,6 @@
+LIBRARY test_icd_version_7_with_additional_exports
+EXPORTS
+ vk_icdGetInstanceProcAddr
+ vk_icdNegotiateLoaderICDInterfaceVersion
+ vk_icdEnumerateAdapterPhysicalDevices
+ vk_icdGetPhysicalDeviceProcAddr
diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp
index 079e8065..b1743553 100644
--- a/tests/framework/icd/test_icd.cpp
+++ b/tests/framework/icd/test_icd.cpp
@@ -47,6 +47,12 @@
#define TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES 0
#endif
+// expose vk_icdNegotiateLoaderICDInterfaceVersion, vk_icdEnumerateAdapterPhysicalDevices, and vk_icdGetPhysicalDeviceProcAddr
+// through vk_icdGetInstanceProcAddr or vkGetInstanceProcAddr
+#ifndef TEST_ICD_EXPOSE_VERSION_7
+#define TEST_ICD_EXPOSE_VERSION_7 0
+#endif
+
TestICD icd;
extern "C" {
FRAMEWORK_EXPORT TestICD* get_test_icd_func() { return &icd; }
@@ -1033,6 +1039,56 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkGetCalibratedTimestampsEXT(VkDevice device
return VK_SUCCESS;
}
+#if defined(WIN32)
+VKAPI_ATTR VkResult VKAPI_CALL test_vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
+ uint32_t* pPhysicalDeviceCount,
+ VkPhysicalDevice* pPhysicalDevices) {
+ if (adapterLUID.LowPart != icd.adapterLUID.LowPart || adapterLUID.HighPart != icd.adapterLUID.HighPart) {
+ *pPhysicalDeviceCount = 0;
+ return VK_SUCCESS;
+ }
+ icd.called_enumerate_adapter_physical_devices = true;
+ VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+ // For this testing, flip order intentionally
+ if (nullptr != pPhysicalDevices) {
+ std::reverse(pPhysicalDevices, pPhysicalDevices + *pPhysicalDeviceCount);
+ }
+ return res;
+}
+#endif // defined(WIN32)
+
+VkResult test_vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
+ if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called &&
+ icd.called_negotiate_interface == CalledNegotiateInterface::not_called)
+ icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_negotiate;
+ else if (icd.called_vk_icd_gipa != CalledICDGIPA::not_called)
+ icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_gipa_first;
+
+ // loader puts the minimum it supports in pSupportedVersion, if that is lower than our minimum
+ // If the ICD doesn't supports the interface version provided by the loader, report VK_ERROR_INCOMPATIBLE_DRIVER
+ if (icd.min_icd_interface_version > *pSupportedVersion) {
+ icd.interface_version_check = InterfaceVersionCheck::loader_version_too_old;
+ *pSupportedVersion = icd.min_icd_interface_version;
+ return VK_ERROR_INCOMPATIBLE_DRIVER;
+ }
+
+ // the loader-provided interface version is newer than that supported by the ICD
+ if (icd.max_icd_interface_version < *pSupportedVersion) {
+ icd.interface_version_check = InterfaceVersionCheck::loader_version_too_new;
+ *pSupportedVersion = icd.max_icd_interface_version;
+ }
+ // ICD interface version is greater than the loader's, return the loader's version
+ else if (icd.max_icd_interface_version > *pSupportedVersion) {
+ icd.interface_version_check = InterfaceVersionCheck::icd_version_too_new;
+ // don't change *pSupportedVersion
+ } else {
+ icd.interface_version_check = InterfaceVersionCheck::version_is_supported;
+ *pSupportedVersion = icd.max_icd_interface_version;
+ }
+
+ return VK_SUCCESS;
+}
+
//// trampolines
PFN_vkVoidFunction get_instance_func_ver_1_1(VkInstance instance, const char* pName) {
@@ -1093,7 +1149,7 @@ PFN_vkVoidFunction get_instance_func_wsi(VkInstance instance, const char* pName)
if (icd.min_icd_interface_version >= 3 && icd.enable_icd_wsi == true) {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
if (string_eq(pName, "vkCreateAndroidSurfaceKHR")) {
- icd.is_using_icd_wsi = UsingICDProvidedWSI::is_using;
+ icd.is_using_icd_wsi = true;
return to_vkVoidFunction(test_vkCreateAndroidSurfaceKHR);
}
#endif
@@ -1175,7 +1231,7 @@ PFN_vkVoidFunction get_instance_func_wsi(VkInstance instance, const char* pName)
}
if (string_eq(pName, "vkDestroySurfaceKHR")) {
- icd.is_using_icd_wsi = UsingICDProvidedWSI::is_using;
+ icd.is_using_icd_wsi = true;
return to_vkVoidFunction(test_vkDestroySurfaceKHR);
}
}
@@ -1410,6 +1466,16 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetDeviceProcAddr(VkDevice devic
}
PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char* pName) {
+#if TEST_ICD_EXPOSE_VERSION_7
+ if (string_eq(pName, "vk_icdNegotiateLoaderICDInterfaceVersion"))
+ return to_vkVoidFunction(test_vk_icdNegotiateLoaderICDInterfaceVersion);
+ if (string_eq(pName, "vk_icdGetPhysicalDeviceProcAddr")) return to_vkVoidFunction(get_physical_device_func);
+#if defined(WIN32)
+ if (string_eq(pName, "vk_icdEnumerateAdapterPhysicalDevices"))
+ return to_vkVoidFunction(test_vk_icdEnumerateAdapterPhysicalDevices);
+#endif // defined(WIN32)
+#endif // TEST_ICD_EXPOSE_VERSION_7
+
if (pName == nullptr) return nullptr;
if (instance == NULL) {
if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(test_vkGetInstanceProcAddr);
@@ -1434,35 +1500,7 @@ PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char*
extern "C" {
#if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
extern FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
- if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called &&
- icd.called_negotiate_interface == CalledNegotiateInterface::not_called)
- icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_negotiate;
- else if (icd.called_vk_icd_gipa != CalledICDGIPA::not_called)
- icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_gipa_first;
-
- // loader puts the minimum it supports in pSupportedVersion, if that is lower than our minimum
- // If the ICD doesn't supports the interface version provided by the loader, report VK_ERROR_INCOMPATIBLE_DRIVER
- if (icd.min_icd_interface_version > *pSupportedVersion) {
- icd.interface_version_check = InterfaceVersionCheck::loader_version_too_old;
- *pSupportedVersion = icd.min_icd_interface_version;
- return VK_ERROR_INCOMPATIBLE_DRIVER;
- }
-
- // the loader-provided interface version is newer than that supported by the ICD
- if (icd.max_icd_interface_version < *pSupportedVersion) {
- icd.interface_version_check = InterfaceVersionCheck::loader_version_too_new;
- *pSupportedVersion = icd.max_icd_interface_version;
- }
- // ICD interface version is greater than the loader's, return the loader's version
- else if (icd.max_icd_interface_version > *pSupportedVersion) {
- icd.interface_version_check = InterfaceVersionCheck::icd_version_too_new;
- // don't change *pSupportedVersion
- } else {
- icd.interface_version_check = InterfaceVersionCheck::version_is_supported;
- *pSupportedVersion = icd.max_icd_interface_version;
- }
-
- return VK_SUCCESS;
+ return test_vk_icdNegotiateLoaderICDInterfaceVersion(pSupportedVersion);
}
#endif // TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
@@ -1474,16 +1512,11 @@ FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDevic
#if TEST_ICD_EXPORT_ICD_GIPA
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) {
- // std::cout << "icdGetInstanceProcAddr: " << pName << "\n";
-
if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_icd_gipa;
-
return base_get_instance_proc_addr(instance, pName);
}
#else // !TEST_ICD_EXPORT_ICD_GIPA
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
- // std::cout << "icdGetInstanceProcAddr: " << pName << "\n";
-
if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_gipa;
return base_get_instance_proc_addr(instance, pName);
}
@@ -1503,17 +1536,7 @@ FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProp
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices) {
- if (adapterLUID.LowPart != icd.adapterLUID.LowPart || adapterLUID.HighPart != icd.adapterLUID.HighPart) {
- *pPhysicalDeviceCount = 0;
- return VK_SUCCESS;
- }
- icd.called_enumerate_adapter_physical_devices = true;
- VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
- // For this testing, flip order intentionally
- if (nullptr != pPhysicalDevices) {
- std::reverse(pPhysicalDevices, pPhysicalDevices + *pPhysicalDeviceCount);
- }
- return res;
+ return test_vk_icdEnumerateAdapterPhysicalDevices(instance, adapterLUID, pPhysicalDeviceCount, pPhysicalDevices);
}
#endif // defined(WIN32)
#endif // TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
diff --git a/tests/framework/icd/test_icd.h b/tests/framework/icd/test_icd.h
index 8134632e..27454136 100644
--- a/tests/framework/icd/test_icd.h
+++ b/tests/framework/icd/test_icd.h
@@ -45,9 +45,34 @@ enum class InterfaceVersionCheck {
version_is_supported
};
-enum class CalledEnumerateAdapterPhysicalDevices { not_called, called };
-
-enum class UsingICDProvidedWSI { not_using, is_using };
+// clang-format off
+inline std::ostream& operator<<(std::ostream& os, const CalledICDGIPA& result) {
+ switch (result) {
+ case (CalledICDGIPA::not_called): return os << "CalledICDGIPA::not_called";
+ case (CalledICDGIPA::vk_icd_gipa): return os << "CalledICDGIPA::vk_icd_gipa";
+ case (CalledICDGIPA::vk_gipa): return os << "CalledICDGIPA::vk_gipa";
+ }
+ return os << static_cast<uint32_t>(result);
+}
+inline std::ostream& operator<<(std::ostream& os, const CalledNegotiateInterface& result) {
+ switch (result) {
+ case (CalledNegotiateInterface::not_called): return os << "CalledNegotiateInterface::not_called";
+ case (CalledNegotiateInterface::vk_icd_negotiate): return os << "CalledNegotiateInterface::vk_icd_negotiate";
+ case (CalledNegotiateInterface::vk_icd_gipa_first): return os << "CalledNegotiateInterface::vk_icd_gipa_first";
+ }
+ return os << static_cast<uint32_t>(result);
+}
+inline std::ostream& operator<<(std::ostream& os, const InterfaceVersionCheck& result) {
+ switch (result) {
+ case (InterfaceVersionCheck::not_called): return os << "InterfaceVersionCheck::not_called";
+ case (InterfaceVersionCheck::loader_version_too_old): return os << "InterfaceVersionCheck::loader_version_too_old";
+ case (InterfaceVersionCheck::loader_version_too_new): return os << "InterfaceVersionCheck::loader_version_too_new";
+ case (InterfaceVersionCheck::icd_version_too_new): return os << "InterfaceVersionCheck::icd_version_too_new";
+ case (InterfaceVersionCheck::version_is_supported): return os << "InterfaceVersionCheck::version_is_supported";
+ }
+ return os << static_cast<uint32_t>(result);
+}
+// clang-format on
struct TestICD {
fs::path manifest_file_path;
@@ -57,13 +82,13 @@ struct TestICD {
InterfaceVersionCheck interface_version_check = InterfaceVersionCheck::not_called;
BUILDER_VALUE(TestICD, uint32_t, min_icd_interface_version, 0)
- BUILDER_VALUE(TestICD, uint32_t, max_icd_interface_version, 6)
+ BUILDER_VALUE(TestICD, uint32_t, max_icd_interface_version, 7)
uint32_t icd_interface_version_received = 0;
bool called_enumerate_adapter_physical_devices = false;
BUILDER_VALUE(TestICD, bool, enable_icd_wsi, false);
- UsingICDProvidedWSI is_using_icd_wsi = UsingICDProvidedWSI::not_using;
+ bool is_using_icd_wsi = false;
BUILDER_VALUE(TestICD, uint32_t, icd_api_version, VK_API_VERSION_1_0)
BUILDER_VECTOR(TestICD, LayerDefinition, instance_layers, instance_layer)
@@ -81,8 +106,9 @@ struct TestICD {
std::vector<uint64_t> swapchain_handles;
// Unknown instance functions Add a `VulkanFunction` to this list which will be searched in
- // vkGetInstanceProcAddr for custom_instance_functions and vk_icdGetPhysicalDeviceProcAddr for custom_physical_device_functions.
- // To add unknown device functions, add it to the PhysicalDevice directly (in the known_device_functions member)
+ // vkGetInstanceProcAddr for custom_instance_functions and vk_icdGetPhysicalDeviceProcAddr for
+ // custom_physical_device_functions. To add unknown device functions, add it to the PhysicalDevice directly (in the
+ // known_device_functions member)
BUILDER_VECTOR(TestICD, VulkanFunction, custom_instance_functions, custom_instance_function)
// Must explicitely state support for the tooling info extension, that way we can control if vkGetInstanceProcAddr returns a
diff --git a/tests/loader_version_tests.cpp b/tests/loader_version_tests.cpp
index 815c7bb0..2e24743d 100644
--- a/tests/loader_version_tests.cpp
+++ b/tests/loader_version_tests.cpp
@@ -53,7 +53,7 @@ TEST(ICDInterfaceVersion2Plus, version_3) {
InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();
- ASSERT_EQ(driver.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
+ ASSERT_FALSE(driver.is_using_icd_wsi);
}
{
driver.min_icd_interface_version = 3;
@@ -61,7 +61,7 @@ TEST(ICDInterfaceVersion2Plus, version_3) {
InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();
- ASSERT_EQ(driver.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
+ ASSERT_FALSE(driver.is_using_icd_wsi);
}
{
driver.min_icd_interface_version = 3;
@@ -69,7 +69,7 @@ TEST(ICDInterfaceVersion2Plus, version_3) {
InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();
- ASSERT_EQ(driver.is_using_icd_wsi, UsingICDProvidedWSI::is_using);
+ ASSERT_TRUE(driver.is_using_icd_wsi);
}
}
@@ -310,6 +310,29 @@ TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults
}
#endif // defined(WIN32)
+TEST(ICDInterfaceVersion7, SingleDriver) {
+ FrameworkEnvironment env{};
+ env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7_WITH_ADDITIONAL_EXPORTS));
+ env.get_test_icd().physical_devices.push_back({});
+ InstWrapper inst{env.vulkan_functions};
+ inst.CheckCreate();
+ auto phys_dev = inst.GetPhysDev();
+ DeviceWrapper dev{inst};
+ dev.CheckCreate(phys_dev);
+ ASSERT_EQ(env.get_test_icd().interface_version_check, InterfaceVersionCheck::version_is_supported);
+}
+
+TEST(ICDInterfaceVersion7, SingleDriverWithoutExportedFunctions) {
+ FrameworkEnvironment env{};
+ env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7));
+ env.get_test_icd().physical_devices.push_back({});
+ InstWrapper inst{env.vulkan_functions};
+ inst.CheckCreate();
+ auto phys_dev = inst.GetPhysDev();
+ DeviceWrapper dev{inst};
+ dev.CheckCreate(phys_dev);
+ ASSERT_EQ(env.get_test_icd().interface_version_check, InterfaceVersionCheck::version_is_supported);
+}
TEST(MultipleICDConfig, Basic) {
FrameworkEnvironment env{};
diff --git a/tests/loader_wsi_tests.cpp b/tests/loader_wsi_tests.cpp
index 095aac95..0b458247 100644
--- a/tests/loader_wsi_tests.cpp
+++ b/tests/loader_wsi_tests.cpp
@@ -68,7 +68,6 @@ TEST(WsiTests, CreateSurfaceWin32NoICDCreateSupport) {
VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(inst, &surf_create_info, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(cur_icd.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
}
@@ -92,7 +91,6 @@ TEST(WsiTests, CreateSurfaceWin32ICDSupport) {
VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(inst, &surf_create_info, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(cur_icd.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
}
@@ -121,7 +119,6 @@ TEST(WsiTests, CreateSurfaceWin32MixedICDSupport) {
VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(instance.inst, &surf_create_info, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(cur_icd.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
}
@@ -202,7 +199,6 @@ TEST(WsiTests, Win32GetPhysicalDeviceSurfaceSupportKHR) {
VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(instance.inst, &surf_create_info, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(driver.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
uint32_t device_count = max_device_count;
std::array<VkPhysicalDevice, max_device_count> phys_devs;
@@ -391,7 +387,6 @@ TEST(WsiTests, XcbGetPhysicalDeviceSurfaceSupportKHR) {
VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXcbSurfaceKHR(instance.inst, &xcb_createInfo, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(cur_icd.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
uint32_t device_count = max_device_count;
std::array<VkPhysicalDevice, max_device_count> phys_devs;
@@ -580,7 +575,6 @@ TEST(WsiTests, XlibGetPhysicalDeviceSurfaceSupportKHR) {
VkXlibSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXlibSurfaceKHR(instance.inst, &createInfo, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(driver.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
uint32_t device_count = max_device_count;
std::array<VkPhysicalDevice, max_device_count> phys_devs;
@@ -769,7 +763,6 @@ TEST(WsiTests, WaylandGetPhysicalDeviceSurfaceSupportKHR) {
VkWaylandSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWaylandSurfaceKHR(instance.inst, &createInfo, nullptr, &surface));
ASSERT_TRUE(surface != VK_NULL_HANDLE);
- // ASSERT_EQ(cur_icd.is_using_icd_wsi, UsingICDProvidedWSI::not_using);
uint32_t device_count = max_device_count;
std::array<VkPhysicalDevice, max_device_count> phys_devs;