| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> |
| | | |
| | | This software is provided 'as-is', without any express or implied |
| | | warranty. In no event will the authors be held liable for any damages |
| | |
| | | 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. |
| | | */ |
| | | |
| | | #include "../../SDL_internal.h" |
| | | |
| | | #if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_COCOA |
| | |
| | | const char* defaultPaths[] = { |
| | | "vulkan.framework/vulkan", |
| | | "libvulkan.1.dylib", |
| | | "libvulkan.dylib", |
| | | "MoltenVK.framework/MoltenVK", |
| | | "libMoltenVK.dylib" |
| | | }; |
| | |
| | | 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 */ |
| | |
| | | } |
| | | |
| | | 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"); |
| | |
| | | } |
| | | |
| | | 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, |
| | |
| | | } |
| | | 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; |
| | | } |
| | |
| | | "vkCreateMacOSSurfaceMVK"); |
| | | VkMacOSSurfaceCreateInfoMVK createInfo = {}; |
| | | VkResult result; |
| | | SDL_MetalView metalview; |
| | | |
| | | if (!_this->vulkan_config.loader_handle) { |
| | | SDL_SetError("Vulkan is not loaded"); |
| | |
| | | " extension is not enabled in the Vulkan instance."); |
| | | return SDL_FALSE; |
| | | } |
| | | |
| | | metalview = Cocoa_Metal_CreateView(_this, window); |
| | | if (metalview == NULL) { |
| | | return SDL_FALSE; |
| | | } |
| | | |
| | | createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; |
| | | createInfo.pNext = NULL; |
| | | createInfo.flags = 0; |
| | | createInfo.pView = Cocoa_Mtl_AddMetalView(window); |
| | | createInfo.pView = (const void *)metalview; |
| | | result = vkCreateMacOSSurfaceMVK(instance, &createInfo, |
| | | NULL, surface); |
| | | if (result != VK_SUCCESS) { |
| | | Cocoa_Metal_DestroyView(_this, metalview); |
| | | SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", |
| | | SDL_Vulkan_GetResultString(result)); |
| | | return SDL_FALSE; |
| | | } |
| | | |
| | | /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call |
| | | * Metal_DestroyView from. Right now the metal view's ref count is +2 (one |
| | | * from returning a new view object in CreateView, and one because it's |
| | | * a subview of the window.) If we release the view here to make it +1, it |
| | | * will be destroyed when the window is destroyed. */ |
| | | CFBridgingRelease(metalview); |
| | | |
| | | return SDL_TRUE; |
| | | } |
| | | |
| | | void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) |
| | | { |
| | | Cocoa_Mtl_GetDrawableSize(window, w, h); |
| | | Cocoa_Metal_GetDrawableSize(window, w, h); |
| | | } |
| | | |
| | | #endif |