Skip to content

Commit

Permalink
Cocoa: Select Vulkan surface extension at runtime
Browse files Browse the repository at this point in the history
This mostly just follows the pattern established by X11.

Related to glfw#1619.
  • Loading branch information
elmindreda committed Jan 16, 2020
1 parent c5cb4a2 commit 15d9180
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 77 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ elseif (WIN32)
elseif (APPLE)
set(_GLFW_COCOA 1)
message(STATUS "Using Cocoa for window creation")
set(VK_USE_PLATFORM_METAL_EXT 1)
message(STATUS "Using VK_EXT_metal_surface")
elseif (UNIX)
set(_GLFW_X11 1)
message(STATUS "Using X11 for window creation")
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ information on what to include when reporting a bug.
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
window (#1499)
- [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
- [Cocoa] Removed dependency on the CoreVideo framework
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
Expand Down Expand Up @@ -260,6 +261,7 @@ skills.
- Cem Karan
- Osman Keskin
- Josh Kilmer
- Byunghoon Kim
- Cameron King
- Peter Knut
- Christoph Kubisch
Expand Down
20 changes: 6 additions & 14 deletions src/cocoa_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ typedef void* id;
#define NSWindowStyleMaskTitled NSTitledWindowMask
#endif

#if defined(VK_USE_PLATFORM_MACOS_MVK)
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;

typedef struct VkMacOSSurfaceCreateInfoMVK
{
Expand All @@ -71,24 +71,16 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
const void* pView;
} 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 {
typedef struct VkMetalSurfaceCreateInfoEXT
{
VkStructureType sType;
const void* pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const CAMetalLayer* pLayer;
const void* pLayer;
} VkMetalSurfaceCreateInfoEXT;

typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance, const VkMetalSurfaceCreateInfoEXT*, const VkAllocationCallbacks*, VkSurfaceKHR*);
#endif
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);

#include "posix_thread.h"
#include "cocoa_joystick.h"
Expand Down
104 changes: 50 additions & 54 deletions src/cocoa_window.m
Original file line number Diff line number Diff line change
Expand Up @@ -1715,19 +1715,16 @@ void _glfwPlatformSetClipboardString(const char* string)

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
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
{
extensions[0] = "VK_KHR_surface";
extensions[1] = "VK_EXT_metal_surface";
}
else if (_glfw.vk.KHR_surface && _glfw.vk.MVK_macos_surface)
{
extensions[0] = "VK_KHR_surface";
extensions[1] = "VK_MVK_macos_surface";
}
}

int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
Expand All @@ -1745,35 +1742,6 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
@autoreleasepool {

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
VkResult err;

#if defined(VK_USE_PLATFORM_MACOS_MVK)
VkMacOSSurfaceCreateInfoMVK sci;

PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
if (!vkCreateMacOSSurfaceMVK)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
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"];
Expand All @@ -1799,21 +1767,49 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
[window->ns.view setLayer:window->ns.layer];
[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;
VkResult err;

if (_glfw.vk.EXT_metal_surface)
{
VkMetalSurfaceCreateInfoEXT sci;

err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
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;
}

#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;
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
sci.pLayer = window->ns.layer;

err = vkCreateMetalSurfaceEXT(instance, &sci, allocator, surface);
}
else
{
VkMacOSSurfaceCreateInfoMVK sci;

PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
if (!vkCreateMacOSSurfaceMVK)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}

memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
sci.pView = window->ns.view;

err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
}

err = vkCreateMetalSurfaceEXT(instance, &sci, allocator, surface);
#endif
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
Expand Down
1 change: 0 additions & 1 deletion src/glfw_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#cmakedefine _GLFW_WIN32
// Define this to 1 if building GLFW for Cocoa
#cmakedefine _GLFW_COCOA
#cmakedefine VK_USE_PLATFORM_METAL_EXT
// Define this to 1 if building GLFW for Wayland
#cmakedefine _GLFW_WAYLAND
// Define this to 1 if building GLFW for OSMesa
Expand Down
3 changes: 0 additions & 3 deletions src/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,11 +559,8 @@ struct _GLFWlibrary
#if defined(_GLFW_WIN32)
GLFWbool KHR_win32_surface;
#elif defined(_GLFW_COCOA)
#if defined(VK_USE_PLATFORM_MACOS_MVK)
GLFWbool MVK_macos_surface;
#elif defined(VK_USE_PLATFORM_METAL_EXT)
GLFWbool EXT_metal_surface;
#endif
#elif defined(_GLFW_X11)
GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface;
Expand Down
3 changes: 0 additions & 3 deletions src/vulkan.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,10 @@ GLFWbool _glfwInitVulkan(int mode)
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_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 = 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)
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
Expand Down

0 comments on commit 15d9180

Please sign in to comment.