Module: Mesa
Branch: main
Commit: 67df2f29eba99c37179c5d54d10ce1a2274bb426
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=67df2f29eba99c37179c5d54d10ce1a2274bb426

Author: Jesse Natalie <jenat...@microsoft.com>
Date:   Wed Nov  1 14:33:41 2023 -0700

vulkan: Support loader interface v7

Reviewed-by: Faith Ekstrand <faith.ekstr...@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25998>

---

 src/vulkan/runtime/vk_instance.c | 70 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/src/vulkan/runtime/vk_instance.c b/src/vulkan/runtime/vk_instance.c
index 0a0dd836eb6..e462c721262 100644
--- a/src/vulkan/runtime/vk_instance.c
+++ b/src/vulkan/runtime/vk_instance.c
@@ -302,6 +302,19 @@ vk_instance_get_proc_addr(const struct vk_instance 
*instance,
 
 #undef LOOKUP_VK_ENTRYPOINT
 
+   /* Beginning with ICD interface v7, the following functions can also be
+    * retrieved via vk_icdGetInstanceProcAddr.
+    */
+
+   if (strcmp(name, "vk_icdNegotiateLoaderICDInterfaceVersion") == 0)
+      return (PFN_vkVoidFunction)vk_icdNegotiateLoaderICDInterfaceVersion;
+   if (strcmp(name, "vk_icdGetPhysicalDeviceProcAddr") == 0)
+      return (PFN_vkVoidFunction)vk_icdGetPhysicalDeviceProcAddr;
+#ifdef _WIN32
+   if (strcmp(name, "vk_icdEnumerateAdapterPhysicalDevices") == 0)
+      return (PFN_vkVoidFunction)vk_icdEnumerateAdapterPhysicalDevices;
+#endif
+
    if (instance == NULL)
       return NULL;
 
@@ -466,6 +479,39 @@ vk_common_EnumeratePhysicalDevices(VkInstance _instance, 
uint32_t *pPhysicalDevi
    return vk_outarray_status(&out);
 }
 
+#ifdef _WIN32
+/* Note: This entrypoint is not exported from ICD DLLs, and is only exposed via
+ * vk_icdGetInstanceProcAddr for loaders with interface v7. This is to avoid
+ * a design flaw in the original loader implementation, which prevented 
enumeration
+ * of physical devices that didn't have a LUID. This flaw was fixed prior to 
the
+ * implementation of v7, so v7 loaders are unaffected, and it's safe to 
support this.
+ */
+VKAPI_ATTR VkResult VKAPI_CALL
+vk_icdEnumerateAdapterPhysicalDevices(VkInstance _instance, LUID adapterLUID,
+                                      uint32_t *pPhysicalDeviceCount,
+                                      VkPhysicalDevice *pPhysicalDevices)
+{
+   VK_FROM_HANDLE(vk_instance, instance, _instance);
+   VK_OUTARRAY_MAKE_TYPED(VkPhysicalDevice, out, pPhysicalDevices, 
pPhysicalDeviceCount);
+
+   VkResult result = enumerate_physical_devices(instance);
+   if (result != VK_SUCCESS)
+      return result;
+
+   list_for_each_entry(struct vk_physical_device, pdevice,
+                       &instance->physical_devices.list, link) {
+      if (pdevice->properties.deviceLUIDValid &&
+          memcmp(pdevice->properties.deviceLUID, &adapterLUID, 
sizeof(adapterLUID)) == 0) {
+         vk_outarray_append_typed(VkPhysicalDevice, &out, element) {
+            *element = vk_physical_device_to_handle(pdevice);
+         }
+      }
+   }
+
+   return vk_outarray_status(&out);
+}
+#endif
+
 VKAPI_ATTR VkResult VKAPI_CALL
 vk_common_EnumeratePhysicalDeviceGroups(VkInstance _instance, uint32_t 
*pGroupCount,
                                         VkPhysicalDeviceGroupProperties 
*pGroupProperties)
@@ -512,7 +558,7 @@ vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
    return vk_instance_get_physical_device_proc_addr(instance, pName);
 }
 
-static uint32_t vk_icd_version = 5;
+static uint32_t vk_icd_version = 7;
 
 uint32_t
 vk_get_negotiated_icd_version(void)
@@ -562,6 +608,28 @@ vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t 
*pSupportedVersion)
     *          VK_ERROR_INCOMPATIBLE_DRIVER from vkCreateInstance() unless a
     *          Vulkan Loader with interface v4 or smaller is being used and the
     *          application provides an API version that is greater than 1.0.
+    *
+    *    - Loader interface v6 differs from v5 in:
+    *        - Windows ICDs may export vk_icdEnumerateAdapterPhysicalDevices,
+    *          to tie a physical device to a WDDM adapter LUID. This allows the
+    *          loader to sort physical devices according to the same policy as 
other
+    *          graphics APIs.
+    *        - Note: A design flaw in the loader implementation of v6 means we 
do
+    *          not actually support returning this function to v6 loaders. See 
the
+    *          comments around the implementation above. It's still fine to 
report
+    *          version number 6 without this method being implemented, however.
+    *
+    *    - Loader interface v7 differs from v6 in:
+    *        - If implemented, the ICD must return the following functions via
+    *          vk_icdGetInstanceProcAddr:
+    *            - vk_icdNegotiateLoaderICDInterfaceVersion
+    *            - vk_icdGetPhysicalDeviceProcAddr
+    *            - vk_icdEnumerateAdapterPhysicalDevices
+    *          Exporting these functions from the ICD is optional. If
+    *          vk_icdNegotiateLoaderICDInterfaceVersion is not exported from 
the
+    *          module, or if VK_LUNARG_direct_driver_loading is being used, 
then
+    *          vk_icdGetInstanceProcAddr will be the first method called, to 
query
+    *          for vk_icdNegotiateLoaderICDInterfaceVersion.
     */
    vk_icd_version = MIN2(vk_icd_version, *pSupportedVersion);
    *pSupportedVersion = vk_icd_version;

Reply via email to