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@gmail.com>
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11550>
This commit is contained in:
Erik Faye-Lund 2021-06-23 10:23:38 +02:00 committed by Marge Bot
parent 56e9ccce7b
commit 693c723211
5 changed files with 43 additions and 11 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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);