Commit 50f3979d authored by ByunghoonKim's avatar ByunghoonKim Committed by Camilla Löwy
Browse files

Cocoa: Add support for VK_EXT_metal_surface

This adds optional support for the VK_EXT_metal_surface instance
extension.

Closes #1619.

(cherry picked from commit c5cb4a253a9c304b136cac01a378567dc46e0320)
parent 977e2b51
...@@ -145,6 +145,8 @@ elseif (WIN32) ...@@ -145,6 +145,8 @@ elseif (WIN32)
elseif (APPLE) elseif (APPLE)
set(_GLFW_COCOA 1) set(_GLFW_COCOA 1)
message(STATUS "Using Cocoa for window creation") message(STATUS "Using Cocoa for window creation")
set(VK_USE_PLATFORM_METAL_EXT 1)
message(STATUS "Using VK_EXT_metal_surface")
elseif (UNIX) elseif (UNIX)
set(_GLFW_X11 1) set(_GLFW_X11 1)
message(STATUS "Using X11 for window creation") message(STATUS "Using X11 for window creation")
......
...@@ -266,10 +266,10 @@ surfaces on Microsoft Windows. If any of these extensions are not available, ...@@ -266,10 +266,10 @@ surfaces on Microsoft Windows. If any of these extensions are not available,
@ref glfwGetRequiredInstanceExtensions will return an empty list and window @ref glfwGetRequiredInstanceExtensions will return an empty list and window
surface creation will fail. surface creation will fail.
GLFW uses the `VK_KHR_surface` and `VK_MVK_macos_surface` extensions to create GLFW uses the `VK_KHR_surface` and either the `VK_MVK_macos_surface` or
surfaces on macOS. If any of these extensions are not available, @ref `VK_EXT_metal_surface` extensions to create surfaces on macOS. If any of these
glfwGetRequiredInstanceExtensions will return an empty list and window surface extensions are not available, @ref glfwGetRequiredInstanceExtensions will
creation will fail. return an empty list and window surface creation will fail.
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface` `VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
......
...@@ -5677,8 +5677,9 @@ GLFWAPI int glfwVulkanSupported(void); ...@@ -5677,8 +5677,9 @@ GLFWAPI int glfwVulkanSupported(void);
* returned array, as it is an error to specify an extension more than once in * returned array, as it is an error to specify an extension more than once in
* the `VkInstanceCreateInfo` struct. * the `VkInstanceCreateInfo` struct.
* *
* @remark @macos This function currently only supports the * @remark @macos This function currently supports either the
* `VK_MVK_macos_surface` extension from MoltenVK. * `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 * @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 * should not free it yourself. It is guaranteed to be valid only until the
......
...@@ -60,6 +60,7 @@ typedef void* id; ...@@ -60,6 +60,7 @@ typedef void* id;
#define NSWindowStyleMaskTitled NSTitledWindowMask #define NSWindowStyleMaskTitled NSTitledWindowMask
#endif #endif
#if defined(VK_USE_PLATFORM_MACOS_MVK)
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef struct VkMacOSSurfaceCreateInfoMVK typedef struct VkMacOSSurfaceCreateInfoMVK
...@@ -72,6 +73,23 @@ typedef struct VkMacOSSurfaceCreateInfoMVK ...@@ -72,6 +73,23 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*); 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 "posix_thread.h"
#include "cocoa_joystick.h" #include "cocoa_joystick.h"
#include "nsgl_context.h" #include "nsgl_context.h"
......
...@@ -1689,11 +1689,19 @@ const char* _glfwPlatformGetClipboardString(void) ...@@ -1689,11 +1689,19 @@ const char* _glfwPlatformGetClipboardString(void)
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
{ {
#if defined(VK_USE_PLATFORM_MACOS_MVK)
if (!_glfw.vk.KHR_surface || !_glfw.vk.MVK_macos_surface) if (!_glfw.vk.KHR_surface || !_glfw.vk.MVK_macos_surface)
return; return;
extensions[0] = "VK_KHR_surface"; extensions[0] = "VK_KHR_surface";
extensions[1] = "VK_MVK_macos_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, int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
...@@ -1712,9 +1720,11 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, ...@@ -1712,9 +1720,11 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
VkResult err; VkResult err;
#if defined(VK_USE_PLATFORM_MACOS_MVK)
VkMacOSSurfaceCreateInfoMVK sci; VkMacOSSurfaceCreateInfoMVK sci;
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK) vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK"); vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
if (!vkCreateMacOSSurfaceMVK) if (!vkCreateMacOSSurfaceMVK)
...@@ -1724,6 +1734,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, ...@@ -1724,6 +1734,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
return VK_ERROR_EXTENSION_NOT_PRESENT; 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 // HACK: Dynamically load Core Animation to avoid adding an extra
// dependency for the majority who don't use MoltenVK // dependency for the majority who don't use MoltenVK
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"]; NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
...@@ -1750,10 +1774,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, ...@@ -1750,10 +1774,20 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
[window->ns.view setWantsLayer:YES]; [window->ns.view setWantsLayer:YES];
memset(&sci, 0, sizeof(sci)); memset(&sci, 0, sizeof(sci));
#if defined(VK_USE_PLATFORM_MACOS_MVK)
sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
sci.pView = window->ns.view; sci.pView = window->ns.view;
err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface); 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) if (err)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#cmakedefine _GLFW_WIN32 #cmakedefine _GLFW_WIN32
// Define this to 1 if building GLFW for Cocoa // Define this to 1 if building GLFW for Cocoa
#cmakedefine _GLFW_COCOA #cmakedefine _GLFW_COCOA
#cmakedefine VK_USE_PLATFORM_METAL_EXT
// Define this to 1 if building GLFW for Wayland // Define this to 1 if building GLFW for Wayland
#cmakedefine _GLFW_WAYLAND #cmakedefine _GLFW_WAYLAND
// Define this to 1 if building GLFW for OSMesa // Define this to 1 if building GLFW for OSMesa
......
...@@ -128,6 +128,7 @@ typedef enum VkStructureType ...@@ -128,6 +128,7 @@ typedef enum VkStructureType
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType; } VkStructureType;
...@@ -555,7 +556,11 @@ struct _GLFWlibrary ...@@ -555,7 +556,11 @@ struct _GLFWlibrary
#if defined(_GLFW_WIN32) #if defined(_GLFW_WIN32)
GLFWbool KHR_win32_surface; GLFWbool KHR_win32_surface;
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
#if defined(VK_USE_PLATFORM_MACOS_MVK)
GLFWbool MVK_macos_surface; GLFWbool MVK_macos_surface;
#elif defined(VK_USE_PLATFORM_METAL_EXT)
GLFWbool EXT_metal_surface;
#endif
#elif defined(_GLFW_X11) #elif defined(_GLFW_X11)
GLFWbool KHR_xlib_surface; GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface; GLFWbool KHR_xcb_surface;
......
...@@ -128,8 +128,13 @@ GLFWbool _glfwInitVulkan(int mode) ...@@ -128,8 +128,13 @@ GLFWbool _glfwInitVulkan(int mode)
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_TRUE; _glfw.vk.KHR_win32_surface = GLFW_TRUE;
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
#if defined(VK_USE_PLATFORM_MACOS_MVK)
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = GLFW_TRUE; _glfw.vk.MVK_macos_surface = GLFW_TRUE;
#elif defined(VK_USE_PLATFORM_METAL_EXT)
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
#endif
#elif defined(_GLFW_X11) #elif defined(_GLFW_X11)
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE; _glfw.vk.KHR_xlib_surface = GLFW_TRUE;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment