Apr 29, 2021, 03:54 by d...@lynne.ee:

> While Vulkan itself went more or less the way it was expected to go, 
> libvulkan didn't quite solve all of the opengl loader issues. It's 
> multi-vendor,
> yes, but unfortunately, the code is Google/Khronos QUALITY, so suffers from
> big static linking issues (static linking on anything but OSX is unsupported),
> has bugs, and due to the prefix system used, there are 3 or so ways to type 
> out
> functions.
>
> Just solve all of those problems by dlopening it. We even have nice emulation
> for it on Windows.
>
> Patch attached.
>

Thanks to jamrial for telling me to zero extralibs, now there's no linking
at all to libvulkan.
v2 attached.

>From 9c2778fe82490b96c9efeba3fe09077fbf13cfe0 Mon Sep 17 00:00:00 2001
From: Lynne <d...@lynne.ee>
Date: Thu, 29 Apr 2021 03:37:42 +0200
Subject: [PATCH v2 2/2] hwcontext_vulkan: dlopen libvulkan

While Vulkan itself went more or less the way it was expected to go,
libvulkan didn't quite solve all of the opengl loader issues. It's multi-vendor,
yes, but unfortunately, the code is Google/Khronos QUALITY, so suffers from
big static linking issues (static linking on anything but OSX is unsupported),
has bugs, and due to the prefix system used, there are 3 or so ways to type out
functions.

Just solve all of those problems by dlopening it. We even have nice emulation
for it on Windows.
---
 configure                    |  4 ++-
 libavutil/hwcontext_vulkan.c | 51 +++++++++++++++++++++++++++++++++---
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 820f719a32..fbd85e3244 100755
--- a/configure
+++ b/configure
@@ -2920,6 +2920,8 @@ nvdec_deps="ffnvcodec"
 vaapi_x11_deps="xlib"
 videotoolbox_hwaccel_deps="videotoolbox pthreads"
 videotoolbox_hwaccel_extralibs="-framework QuartzCore"
+vulkan_deps_any="libdl LoadLibrary"
+vulkan_hwaccel_extralibs=""
 xvmc_deps="X11_extensions_XvMClib_h"
 
 av1_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_AV1"
@@ -6739,7 +6741,7 @@ enabled vdpau &&
 enabled crystalhd && check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd
 
 enabled vulkan &&
-    require_pkg_config vulkan "vulkan >= 1.1.97" "vulkan/vulkan.h" vkCreateInstance
+    require_cpp_condition vulkan vulkan/vulkan.h "defined VK_VERSION_1_1"
 
 if enabled x86; then
     case $target_os in
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 7bb05ca1c7..52de5ab122 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -26,8 +26,11 @@
 #include "hwcontext_internal.h"
 #include "hwcontext_vulkan.h"
 
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
-                                                               const char *name);
+#ifdef _WIN32
+#include "compat/w32dlfcn.h"
+#else
+#include <dlfcn.h>
+#endif
 
 #if CONFIG_LIBDRM
 #include <unistd.h>
@@ -186,7 +189,8 @@ typedef struct VulkanExecCtx {
 } VulkanExecCtx;
 
 typedef struct VulkanDevicePriv {
-    /* Vulkan loader functions */
+    /* Vulkan library and loader functions */
+    void *libvulkan;
     VulkanFunctions vkfn;
 
     /* Properties */
@@ -369,6 +373,40 @@ static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p,
     return 1;
 }
 
+static int load_libvulkan(AVHWDeviceContext *ctx)
+{
+    AVVulkanDeviceContext *hwctx = ctx->hwctx;
+    VulkanDevicePriv *p = ctx->internal->priv;
+
+    static const char *lib_names[] = {
+#if defined(_WIN32)
+        "vulkan-1.dll",
+#elif defined(__APPLE__)
+        "libvulkan.dylib",
+        "libvulkan.1.dylib",
+        "libMoltenVK.dylib",
+#else
+        "libvulkan.so.1",
+        "libvulkan.so",
+#endif
+    };
+
+    for (int i = 0; i < FF_ARRAY_ELEMS(lib_names); i++) {
+        p->libvulkan = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
+        if (p->libvulkan)
+            break;
+    }
+
+    if (!p->libvulkan) {
+        av_log(ctx, AV_LOG_ERROR, "Unable to open the libvulkan library!\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    hwctx->get_proc_addr = (PFN_vkGetInstanceProcAddr)dlsym(p->libvulkan, "vkGetInstanceProcAddr");
+
+    return 0;
+}
+
 static int load_functions(AVHWDeviceContext *ctx, int has_inst, int has_dev)
 {
     AVVulkanDeviceContext *hwctx = ctx->hwctx;
@@ -649,7 +687,9 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
     };
 
     if (!hwctx->get_proc_addr) {
-        hwctx->get_proc_addr = vkGetInstanceProcAddr;
+        err = load_libvulkan(ctx);
+        if (err < 0)
+            return err;
     }
 
     err = load_functions(ctx, 0, 0);
@@ -1188,6 +1228,9 @@ static void vulkan_device_free(AVHWDeviceContext *ctx)
 
     vk->DestroyInstance(hwctx->inst, hwctx->alloc);
 
+    if (p->libvulkan)
+        dlclose(p->libvulkan);
+
     for (int i = 0; i < hwctx->nb_enabled_inst_extensions; i++)
         av_free((void *)hwctx->enabled_inst_extensions[i]);
     av_free((void *)hwctx->enabled_inst_extensions);
-- 
2.31.1.498.g6c1eba8ee3d

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to