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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h
index 0ab84cb..c494b2e 100644
--- a/include/SDL_config_macosx.h
+++ b/include/SDL_config_macosx.h
@@ -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
diff --git a/include/SDL_vulkan.h b/include/SDL_vulkan.h
index 972cca4..d69a436 100644
--- a/include/SDL_vulkan.h
+++ b/include/SDL_vulkan.h
@@ -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.
*
@@ -153,7 +153,7 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
* is smaller than the number of required extensions, \c SDL_FALSE will be
* returned instead of \c SDL_TRUE, to indicate that not all the required
* extensions were returned.
- *
+ *
* \note If \c window is not NULL, it will be checked against its creation
* flags to ensure that the Vulkan flag is present. This parameter
* will be removed in a future major release.
diff --git a/src/video/cocoa/SDL_cocoavulkan.m b/src/video/cocoa/SDL_cocoavulkan.m
index 38c9b5c..4801d76 100644
--- a/src/video/cocoa/SDL_cocoavulkan.m
+++ b/src/video/cocoa/SDL_cocoavulkan.m
@@ -19,7 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/
-/*
+/*
* @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
@@ -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;
}
diff --git a/src/video/uikit/SDL_uikitvulkan.m b/src/video/uikit/SDL_uikitvulkan.m
index a436133..c4b779d 100644
--- a/src/video/uikit/SDL_uikitvulkan.m
+++ b/src/video/uikit/SDL_uikitvulkan.m
@@ -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);
+ }
+
+ for (i = 0; i < numPaths && _this->vulkan_config.loader_handle == NULL; i++) {
+ foundPath = paths[i];
+ _this->vulkan_config.loader_handle = SDL_LoadObject(foundPath);
}
- _this->vulkan_config.loader_handle = SDL_LoadObject(path);
- if (!_this->vulkan_config.loader_handle) {
- return -1;
+ 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;
}