From 8e899ccc29cc082f8d373718f1881ef5b8863f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 10 Jul 2017 17:07:59 +0200 Subject: [PATCH] Cocoa: Add support for MoltenVK dynamic library Tested with MoltenVK 0.18.0. Related to #870. --- CMake/modules/FindVulkan.cmake | 10 +++++----- README.md | 5 +++-- docs/vulkan.dox | 24 ++++++++++++++---------- include/GLFW/glfw3.h | 6 ------ src/vulkan.c | 11 +---------- tests/CMakeLists.txt | 6 ++++-- 6 files changed, 27 insertions(+), 35 deletions(-) diff --git a/CMake/modules/FindVulkan.cmake b/CMake/modules/FindVulkan.cmake index 078fd460..5bdb5560 100644 --- a/CMake/modules/FindVulkan.cmake +++ b/CMake/modules/FindVulkan.cmake @@ -28,12 +28,12 @@ if (WIN32) "$ENV{VK_SDK_PATH}/Bin32") endif() elseif (APPLE) + set(CMAKE_FIND_FRAMEWORK NEVER) find_library(VULKAN_LIBRARY MoltenVK) - if (VULKAN_LIBRARY) - set(VULKAN_STATIC_LIBRARY ${VULKAN_LIBRARY}) - find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS - "${VULKAN_LIBRARY}/Headers") - endif() + set(CMAKE_FIND_FRAMEWORK ONLY) + find_library(VULKAN_STATIC_LIBRARY MoltenVK) + find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS + "${VULKAN_LIBRARY}/Headers") else() find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS "$ENV{VULKAN_SDK}/include") diff --git a/README.md b/README.md index b2110b2c..685d927d 100644 --- a/README.md +++ b/README.md @@ -108,8 +108,9 @@ located in the `deps/` directory. - [Vulkan headers](https://www.khronos.org/registry/vulkan/) for Vulkan tests The Vulkan example additionally requires the Vulkan SDK to be installed, or it -will not be included in the build. On macOS you need to set the path to the -MoltenVK SDK manually as it has no standard location. +will not be included in the build. On macOS you need to +[provide the path](@ref vulkan_loader) to the MoltenVK SDK manually as it has no +standard installation location. The documentation is generated with [Doxygen](http://doxygen.org/). If CMake does not find Doxygen, the documentation will not be generated when you build. diff --git a/docs/vulkan.dox b/docs/vulkan.dox index 60d04941..7de9cd64 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -20,6 +20,11 @@ The GLFW library does not need the Vulkan SDK to enable support for Vulkan. However, any Vulkan-specific test and example programs are built only if the CMake files find a Vulkan SDK. +@macos Because MoltenVK is typically not installed system-wide, you will need to +point CMake to it using the `CMAKE_FRAMEWORK_PATH` variable when configuring the +GLFW source tree. Set this variable to the `MoltenVK/macOS` subdirectory of the +SDK, either on the command-line or in the CMake GUI. + For details on a specific function in this category, see the @ref vulkan. There are also guides for the other areas of the GLFW API. @@ -34,19 +39,18 @@ are also guides for the other areas of the GLFW API. By default, GLFW will look for the Vulkan loader on demand at runtime via its standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other -Unix-like systems). This means that GLFW does not need to be linked against the -loader. However, it also means that if you are using the static library form of -the Vulkan loader GLFW will either fail to find it or (worse) use the wrong one. +Unix-like systems and `libMoltenVK.dylib` on macOS). This means that GLFW does +not need to be linked against the loader. However, it also means that if you +are using the static library form of the Vulkan loader GLFW will either fail to +find it or (worse) use the wrong one. The @ref GLFW_VULKAN_STATIC CMake option makes GLFW link directly against the -static form. Not linking against the Vulkan loader will then be a compile-time -error. +static library form. Not linking against the Vulkan loader will then be +a compile-time error. -@macos MoltenVK only provides the static library form of the Vulkan loader, but -GLFW is able to find it without @ref GLFW_VULKAN_STATIC as long as it is linked -into any of the binaries already loaded into the process. As it is a static -library, you must also link against its dependencies: the `Cocoa`, `Metal` and -`QuartzCore` frameworks and the `libc++` library. +@macos When using the static library form of MoltenVK (i.e. `MetalVK.framework` +and not `libMoltenVK.dylib`) you must also link against its dependencies: the +`Cocoa`, `Metal` and `QuartzCore` system frameworks and the `libc++` library. @section vulkan_include Including the Vulkan and GLFW header files diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index e396006a..04b79ca4 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -211,13 +211,7 @@ extern "C" { #endif /* OpenGL and OpenGL ES headers */ #if defined(GLFW_INCLUDE_VULKAN) - - #if defined(__APPLE__) - #include - #else #include - #endif - #endif /* Vulkan header */ #if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) diff --git a/src/vulkan.c b/src/vulkan.c index 858a1e97..f2473cf6 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -52,8 +52,7 @@ GLFWbool _glfwInitVulkan(int mode) #if defined(_GLFW_WIN32) _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll"); #elif defined(_GLFW_COCOA) - // NULL maps to RTLD_DEFAULT, which searches all loaded binaries - _glfw.vk.handle = _glfw_dlopen(NULL); + _glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib"); #else _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1"); #endif @@ -69,16 +68,8 @@ GLFWbool _glfwInitVulkan(int mode) _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr"); if (!_glfw.vk.GetInstanceProcAddr) { -#if defined(_GLFW_COCOA) - if (mode == _GLFW_REQUIRE_LOADER) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "Vulkan: vkGetInstanceProcAddr not found in process"); - } -#else _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader does not export vkGetInstanceProcAddr"); -#endif _glfwTerminateVulkan(); return GLFW_FALSE; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9f56bcb7..56d871b8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -53,8 +53,10 @@ set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen if (VULKAN_FOUND) add_executable(vulkan WIN32 vulkan.c ${ICON}) target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}") - if (NOT GLFW_VULKAN_STATIC) - target_link_libraries(vulkan "${VULKAN_LIBRARY}" ${GLFW_VULKAN_DEPS}) + if (GLFW_VULKAN_STATIC) + target_link_libraries(vulkan "${VULKAN_STATIC_LIBRARY}" ${GLFW_VULKAN_DEPS}) + else() + target_link_libraries(vulkan "${VULKAN_LIBRARY}") endif() list(APPEND WINDOWS_BINARIES vulkan) endif()