From f6901e4a3df2bd9ea560033a1391287ac0a904ea Mon Sep 17 00:00:00 2001 From: Luflosi Date: Fri, 17 Jan 2020 13:14:32 +0100 Subject: [PATCH] Cocoa: Add support for VK_EXT_metal_surface From upstream: https://github.com/glfw/glfw/commit/c5cb4a253a9c304b136cac01a378567dc46e0320. --- glfw/cocoa_platform.h | 21 ++++++++++++++++++++- glfw/cocoa_window.m | 38 ++++++++++++++++++++++++++++++++++++-- glfw/glfw3.h | 5 +++-- glfw/internal.h | 5 +++++ glfw/vulkan.c | 5 +++++ 5 files changed, 69 insertions(+), 5 deletions(-) diff --git a/glfw/cocoa_platform.h b/glfw/cocoa_platform.h index 32c16292b..f874a8da8 100644 --- a/glfw/cocoa_platform.h +++ b/glfw/cocoa_platform.h @@ -65,13 +65,15 @@ typedef void* CVDisplayLinkRef; #endif -typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int, unsigned long); typedef bool (* GLFWapplicationshouldhandlereopenfun)(int); typedef void (* GLFWapplicationwillfinishlaunchingfun)(void); typedef bool (* GLFWcocoatogglefullscreenfun)(GLFWwindow*); typedef void (* GLFWcocoarenderframefun)(GLFWwindow*); +#if defined(VK_USE_PLATFORM_MACOS_MVK) +typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; + typedef struct VkMacOSSurfaceCreateInfoMVK { VkStructureType sType; @@ -82,6 +84,23 @@ typedef struct VkMacOSSurfaceCreateInfoMVK typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*); +#elif defined(VK_USE_PLATFORM_METAL_EXT) +#define VK_EXT_metal_surface 1 +typedef void CAMetalLayer; + +#define VK_EXT_METAL_SURFACE_SPEC_VERSION 1 +#define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface" +typedef VkFlags VkMetalSurfaceCreateFlagsEXT; +typedef struct VkMetalSurfaceCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkMetalSurfaceCreateFlagsEXT flags; + const CAMetalLayer* pLayer; +} VkMetalSurfaceCreateInfoEXT; + +typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance, const VkMetalSurfaceCreateInfoEXT*, const VkAllocationCallbacks*, VkSurfaceKHR*); +#endif + #include "posix_thread.h" #include "cocoa_joystick.h" #include "nsgl_context.h" diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index e431995b1..3749abaae 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -2079,11 +2079,19 @@ const char* _glfwPlatformGetClipboardString(void) void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) { +#if defined(VK_USE_PLATFORM_MACOS_MVK) if (!_glfw.vk.KHR_surface || !_glfw.vk.MVK_macos_surface) return; extensions[0] = "VK_KHR_surface"; extensions[1] = "VK_MVK_macos_surface"; + +#elif defined(VK_USE_PLATFORM_METAL_EXT) + if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_metal_surface) + return; + extensions[0] = "VK_KHR_surface"; + extensions[1] = "VK_EXT_metal_surface"; +#endif } int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance UNUSED, @@ -2100,9 +2108,11 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 VkResult err; - VkMacOSSurfaceCreateInfoMVK sci; - PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK; +#if defined(VK_USE_PLATFORM_MACOS_MVK) + VkMacOSSurfaceCreateInfoMVK sci; + + PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK; vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK) vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK"); if (!vkCreateMacOSSurfaceMVK) @@ -2112,6 +2122,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, return VK_ERROR_EXTENSION_NOT_PRESENT; } +#elif defined(VK_USE_PLATFORM_METAL_EXT) + VkMetalSurfaceCreateInfoEXT sci; + + PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT; + vkCreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT) + vkGetInstanceProcAddr(instance, "vkCreateMetalSurfaceEXT"); + if (!vkCreateMetalSurfaceEXT) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Cocoa: Vulkan instance missing VK_EXT_metal_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } +#endif + // HACK: Dynamically load Core Animation to avoid adding an extra // dependency for the majority who don't use MoltenVK NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"]; @@ -2138,10 +2162,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, [window->ns.view setWantsLayer:YES]; memset(&sci, 0, sizeof(sci)); +#if defined(VK_USE_PLATFORM_MACOS_MVK) sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; sci.pView = window->ns.view; err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface); + +#elif defined(VK_USE_PLATFORM_METAL_EXT) + sci.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + sci.pNext = NULL; + sci.flags = 0; + sci.pLayer = window->ns.layer; + + err = vkCreateMetalSurfaceEXT(instance, &sci, allocator, surface); +#endif if (err) { _glfwInputError(GLFW_PLATFORM_ERROR, diff --git a/glfw/glfw3.h b/glfw/glfw3.h index acc9f6844..3822e3754 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -5566,8 +5566,9 @@ GLFWAPI int glfwVulkanSupported(void); * returned array, as it is an error to specify an extension more than once in * the `VkInstanceCreateInfo` struct. * - * @remark @macos This function currently only supports the - * `VK_MVK_macos_surface` extension from MoltenVK. + * @remark @macos This function currently supports either the + * `VK_MVK_macos_surface` extension from MoltenVK or `VK_EXT_metal_surface` + * extension. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the diff --git a/glfw/internal.h b/glfw/internal.h index 17a7b5446..047296443 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -132,6 +132,7 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, + VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -587,7 +588,11 @@ struct _GLFWlibrary #if defined(_GLFW_WIN32) bool KHR_win32_surface; #elif defined(_GLFW_COCOA) + #if defined(VK_USE_PLATFORM_MACOS_MVK) bool MVK_macos_surface; + #elif defined(VK_USE_PLATFORM_METAL_EXT) + bool EXT_metal_surface; + #endif #elif defined(_GLFW_X11) bool KHR_xlib_surface; bool KHR_xcb_surface; diff --git a/glfw/vulkan.c b/glfw/vulkan.c index 421248bc4..7827a0d7c 100644 --- a/glfw/vulkan.c +++ b/glfw/vulkan.c @@ -128,8 +128,13 @@ bool _glfwInitVulkan(int mode) else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) _glfw.vk.KHR_win32_surface = true; #elif defined(_GLFW_COCOA) + #if defined(VK_USE_PLATFORM_MACOS_MVK) else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0) _glfw.vk.MVK_macos_surface = true; + #elif defined(VK_USE_PLATFORM_METAL_EXT) + else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0) + _glfw.vk.EXT_metal_surface = true; + #endif #elif defined(_GLFW_X11) else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) _glfw.vk.KHR_xlib_surface = true;