[PATCH vkd3d v2 5/5] Add support for MoltenVK on Mac OS.

Chip Davis cdavis at codeweavers.com
Fri Aug 3 16:12:23 CDT 2018


Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---

Notes:
    Try 2: Drop support for the demos; they require Objective-C. Check for
           MoltenVK instead of if we're building for Mac. Check for the name
           of the library to load in configure.
    
    For that last one, I've appropriated WINE_CHECK_SONAME().

 configure.ac                           | 18 ++++++++++---
 libs/vkd3d-utils/vkd3d_utils_main.c    |  4 +++
 libs/vkd3d-utils/vkd3d_utils_private.h |  7 +++++
 libs/vkd3d/device.c                    |  4 +--
 m4/check-soname.m4                     | 36 ++++++++++++++++++++++++++
 tests/vkd3d_api.c                      | 16 ++++++++++++
 6 files changed, 79 insertions(+), 6 deletions(-)
 create mode 100644 m4/check-soname.m4

diff --git a/configure.ac b/configure.ac
index 7c2a560..76ed60c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,9 +75,12 @@ AC_CHECK_LIB([pthread], [pthread_create],
              [AC_MSG_ERROR([libpthread not found.])])
 
 AC_SUBST([VULKAN_LIBS])
-AC_CHECK_LIB([vulkan], [vkGetInstanceProcAddr],
-             [VULKAN_LIBS="-lvulkan"],
-             [AC_MSG_ERROR([libvulkan not found.])])
+VKD3D_CHECK_SONAME([vulkan], [vkGetInstanceProcAddr],
+                   [VULKAN_LIBS="-lvulkan"],
+                   [VKD3D_CHECK_SONAME([MoltenVK], [vkGetInstanceProcAddr],
+                                       [VULKAN_LIBS="-lMoltenVK"
+                                        AC_DEFINE_UNQUOTED([SONAME_LIBVULKAN],["$ac_cv_lib_soname_MoltenVK"])],
+                                       [AC_MSG_ERROR([libvulkan and libMoltenVK not found.])])])
 
 HAVE_SPIRV_TOOLS=no
 AS_IF([test "x$with_spirv_tools" = "xyes"],
@@ -85,12 +88,19 @@ AS_IF([test "x$with_spirv_tools" = "xyes"],
       [AC_DEFINE([HAVE_SPIRV_TOOLS], [1], [Define to 1 if you have SPIRV-Tools.])
       HAVE_SPIRV_TOOLS=yes])])
 
-PKG_CHECK_MODULES([XCB], [xcb xcb-keysyms])
 case $host_os in
   darwin*|macosx*)
+    AC_CHECK_HEADERS(MoltenVK/vk_mvk_moltenvk.h)
+    AS_IF([test "x$ac_cv_header_MoltenVK_vk_mvk_moltenvk_h" = "xno"],
+          [AC_MSG_ERROR([MoltenVK is required to use vkd3d on Mac OS.])])
     enable_demos_default=no
     ;;
   *)
+    PKG_CHECK_MODULES([XCB], [xcb xcb-keysyms])
+    save_cppflags="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $XCB_CFLAGS"
+    AC_CHECK_HEADERS(xcb/xcb.h)
+    CPPFLAGS="$save_cppflags"
     enable_demos_default=yes
     ;;
 esac
diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c
index 2c4d89a..a96ba68 100644
--- a/libs/vkd3d-utils/vkd3d_utils_main.c
+++ b/libs/vkd3d-utils/vkd3d_utils_main.c
@@ -34,7 +34,11 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
     static const char * const instance_extensions[] =
     {
         VK_KHR_SURFACE_EXTENSION_NAME,
+#ifdef HAVE_MOLTENVK_VK_MVK_MOLTENVK_H
+        VK_MVK_MACOS_SURFACE_EXTENSION_NAME,
+#elif defined(HAVE_XCB_XCB_H)
         VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+#endif
     };
     static const char * const device_extensions[] =
     {
diff --git a/libs/vkd3d-utils/vkd3d_utils_private.h b/libs/vkd3d-utils/vkd3d_utils_private.h
index 6aa0df6..9e4249c 100644
--- a/libs/vkd3d-utils/vkd3d_utils_private.h
+++ b/libs/vkd3d-utils/vkd3d_utils_private.h
@@ -20,7 +20,14 @@
 #define __VKD3D_UTILS_PRIVATE_H
 
 #define VK_NO_PROTOTYPES
+
+#include "config.h"
+
+#ifdef HAVE_MOLTENVK_VK_MVK_MOLTENVK_H
+#define VK_USE_PLATFORM_MACOS_MVK
+#elif defined(HAVE_XCB_XCB_H)
 #define VK_USE_PLATFORM_XCB_KHR
+#endif
 
 #include <pthread.h>
 #include <vkd3d.h>
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 6fa0017..4e5a9b0 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -212,9 +212,9 @@ static HRESULT vkd3d_init_vk_global_procs(struct vkd3d_instance *instance,
 
     if (!vkGetInstanceProcAddr)
     {
-        if (!(instance->libvulkan = dlopen("libvulkan.so.1", RTLD_NOW)))
+        if (!(instance->libvulkan = dlopen(SONAME_LIBVULKAN, RTLD_NOW)))
         {
-            ERR("Failed to load libvulkan.\n");
+            ERR("Failed to load libvulkan: %s\n", dlerror());
             return E_FAIL;
         }
 
diff --git a/m4/check-soname.m4 b/m4/check-soname.m4
new file mode 100644
index 0000000..0b231ff
--- /dev/null
+++ b/m4/check-soname.m4
@@ -0,0 +1,36 @@
+dnl
+dnl This file contains code derived from WINE_CHECK_SONAME() and is used courtesy of Alexandre Julliard.
+dnl
+
+dnl VKD3D_PATH_SONAME_TOOLS
+AC_DEFUN([VKD3D_PATH_SONAME_TOOLS],
+[AC_PATH_PROG(LDD,ldd,true,/sbin:/usr/sbin:$PATH)
+AC_CHECK_TOOL(OTOOL,otool,otool)
+AC_CHECK_TOOL(READELF,[readelf],true)])
+
+dnl VKD3D_CHECK_SONAME(library, function, [action-if-found, [action-if-not-found, [other_libraries, [pattern]]]])
+dnl
+AC_DEFUN([VKD3D_CHECK_SONAME],
+[AC_REQUIRE([VKD3D_PATH_SONAME_TOOLS])dnl
+AS_VAR_PUSHDEF([ac_Lib],[ac_cv_lib_soname_$1])dnl
+m4_pushdef([ac_lib_pattern],m4_default([$6],[lib$1]))dnl
+AC_MSG_CHECKING([for -l$1])
+AC_CACHE_VAL(ac_Lib,
+[ac_check_soname_save_LIBS=$LIBS
+  LIBS="-l$1 $5 $LIBS"
+  AC_LINK_IFELSE([AC_LANG_CALL([], [$2])],
+  [AS_CASE(["$host_os"],
+           [darwin*|macosx*], [AS_VAR_SET(ac_Lib,[`$OTOOL -L conftest$ac_exeext | grep "]ac_lib_pattern[\\.[[0-9A-Za-z.]]*dylib" | sed -e "s/^.*\/\(]ac_lib_pattern[\.[[0-9A-Za-z.]]*dylib\).*$/\1/"';2,$d'`])],
+           [AS_VAR_SET(ac_Lib,[`$READELF -d conftest$ac_exeext | grep "NEEDED.*]ac_lib_pattern[\\.$LIBEXT" | sed -e "s/^.*\\m4_dquote(\\(]ac_lib_pattern[\\.$LIBEXT[[^	 ]]*\\)\\).*$/\1/"';2,$d'`])
+            AS_VAR_IF([ac_Lib],[],
+                     [AS_VAR_SET(ac_Lib,[`$LDD conftest$ac_exeext | grep "]ac_lib_pattern[\\.$LIBEXT" | sed -e "s/^.*\(]ac_lib_pattern[\.$LIBEXT[[^	 ]]*\).*$/\1/"';2,$d'`])])])])
+  LIBS=$ac_check_soname_save_LIBS])dnl
+AS_VAR_IF([ac_Lib],[],
+      [AC_MSG_RESULT([not found])
+       $4],
+      [AC_MSG_RESULT(AS_VAR_GET(ac_Lib))
+       AC_DEFINE_UNQUOTED(AS_TR_CPP(SONAME_LIB$1),["]AS_VAR_GET(ac_Lib)["],
+                          [Define to the soname of the lib$1 library.])
+       $3])dnl
+m4_popdef([ac_lib_pattern])dnl
+AS_VAR_POPDEF([ac_Lib])])
diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c
index e2d9d01..dc253e9 100644
--- a/tests/vkd3d_api.c
+++ b/tests/vkd3d_api.c
@@ -19,8 +19,12 @@
 #define COBJMACROS
 #define INITGUID
 #define WIDL_C_INLINE_WRAPPERS
+#ifdef HAVE_MOLTENVK_VK_MVK_MOLTENVK_H
+#define VK_USE_PLATFORM_MACOS_MVK
+#else
 #define VK_USE_PLATFORM_XCB_KHR
 #define VK_USE_PLATFORM_XLIB_KHR
+#endif
 #include "vkd3d_test.h"
 #include <vkd3d.h>
 
@@ -215,8 +219,12 @@ static void test_additional_instance_extensions(void)
     struct vulkan_extension extensions[] =
     {
         {VK_KHR_SURFACE_EXTENSION_NAME},
+#ifdef HAVE_MOLTENVK_VK_MVK_MOLTENVK_H
+        {VK_MVK_MACOS_SURFACE_EXTENSION_NAME},
+#else
         {VK_KHR_XCB_SURFACE_EXTENSION_NAME},
         {VK_KHR_XLIB_SURFACE_EXTENSION_NAME},
+#endif
     };
 
     const char *enabled_extensions[ARRAY_SIZE(extensions)];
@@ -249,6 +257,13 @@ static void test_additional_instance_extensions(void)
         if (!extensions[i].is_supported)
             continue;
 
+#ifdef HAVE_MOLTENVK_VK_MVK_MOLTENVK_H
+        if (!strcmp(extensions[i].name, VK_MVK_MACOS_SURFACE_EXTENSION_NAME))
+        {
+            pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateMacOSSurfaceMVK");
+            ok(pfn, "Failed to get proc addr for vkCreateMacOSSurfaceMVK.\n");
+        }
+#else
         if (!strcmp(extensions[i].name, VK_KHR_XCB_SURFACE_EXTENSION_NAME))
         {
             pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateXcbSurfaceKHR");
@@ -259,6 +274,7 @@ static void test_additional_instance_extensions(void)
             pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateXlibSurfaceKHR");
             ok(pfn, "Failed to get proc addr for vkCreateXlibSurfaceKHR.\n");
         }
+#endif
     }
 
     refcount = vkd3d_instance_decref(instance);
-- 
2.18.0




More information about the wine-devel mailing list