Cocoa: Add fully dynamic loading of Vulkan loader

If the application is not linked against the Vulkan loader and relies on
a third-party loader library or glfwGetInstanceProcAddress, then our
call to dlopen will fail without a custom dyld environment variable.

This adds a fallback of looking in the directory of the main executable,
which matches the bundle structure recommended by the Vulkan SDK, making
that finally work out of the box for fully dynamic loading.
This commit is contained in:
Camilla Löwy 2020-01-16 05:09:19 +01:00
parent 15d91801b7
commit 7da87aaae7
4 changed files with 31 additions and 0 deletions

View File

@ -142,6 +142,7 @@ information on what to include when reporting a bug.
window (#1499) window (#1499)
- [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions - [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
- [Cocoa] Removed dependency on the CoreVideo framework - [Cocoa] Removed dependency on the CoreVideo framework
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553) - [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll - [Cocoa] Bugfix: Window remained on screen after destruction until event poll

View File

@ -463,6 +463,32 @@ static GLFWbool initializeTIS(void)
@end // GLFWApplicationDelegate @end // GLFWApplicationDelegate
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwLoadLocalVulkanLoaderNS(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef url =
CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib"));
if (!url)
return NULL;
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfw_dlopen(path);
CFRelease(url);
return handle;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -207,3 +207,5 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
float _glfwTransformYNS(float y); float _glfwTransformYNS(float y);
void* _glfwLoadLocalVulkanLoaderNS(void);

View File

@ -57,6 +57,8 @@ GLFWbool _glfwInitVulkan(int mode)
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll"); _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib"); _glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
if (!_glfw.vk.handle)
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
#else #else
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1"); _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
#endif #endif