mirror of https://github.com/encounter/SDL.git
Support official Vulkan SDK for macOS.
This tries to load vulkan.framework or libvulkan.1.dylib before MoltenVK.framework or libMoltenVK.dylib. In the previous version, layers would not work for applications run-time loading the default library.
This commit is contained in:
parent
f9f45d0bf5
commit
be6ca785e3
|
@ -69,30 +69,43 @@ typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
|
||||||
* \brief Dynamically load a Vulkan loader library.
|
* \brief Dynamically load a Vulkan loader library.
|
||||||
*
|
*
|
||||||
* \param [in] path The platform dependent Vulkan loader library name, or
|
* \param [in] path The platform dependent Vulkan loader library name, or
|
||||||
* \c NULL to open the default Vulkan loader library.
|
* \c NULL.
|
||||||
*
|
*
|
||||||
* \return \c 0 on success, or \c -1 if the library couldn't be loaded.
|
* \return \c 0 on success, or \c -1 if the library couldn't be loaded.
|
||||||
*
|
*
|
||||||
* This should be done after initializing the video driver, but before
|
* If \a path is NULL SDL will use the value of the environment variable
|
||||||
|
* \c SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan
|
||||||
|
* loader library.
|
||||||
|
*
|
||||||
|
* This should be called after initializing the video driver, but before
|
||||||
* creating any Vulkan windows. If no Vulkan loader library is loaded, the
|
* creating any Vulkan windows. If no Vulkan loader library is loaded, the
|
||||||
* default library will be loaded upon creation of the first Vulkan window.
|
* default library will be loaded upon creation of the first Vulkan window.
|
||||||
*
|
*
|
||||||
* \note If you specify a non-NULL \a path, you should retrieve all of the
|
* \note It is fairly common for Vulkan applications to link with \a libvulkan
|
||||||
* Vulkan functions used in your program from the dynamic library using
|
* instead of explicitly loading it at run time. This will work with
|
||||||
|
* SDL provided the application links to a dynamic library and both it
|
||||||
|
* and SDL use the same search path.
|
||||||
|
*
|
||||||
|
* \note If you specify a non-NULL \c path, an application should retrieve all
|
||||||
|
* of the Vulkan functions it uses from the dynamic library using
|
||||||
* \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
|
* \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
|
||||||
* \a path points to the same vulkan loader library that you linked to.
|
* \c path points to the same vulkan loader library the application
|
||||||
|
* linked to.
|
||||||
*
|
*
|
||||||
* \note On Apple devices, if \a path is NULL, SDL will attempt to find
|
* \note On Apple devices, if \a path is NULL, SDL will attempt to find
|
||||||
* the vkGetInstanceProcAddr address within all the mach-o images of
|
* the vkGetInstanceProcAddr address within all the mach-o images of
|
||||||
* the current process. This is because the currently (v0.17.0)
|
* the current process. This is because it is fairly common for Vulkan
|
||||||
* recommended MoltenVK (Vulkan on Metal) usage is as a static library.
|
* applications to link with libvulkan (and historically MoltenVK was
|
||||||
* If it is not found then SDL will attempt to load \c libMoltenVK.dylib.
|
* provided as a static library). If it is not found then, on macOS, SDL
|
||||||
* Applications using the dylib alternative therefore do not need to do
|
* will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib,
|
||||||
* anything special when calling SDL.
|
* \c MoltenVK.framework/MoltenVK and \c libMoltenVK.dylib in that order.
|
||||||
|
* On iOS SDL will attempt to load \c libMoltenVK.dylib. Applications
|
||||||
|
* using a dynamic framework or .dylib must ensure it is included in its
|
||||||
|
* application bundle.
|
||||||
*
|
*
|
||||||
* \note On non-Apple devices, SDL requires you to either not link to the
|
* \note On non-Apple devices, application linking with a static libvulkan is
|
||||||
* Vulkan loader or link to a dynamic library version. This limitation
|
* not supported. Either do not link to the Vulkan loader or link to a
|
||||||
* may be removed in a future version of SDL.
|
* dynamic library version.
|
||||||
*
|
*
|
||||||
* \note This function will fail if there are no working Vulkan drivers
|
* \note This function will fail if there are no working Vulkan drivers
|
||||||
* installed.
|
* installed.
|
||||||
|
|
|
@ -39,7 +39,13 @@
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#define DEFAULT_MOLTENVK "libMoltenVK.dylib"
|
const char* defaultPaths[] = {
|
||||||
|
"vulkan.framework/vulkan",
|
||||||
|
"libvulkan.1.dylib",
|
||||||
|
"MoltenVK.framework/MoltenVK",
|
||||||
|
"libMoltenVK.dylib"
|
||||||
|
};
|
||||||
|
|
||||||
/* Since libSDL is most likely a .dylib, need RTLD_DEFAULT not RTLD_SELF. */
|
/* Since libSDL is most likely a .dylib, need RTLD_DEFAULT not RTLD_SELF. */
|
||||||
#define DEFAULT_HANDLE RTLD_DEFAULT
|
#define DEFAULT_HANDLE RTLD_DEFAULT
|
||||||
|
|
||||||
|
@ -52,7 +58,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
||||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
|
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
|
||||||
|
|
||||||
if (_this->vulkan_config.loader_handle) {
|
if (_this->vulkan_config.loader_handle) {
|
||||||
SDL_SetError("MoltenVK/Vulkan already loaded");
|
SDL_SetError("Vulkan/MoltenVK already loaded");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +66,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
||||||
if (!path) {
|
if (!path) {
|
||||||
path = SDL_getenv("SDL_VULKAN_LIBRARY");
|
path = SDL_getenv("SDL_VULKAN_LIBRARY");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
/* MoltenVK framework, currently, v0.17.0, has a static library and is
|
/* MoltenVK framework, currently, v0.17.0, has a static library and is
|
||||||
* the recommended way to use the package. There is likely no object to
|
* the recommended way to use the package. There is likely no object to
|
||||||
|
@ -72,16 +79,31 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
||||||
if (vkGetInstanceProcAddr) {
|
if (vkGetInstanceProcAddr) {
|
||||||
_this->vulkan_config.loader_handle = DEFAULT_HANDLE;
|
_this->vulkan_config.loader_handle = DEFAULT_HANDLE;
|
||||||
} else {
|
} else {
|
||||||
if (!path) {
|
const char** paths;
|
||||||
/* Look for the .dylib packaged with the application instead. */
|
int numPaths;
|
||||||
path = DEFAULT_MOLTENVK;
|
int i;
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
paths = &path;
|
||||||
|
numPaths = 1;
|
||||||
|
} else {
|
||||||
|
/* Look for framework or .dylib packaged with the application
|
||||||
|
* instead. */
|
||||||
|
paths = defaultPaths;
|
||||||
|
numPaths = SDL_arraysize(defaultPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
|
for (i=0; i < numPaths; i++) {
|
||||||
if (!_this->vulkan_config.loader_handle) {
|
_this->vulkan_config.loader_handle = SDL_LoadObject(paths[i]);
|
||||||
return -1;
|
if (_this->vulkan_config.loader_handle)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
SDL_strlcpy(_this->vulkan_config.loader_path, path,
|
if (i == numPaths)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
SDL_strlcpy(_this->vulkan_config.loader_path, paths[i],
|
||||||
SDL_arraysize(_this->vulkan_config.loader_path));
|
SDL_arraysize(_this->vulkan_config.loader_path));
|
||||||
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
|
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
|
||||||
_this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
|
_this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
|
||||||
|
@ -90,7 +112,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
||||||
if (!vkGetInstanceProcAddr) {
|
if (!vkGetInstanceProcAddr) {
|
||||||
SDL_SetError("Failed to find %s in either executable or %s: %s",
|
SDL_SetError("Failed to find %s in either executable or %s: %s",
|
||||||
"vkGetInstanceProcAddr",
|
"vkGetInstanceProcAddr",
|
||||||
DEFAULT_MOLTENVK,
|
_this->vulkan_config.loader_path,
|
||||||
(const char *) dlerror());
|
(const char *) dlerror());
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue