Mesa (master): zink: make physical device functions use a dynamic function pointers.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Nov 8 06:15:19 UTC 2020


Module: Mesa
Branch: master
Commit: d377d844969b18264d3eeeeb1bbdf37131c69791
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d377d844969b18264d3eeeeb1bbdf37131c69791

Author: Duncan Hopkins <duncan at duncanhopkins.me.uk>
Date:   Wed Nov  4 17:42:29 2020 +0000

zink: make physical device functions use a dynamic function pointers.

vkGetPhysicalDeviceFeatures2 and vkGetPhysicalDeviceProperties2 are not present on some MoltenVK versions.
VK_KHR_get_physical_device_properties2 exposes the KHR versions of the same functions.
These cannot be used via static linking, so we have to dynamically detect the loader version and then the extension
to work out which pointers to use.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7447>

---

 src/gallium/drivers/zink/zink_device_info.py | 70 +++++++++++++++++-----------
 src/gallium/drivers/zink/zink_screen.c       | 48 ++++++++++++++++++-
 src/gallium/drivers/zink/zink_screen.h       |  5 ++
 3 files changed, 94 insertions(+), 29 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py
index 0a7ec8fd137..149a5bf212b 100644
--- a/src/gallium/drivers/zink/zink_device_info.py
+++ b/src/gallium/drivers/zink/zink_device_info.py
@@ -170,53 +170,69 @@ zink_get_physical_device_info(struct zink_screen *screen)
       }
    }
 
-   // check for device extension features
-   info->feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+   if (screen->vk_GetPhysicalDeviceFeatures2) {
+      // check for device extension features
+      info->feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
 
 %for ext in extensions:
 %if ext.feature_field is not None or ext.has_features:
-   ${ext.guard_start()}
-   if (support_${ext.name_with_vendor()}) {
-      info->${ext.field("feats")}.sType = ${ext.stype("FEATURES")};
-      info->${ext.field("feats")}.pNext = info->feats.pNext;
-      info->feats.pNext = &info->${ext.field("feats")};
-   }
-   ${ext.guard_end()}
+      ${ext.guard_start()}
+      if (support_${ext.name_with_vendor()}) {
+         info->${ext.field("feats")}.sType = ${ext.stype("FEATURES")};
+         info->${ext.field("feats")}.pNext = info->feats.pNext;
+         info->feats.pNext = &info->${ext.field("feats")};
+      }
+      ${ext.guard_end()}
 %endif
 %endfor
 
-   vkGetPhysicalDeviceFeatures2(screen->pdev, &info->feats);
+      screen->vk_GetPhysicalDeviceFeatures2(screen->pdev, &info->feats);
 
 %for ext in extensions:
-   ${ext.guard_start()}
+      ${ext.guard_start()}
 %if ext.feature_field is None:
-   info->have_${ext.name_with_vendor()} = support_${ext.name_with_vendor()};
+      info->have_${ext.name_with_vendor()} = support_${ext.name_with_vendor()};
 %else:
-   if (support_${ext.name_with_vendor()} && info->${ext.field("feats")}.${ext.feature_field}) {
-      info->have_${ext.name_with_vendor()} = true;
-   }
+      if (support_${ext.name_with_vendor()} && info->${ext.field("feats")}.${ext.feature_field}) {
+         info->have_${ext.name_with_vendor()} = true;
+      }
 %endif
-   ${ext.guard_end()}
+      ${ext.guard_end()}
+%endfor
+   } else {
+      vkGetPhysicalDeviceFeatures(screen->pdev, &info->feats.features);
+
+%for ext in extensions:
+      ${ext.guard_start()}
+%if ext.feature_field is None:
+      info->have_${ext.name_with_vendor()} = support_${ext.name_with_vendor()};
+%endif
+      ${ext.guard_end()}
 %endfor
+   }
 
    // check for device properties
-   VkPhysicalDeviceProperties2 props = {};
-   props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+   if (screen->vk_GetPhysicalDeviceProperties2) {
+      VkPhysicalDeviceProperties2 props = {};
+      props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
 
 %for ext in extensions:
 %if ext.has_properties:
-   ${ext.guard_start()}
-   if (info->have_${ext.name_with_vendor()}) {
-      info->${ext.field("props")}.sType = ${ext.stype("PROPERTIES")};
-      info->${ext.field("props")}.pNext = props.pNext;
-      props.pNext = &info->${ext.field("props")};
-   }
-   ${ext.guard_end()}
+      ${ext.guard_start()}
+      if (info->have_${ext.name_with_vendor()}) {
+         info->${ext.field("props")}.sType = ${ext.stype("PROPERTIES")};
+         info->${ext.field("props")}.pNext = props.pNext;
+         props.pNext = &info->${ext.field("props")};
+      }
+      ${ext.guard_end()}
 %endif
 %endfor
 
-   vkGetPhysicalDeviceProperties2(screen->pdev, &props);
-   memcpy(&info->props, &props.properties, sizeof(info->props));
+      screen->vk_GetPhysicalDeviceProperties2(screen->pdev, &props);
+      memcpy(&info->props, &props.properties, sizeof(info->props));
+   } else {
+      vkGetPhysicalDeviceProperties(screen->pdev, &info->props);
+   }
 
    // generate extension list
    num_extensions = 0;
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 96c6945f977..5ee02be415a 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -672,6 +672,7 @@ create_instance(struct zink_screen *screen)
                   }
                   if (!strcmp(extension_props[i].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
                      extensions[num_extensions++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
+                     screen->have_physical_device_prop2_ext = true;
                   }
                   if (!strcmp(extension_props[i].extensionName, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
                      extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME;
@@ -873,6 +874,42 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen,
       } \
    } while (0)
 
+#define GET_PROC_ADDR_INSTANCE_LOCAL(instance, x) PFN_vk##x vk_##x = (PFN_vk##x)vkGetInstanceProcAddr(instance, "vk"#x)
+
+static bool
+load_instance_extensions(struct zink_screen *screen)
+{
+   screen->loader_version = VK_API_VERSION_1_0;
+   {
+      // Get the Loader version
+      GET_PROC_ADDR_INSTANCE_LOCAL(NULL, EnumerateInstanceVersion);
+      if (vk_EnumerateInstanceVersion) {
+         uint32_t loader_version_temp = VK_API_VERSION_1_0;
+         if (VK_SUCCESS == (*vk_EnumerateInstanceVersion)( &loader_version_temp)) {
+            screen->loader_version = loader_version_temp;
+         }
+      }
+   }
+   if (zink_debug & ZINK_DEBUG_VALIDATION) {
+      printf("zink: Loader %d.%d.%d \n", VK_VERSION_MAJOR(screen->loader_version), VK_VERSION_MINOR(screen->loader_version), VK_VERSION_PATCH(screen->loader_version));
+   }
+
+   if (VK_MAKE_VERSION(1,1,0) <= screen->loader_version) {
+      // Get Vk 1.1+ Instance functions
+      GET_PROC_ADDR_INSTANCE(GetPhysicalDeviceFeatures2);
+      GET_PROC_ADDR_INSTANCE(GetPhysicalDeviceProperties2);
+   } else
+   if (screen->have_physical_device_prop2_ext) {
+      // Not Vk 1.1+ so if VK_KHR_get_physical_device_properties2 the use it
+      GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, GetPhysicalDeviceFeatures2KHR);
+      GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, GetPhysicalDeviceProperties2KHR);
+      screen->vk_GetPhysicalDeviceFeatures2 = vk_GetPhysicalDeviceFeatures2KHR;
+      screen->vk_GetPhysicalDeviceProperties2 = vk_GetPhysicalDeviceProperties2KHR;
+   }
+
+   return true;
+}
+
 static bool
 load_device_extensions(struct zink_screen *screen)
 {
@@ -1041,7 +1078,10 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd, const struct pipe_
    zink_debug = debug_get_option_zink_debug();
 
    screen->instance = create_instance(screen);
-   if(!screen->instance)
+   if (!screen->instance)
+      goto fail;
+
+   if (!load_instance_extensions(screen))
       goto fail;
 
    if (screen->have_debug_utils_ext && !create_debug(screen))
@@ -1088,7 +1128,11 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd, const struct pipe_
    /* extensions don't have bool members in pEnabledFeatures.
     * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct
     */
-   dci.pNext = &screen->info.feats;
+   if (screen->info.feats.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
+      dci.pNext = &screen->info.feats;
+   } else {
+      dci.pEnabledFeatures = &screen->info.feats.features;
+   }
 
    dci.ppEnabledExtensionNames = screen->info.extensions;
    dci.enabledExtensionCount = screen->info.num_extensions;
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index aa8adffd1ee..ed27159a234 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -64,11 +64,16 @@ struct zink_screen {
    VkDevice dev;
    VkDebugUtilsMessengerEXT debugUtilsCallbackHandle;
 
+   uint32_t loader_version;
+   bool have_physical_device_prop2_ext;
    bool have_debug_utils_ext;
 #if defined(MVK_VERSION)
    bool have_moltenvk;
 #endif
 
+   PFN_vkGetPhysicalDeviceFeatures2 vk_GetPhysicalDeviceFeatures2;
+   PFN_vkGetPhysicalDeviceProperties2 vk_GetPhysicalDeviceProperties2;
+
    PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR;
    PFN_vkCmdBeginConditionalRenderingEXT vk_CmdBeginConditionalRenderingEXT;
    PFN_vkCmdEndConditionalRenderingEXT vk_CmdEndConditionalRenderingEXT;



More information about the mesa-commit mailing list