Vulkan: Switch from vkCreateMacOSSurfaceMVK() to vkCreateMetalSurfaceEXT()
Since we are calling this off the UI thread, we can't use anything which accesses the underlying NSView object. We create and set the Metal layer on the UI thread before the video backend is initialized. This extension is both compatible with MoltenVK and gfx-portability for accepting a layer at surface creation.
This commit is contained in:
parent
52d4756679
commit
a2f4fafe86
|
@ -107,17 +107,18 @@ VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, const WindowSys
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
if (wsi.type == WindowSystemType::MacOS)
|
||||
{
|
||||
VkMacOSSurfaceCreateInfoMVK surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, nullptr, 0, wsi.render_surface};
|
||||
VkMetalSurfaceCreateInfoEXT surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, nullptr, 0,
|
||||
static_cast<const CAMetalLayer*>(wsi.render_surface)};
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
VkResult res = vkCreateMacOSSurfaceMVK(instance, &surface_create_info, nullptr, &surface);
|
||||
VkResult res = vkCreateMetalSurfaceEXT(instance, &surface_create_info, nullptr, &surface);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateMacOSSurfaceMVK failed: ");
|
||||
LOG_VULKAN_ERROR(res, "vkCreateMetalSurfaceEXT failed: ");
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,8 +211,8 @@ bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
if (wstype == WindowSystemType::MacOS && !AddExtension(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, true))
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
if (wstype == WindowSystemType::MacOS && !AddExtension(VK_EXT_METAL_SURFACE_EXTENSION_NAME, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceXlibPresentationSupportKHR, false
|
|||
VULKAN_INSTANCE_ENTRY_POINT(vkCreateAndroidSurfaceKHR, false)
|
||||
#endif
|
||||
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
VULKAN_INSTANCE_ENTRY_POINT(vkCreateMacOSSurfaceMVK, false)
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
VULKAN_INSTANCE_ENTRY_POINT(vkCreateMetalSurfaceEXT, false)
|
||||
#endif
|
||||
|
||||
VULKAN_INSTANCE_ENTRY_POINT(vkCreateDebugReportCallbackEXT, false)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_MACOS_MVK
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#endif
|
||||
|
||||
#include "vulkan/vulkan.h"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
#include <objc/message.h>
|
||||
#endif
|
||||
|
||||
|
@ -280,7 +280,7 @@ void VideoBackend::Shutdown()
|
|||
UnloadVulkanLibrary();
|
||||
}
|
||||
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
static bool IsRunningOnMojaveOrHigher()
|
||||
{
|
||||
// id processInfo = [NSProcessInfo processInfo]
|
||||
|
@ -306,7 +306,7 @@ static bool IsRunningOnMojaveOrHigher()
|
|||
|
||||
void VideoBackend::PrepareWindow(WindowSystemInfo& wsi)
|
||||
{
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
// This is kinda messy, but it avoids having to write Objective C++ just to create a metal layer.
|
||||
id view = reinterpret_cast<id>(wsi.render_surface);
|
||||
Class clsCAMetalLayer = objc_getClass("CAMetalLayer");
|
||||
|
|
Loading…
Reference in New Issue