mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-04 01:34:38 +00:00 
			
		
		
		
	Fixed bug 4570 - Support Vulkan Portability rather than MoltenVK specifically
Dzmitry Malyshau
Current code, search paths, and error messages are written to only consider MoltenVK on macOS as a Vulkan Portability implementation. It's not the only implementation available to the users. gfx-portability [1] has been shown to run a number of titles well, including Dota2, Dolphin Emulator, and vkQuake3, often out-performing MoltenVK in frame rate and stability (see Dolphin benchmark [2]).
There is no reason for SDL to be that specific, it's not using any MVK-specific functions other than the WSI initialization ("VK_MVK_macos_surface"). gfx-portability exposes this extension as well, and a more generic WSI extension is in process. It would be good if SDL was written in a more generic way that expect a Vulkan Portability library as opposed to MoltenVK specifically.
[1] https://github.com/gfx-rs/portability
[2] https://gfx-rs.github.io/2019/03/22/dolphin-macos-performance.html
			
			
This commit is contained in:
		@@ -218,7 +218,7 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Enable Vulkan support */
 | 
			
		||||
/* Metal/MoltenVK/Vulkan only supported on 64-bit architectures with 10.11+ */
 | 
			
		||||
/* Metal/Vulkan Portability only supported on 64-bit architectures with 10.11+ */
 | 
			
		||||
#if TARGET_CPU_X86_64 && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100)
 | 
			
		||||
#define SDL_VIDEO_VULKAN 1
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -98,8 +98,8 @@ typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
 | 
			
		||||
 *        applications to link with libvulkan (and historically MoltenVK was
 | 
			
		||||
 *        provided as a static library). If it is not found then, on macOS, SDL
 | 
			
		||||
 *        will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib,
 | 
			
		||||
 *        \c MoltenVK.framework/MoltenVK and \c libMoltenVK.dylib in that order.
 | 
			
		||||
 *        On iOS SDL will attempt to load \c libMoltenVK.dylib. Applications
 | 
			
		||||
 *        followed by \c libvulkan.dylib, in that order.
 | 
			
		||||
 *        On iOS SDL will attempt to load \c libvulkan.dylib only. Applications
 | 
			
		||||
 *        using a dynamic framework or .dylib must ensure it is included in its
 | 
			
		||||
 *        application bundle.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,7 @@
 | 
			
		||||
const char* defaultPaths[] = {
 | 
			
		||||
    "vulkan.framework/vulkan",
 | 
			
		||||
    "libvulkan.1.dylib",
 | 
			
		||||
    "libvulkan.dylib",
 | 
			
		||||
    "MoltenVK.framework/MoltenVK",
 | 
			
		||||
    "libMoltenVK.dylib"
 | 
			
		||||
};
 | 
			
		||||
@@ -58,7 +59,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
 | 
			
		||||
 | 
			
		||||
    if (_this->vulkan_config.loader_handle) {
 | 
			
		||||
        return SDL_SetError("Vulkan/MoltenVK already loaded");
 | 
			
		||||
        return SDL_SetError("Vulkan Portability library is already loaded.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Load the Vulkan loader library */
 | 
			
		||||
@@ -67,9 +68,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!path) {
 | 
			
		||||
        /* 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
 | 
			
		||||
         * load. */
 | 
			
		||||
        /* Handle the case where Vulkan Portability is linked statically. */
 | 
			
		||||
        vkGetInstanceProcAddr =
 | 
			
		||||
         (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
 | 
			
		||||
                                          "vkGetInstanceProcAddr");
 | 
			
		||||
@@ -99,7 +98,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (_this->vulkan_config.loader_handle == NULL) {
 | 
			
		||||
            return SDL_SetError("Failed to load Vulkan/MoltenVK library");
 | 
			
		||||
            return SDL_SetError("Failed to load Vulkan Portability library");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SDL_strlcpy(_this->vulkan_config.loader_path, foundPath,
 | 
			
		||||
@@ -139,11 +138,11 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free(extensions);
 | 
			
		||||
    if (!hasSurfaceExtension) {
 | 
			
		||||
        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
 | 
			
		||||
        SDL_SetError("Installed Vulkan Portability library doesn't implement the "
 | 
			
		||||
                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    } else if (!hasMacOSSurfaceExtension) {
 | 
			
		||||
        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
 | 
			
		||||
        SDL_SetError("Installed Vulkan Portability library doesn't implement the "
 | 
			
		||||
                     VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,10 @@
 | 
			
		||||
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_MOLTENVK  "libMoltenVK.dylib"
 | 
			
		||||
const char* defaultPaths[] = {
 | 
			
		||||
    "libvulkan.dylib",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Since libSDL is static, could use RTLD_SELF. Using RTLD_DEFAULT is future
 | 
			
		||||
 * proofing. */
 | 
			
		||||
#define DEFAULT_HANDLE RTLD_DEFAULT
 | 
			
		||||
@@ -53,7 +56,7 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
 | 
			
		||||
 | 
			
		||||
    if (_this->vulkan_config.loader_handle) {
 | 
			
		||||
        return SDL_SetError("MoltenVK/Vulkan already loaded");
 | 
			
		||||
        return SDL_SetError("Vulkan Portability library is already loaded.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Load the Vulkan loader library */
 | 
			
		||||
@@ -62,9 +65,7 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!path) {
 | 
			
		||||
        /* 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
 | 
			
		||||
         * load. */
 | 
			
		||||
        /* Handle the case where Vulkan Portability is linked statically. */
 | 
			
		||||
        vkGetInstanceProcAddr =
 | 
			
		||||
        (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
 | 
			
		||||
                                         "vkGetInstanceProcAddr");
 | 
			
		||||
@@ -73,15 +74,29 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    if (vkGetInstanceProcAddr) {
 | 
			
		||||
        _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!path) {
 | 
			
		||||
        const char** paths;
 | 
			
		||||
        const char *foundPath = NULL;
 | 
			
		||||
        int numPaths;
 | 
			
		||||
        int i;
 | 
			
		||||
 | 
			
		||||
        if (path) {
 | 
			
		||||
            paths = &path;
 | 
			
		||||
            numPaths = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            /* Look for the .dylib packaged with the application instead. */
 | 
			
		||||
            path = DEFAULT_MOLTENVK;
 | 
			
		||||
            paths = defaultPaths;
 | 
			
		||||
            numPaths = SDL_arraysize(defaultPaths);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _this->vulkan_config.loader_handle = SDL_LoadObject(path);
 | 
			
		||||
        if (!_this->vulkan_config.loader_handle) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        for (i = 0; i < numPaths && _this->vulkan_config.loader_handle == NULL; i++) {
 | 
			
		||||
            foundPath = paths[i];
 | 
			
		||||
            _this->vulkan_config.loader_handle = SDL_LoadObject(foundPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (_this->vulkan_config.loader_handle == NULL) {
 | 
			
		||||
            return SDL_SetError("Failed to load Vulkan Portability library");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SDL_strlcpy(_this->vulkan_config.loader_path, path,
 | 
			
		||||
                    SDL_arraysize(_this->vulkan_config.loader_path));
 | 
			
		||||
        vkGetInstanceProcAddr =
 | 
			
		||||
@@ -93,7 +108,7 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    if (!vkGetInstanceProcAddr) {
 | 
			
		||||
        SDL_SetError("Failed to find %s in either executable or %s: %s",
 | 
			
		||||
                     "vkGetInstanceProcAddr",
 | 
			
		||||
                     DEFAULT_MOLTENVK,
 | 
			
		||||
                     "linked Vulkan Portability library",
 | 
			
		||||
                     (const char *) dlerror());
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
@@ -128,11 +143,11 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
 | 
			
		||||
    SDL_free(extensions);
 | 
			
		||||
 | 
			
		||||
    if (!hasSurfaceExtension) {
 | 
			
		||||
        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
 | 
			
		||||
        SDL_SetError("Installed Vulkan Portability doesn't implement the "
 | 
			
		||||
                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    } else if (!hasIOSSurfaceExtension) {
 | 
			
		||||
        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
 | 
			
		||||
        SDL_SetError("Installed Vulkan Portability doesn't implement the "
 | 
			
		||||
                     VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user