Mesa (main): zink: use run-time linking to loader

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri May 13 17:05:46 UTC 2022


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

Author: Erik Faye-Lund <erik.faye-lund at collabora.com>
Date:   Wed Jun 23 10:23:38 2021 +0200

zink: use run-time linking to loader

This makes Zink no longer have the vulkan-loader in the import-table,
which can prevent opengl32.dll on Windows from loading on systems
without the loader installed.

Acked-by: Hoe Hao Cheng <haochengho12907 at gmail.com>
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11550>

---

 meson.build                               |  4 ----
 src/gallium/drivers/zink/meson.build      |  2 +-
 src/gallium/drivers/zink/zink_instance.py |  5 ++++-
 src/gallium/drivers/zink/zink_screen.c    | 35 +++++++++++++++++++++++++++----
 src/gallium/drivers/zink/zink_screen.h    |  8 ++++++-
 5 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/meson.build b/meson.build
index 9f93ad52be7..460fefaad5c 100644
--- a/meson.build
+++ b/meson.build
@@ -671,10 +671,6 @@ if vdpau_drivers_path == ''
   vdpau_drivers_path = join_paths(get_option('libdir'), 'vdpau')
 endif
 
-if with_gallium_zink
-  dep_vulkan = dependency('vulkan')
-endif
-
 dep_dxheaders = null_dep
 if with_gallium_d3d12 or with_microsoft_clc or with_microsoft_vk
   dep_dxheaders = dependency('directx-headers', required : false)
diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build
index 78591430be8..78975f90e93 100644
--- a/src/gallium/drivers/zink/meson.build
+++ b/src/gallium/drivers/zink/meson.build
@@ -91,7 +91,7 @@ libzink = static_library(
   gnu_symbol_visibility : 'hidden',
   include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_vulkan_util, inc_zink_vk],
   dependencies: [
-    dep_vulkan, idep_nir_headers, idep_mesautil, idep_vulkan_util_headers,
+    idep_nir_headers, idep_mesautil, idep_vulkan_util_headers,
     idep_vulkan_wsi_headers, idep_vulkan_util
   ],
   c_args: zink_c_args,
diff --git a/src/gallium/drivers/zink/zink_instance.py b/src/gallium/drivers/zink/zink_instance.py
index 1fa44804c4b..5761352c972 100644
--- a/src/gallium/drivers/zink/zink_instance.py
+++ b/src/gallium/drivers/zink/zink_instance.py
@@ -250,7 +250,10 @@ zink_create_instance(struct zink_screen *screen)
    ici.ppEnabledLayerNames = layers;
    ici.enabledLayerCount = num_layers;
 
-   VkResult err = vkCreateInstance(&ici, NULL, &screen->instance);
+   GET_PROC_ADDR_INSTANCE_LOCAL(screen, NULL, CreateInstance);
+   assert(vk_CreateInstance);
+
+   VkResult err = vk_CreateInstance(&ici, NULL, &screen->instance);
    if (err != VK_SUCCESS) {
       mesa_loge("ZINK: vkCreateInstance failed");
       return false;
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 47c482432a0..0f381a5ab1c 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -39,6 +39,7 @@
 
 #include "os/os_process.h"
 #include "util/u_debug.h"
+#include "util/u_dl.h"
 #include "util/format/u_format.h"
 #include "util/hash_table.h"
 #include "util/os_file.h"
@@ -55,8 +56,14 @@
 
 #if DETECT_OS_WINDOWS
 #include <io.h>
+#define VK_LIBNAME "vulkan-1.dll"
 #else
 #include <unistd.h>
+#if DETECT_OS_APPLE
+#define VK_LIBNAME "libvulkan.1.dylib"
+#else
+#define VK_LIBNAME "libvulkan.so.1"
+#endif
 #endif
 
 #if defined(__APPLE__)
@@ -1227,6 +1234,8 @@ zink_destroy_screen(struct pipe_screen *pscreen)
    VKSCR(DestroyInstance)(screen->instance, NULL);
    util_idalloc_mt_fini(&screen->buffer_ids);
 
+   util_dl_close(screen->loader_lib);
+
    slab_destroy_parent(&screen->transfer_pool);
    ralloc_free(screen);
    glsl_type_singleton_decref();
@@ -2045,8 +2054,17 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
       abort();
    }
 
-   screen->instance_info.loader_version = zink_get_loader_version(screen);
+   screen->loader_lib = util_dl_open(VK_LIBNAME);
+   if (!screen->loader_lib)
+      goto fail;
 
+   screen->vk_GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)util_dl_get_proc_address(screen->loader_lib, "vkGetInstanceProcAddr");
+   screen->vk_GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)util_dl_get_proc_address(screen->loader_lib, "vkGetDeviceProcAddr");
+   if (!screen->vk_GetInstanceProcAddr ||
+       !screen->vk_GetDeviceProcAddr)
+      goto fail;
+
+   screen->instance_info.loader_version = zink_get_loader_version(screen);
 #if WITH_XMLCONFIG
    if (config) {
       driParseConfigFiles(config->options, config->options_info, 0, "zink",
@@ -2060,8 +2078,12 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
    if (!zink_create_instance(screen))
       goto fail;
 
-   vk_instance_dispatch_table_load(&screen->vk.instance, &vkGetInstanceProcAddr, screen->instance);
-   vk_physical_device_dispatch_table_load(&screen->vk.physical_device, &vkGetInstanceProcAddr, screen->instance);
+   vk_instance_dispatch_table_load(&screen->vk.instance,
+                                   screen->vk_GetInstanceProcAddr,
+                                   screen->instance);
+   vk_physical_device_dispatch_table_load(&screen->vk.physical_device,
+                                          screen->vk_GetInstanceProcAddr,
+                                          screen->instance);
 
    zink_verify_instance_extensions(screen);
 
@@ -2098,7 +2120,9 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
    if (!screen->dev)
       goto fail;
 
-   vk_device_dispatch_table_load(&screen->vk.device, &vkGetDeviceProcAddr, screen->dev);
+   vk_device_dispatch_table_load(&screen->vk.device,
+                                 screen->vk_GetDeviceProcAddr,
+                                 screen->dev);
 
    init_queue(screen);
    if (screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV ||
@@ -2237,6 +2261,9 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
    return screen;
 
 fail:
+   if (screen->loader_lib)
+      util_dl_close(screen->loader_lib);
+
    ralloc_free(screen);
    return NULL;
 }
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index 6eb5b904eba..56284f5f51b 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -45,6 +45,7 @@
 
 extern uint32_t zink_debug;
 struct hash_table;
+struct util_dl_library;
 
 struct zink_batch_state;
 struct zink_context;
@@ -80,6 +81,11 @@ struct zink_modifier_prop {
 
 struct zink_screen {
    struct pipe_screen base;
+
+   struct util_dl_library *loader_lib;
+   PFN_vkGetInstanceProcAddr vk_GetInstanceProcAddr;
+   PFN_vkGetDeviceProcAddr vk_GetDeviceProcAddr;
+
    bool threaded;
    bool is_cpu;
    uint32_t curr_batch; //the current batch id
@@ -265,7 +271,7 @@ zink_screen_timeline_wait(struct zink_screen *screen, uint32_t batch_id, uint64_
 bool
 zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format);
 
-#define GET_PROC_ADDR_INSTANCE_LOCAL(screen, instance, x) PFN_vk##x vk_##x = (PFN_vk##x)vkGetInstanceProcAddr(instance, "vk"#x)
+#define GET_PROC_ADDR_INSTANCE_LOCAL(screen, instance, x) PFN_vk##x vk_##x = (PFN_vk##x)(screen)->vk_GetInstanceProcAddr(instance, "vk"#x)
 
 void
 zink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg);



More information about the mesa-commit mailing list