From ea1b6852c5b0c2e1775b0cf64bbf9e71c31c6922 Mon Sep 17 00:00:00 2001 From: Eric Warmenhoven Date: Fri, 27 Sep 2024 17:36:45 -0400 Subject: [PATCH] apple: switch from MTKView to CAMetalLayer for vulkan (again) (#17045) --- gfx/common/vksym.h | 8 ++---- gfx/common/vulkan_common.c | 38 +++++++-------------------- gfx/drivers_context/cocoa_vk_ctx.m | 4 +-- ui/drivers/cocoa/apple_platform.h | 8 ++++++ ui/drivers/ui_cocoa.m | 10 ++++++++ ui/drivers/ui_cocoatouch.m | 41 ++++++++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 37 deletions(-) diff --git a/gfx/common/vksym.h b/gfx/common/vksym.h index f7f704b8a8..d07baed072 100644 --- a/gfx/common/vksym.h +++ b/gfx/common/vksym.h @@ -47,12 +47,8 @@ #define VK_USE_PLATFORM_XLIB_KHR #endif -#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL) -#define VK_USE_PLATFORM_MACOS_MVK -#endif - -#ifdef HAVE_COCOATOUCH -#define VK_USE_PLATFORM_IOS_MVK +#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL) || defined(HAVE_COCOATOUCH) +#define VK_USE_PLATFORM_METAL_EXT #endif #include diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index ad1b89122e..7033e68668 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -899,10 +899,8 @@ static VkInstance vulkan_context_create_instance_wrapper(void *opaque, const VkI required_extensions[required_extension_count++] = "VK_KHR_display"; break; case VULKAN_WSI_MVK_MACOS: - required_extensions[required_extension_count++] = "VK_MVK_macos_surface"; - break; case VULKAN_WSI_MVK_IOS: - required_extensions[required_extension_count++] = "VK_MVK_ios_surface"; + required_extensions[required_extension_count++] = "VK_EXT_metal_surface"; break; case VULKAN_WSI_NONE: default: @@ -1677,36 +1675,18 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, return false; break; case VULKAN_WSI_MVK_MACOS: -#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL) - { - VkMacOSSurfaceCreateInfoMVK surf_info; - PFN_vkCreateMacOSSurfaceMVK create; - if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(vk->context.instance, "vkCreateMacOSSurfaceMVK", create)) - return false; - - surf_info.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; - surf_info.pNext = NULL; - surf_info.flags = 0; - surf_info.pView = surface; - - if (create(vk->context.instance, &surf_info, NULL, &vk->vk_surface) - != VK_SUCCESS) - return false; - } -#endif - break; case VULKAN_WSI_MVK_IOS: -#ifdef HAVE_COCOATOUCH +#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL) || defined(HAVE_COCOATOUCH) { - VkIOSSurfaceCreateInfoMVK surf_info; - PFN_vkCreateIOSSurfaceMVK create; - if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(vk->context.instance, "vkCreateIOSSurfaceMVK", create)) + VkMetalSurfaceCreateInfoEXT surf_info; + PFN_vkCreateMetalSurfaceEXT create; + if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(vk->context.instance, "vkCreateMetalSurfaceEXT", create)) return false; - surf_info.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; - surf_info.pNext = NULL; - surf_info.flags = 0; - surf_info.pView = surface; + surf_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + surf_info.pNext = NULL; + surf_info.flags = 0; + surf_info.pLayer = surface; if (create(vk->context.instance, &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS) diff --git a/gfx/drivers_context/cocoa_vk_ctx.m b/gfx/drivers_context/cocoa_vk_ctx.m index 232f1afa76..9e732dc319 100755 --- a/gfx/drivers_context/cocoa_vk_ctx.m +++ b/gfx/drivers_context/cocoa_vk_ctx.m @@ -249,7 +249,7 @@ static bool cocoa_vk_gfx_ctx_set_video_mode(void *data, &cocoa_ctx->vk, VULKAN_WSI_MVK_MACOS, NULL, - (BRIDGE void *)g_view, + (BRIDGE void *)g_view.layer, cocoa_ctx->width, cocoa_ctx->height, cocoa_ctx->swap_interval)) @@ -298,7 +298,7 @@ static bool cocoa_vk_gfx_ctx_set_video_mode(void *data, if (!vulkan_surface_create(&cocoa_ctx->vk, VULKAN_WSI_MVK_IOS, NULL, - (BRIDGE void *)g_view, + (BRIDGE void *)((MetalLayerView*)g_view).metalLayer, cocoa_ctx->width, cocoa_ctx->height, cocoa_ctx->swap_interval)) diff --git a/ui/drivers/cocoa/apple_platform.h b/ui/drivers/cocoa/apple_platform.h index badd8d217c..86bb97ee19 100644 --- a/ui/drivers/cocoa/apple_platform.h +++ b/ui/drivers/cocoa/apple_platform.h @@ -70,6 +70,14 @@ extern id apple_platform; void rarch_start_draw_observer(void); void rarch_stop_draw_observer(void); +#if defined(HAVE_COCOA_METAL) +@interface MetalLayerView : UIView +@property (nonatomic, readonly) CAMetalLayer *metalLayer; +@end +#endif + +#import + @interface RetroArch_iOS : UINavigationController { UIView *_renderView; diff --git a/ui/drivers/ui_cocoa.m b/ui/drivers/ui_cocoa.m index 9dcb134443..0c2d405554 100644 --- a/ui/drivers/ui_cocoa.m +++ b/ui/drivers/ui_cocoa.m @@ -667,6 +667,16 @@ static ui_application_t ui_application_cocoa = { switch (vt) { case APPLE_VIEW_TYPE_VULKAN: + { + _renderView = [CocoaView get]; + CAMetalLayer *metal_layer = [[CAMetalLayer alloc] init]; + metal_layer.device = MTLCreateSystemDefaultDevice(); + metal_layer.framebufferOnly = YES; + metal_layer.contentsScale = [[NSScreen mainScreen] backingScaleFactor]; + _renderView.layer = metal_layer; + [_renderView setWantsLayer:YES]; + } + break; case APPLE_VIEW_TYPE_METAL: { MetalView *v = [MetalView new]; diff --git a/ui/drivers/ui_cocoatouch.m b/ui/drivers/ui_cocoatouch.m index 822db5577b..7e2f2828f9 100644 --- a/ui/drivers/ui_cocoatouch.m +++ b/ui/drivers/ui_cocoatouch.m @@ -500,6 +500,42 @@ enum @end +#ifdef HAVE_COCOA_METAL +@implementation MetalLayerView + ++ (Class)layerClass { + return [CAMetalLayer class]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self setupMetalLayer]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupMetalLayer]; + } + return self; +} + +- (CAMetalLayer *)metalLayer { + return (CAMetalLayer *)self.layer; +} + +- (void)setupMetalLayer { + self.metalLayer.device = MTLCreateSystemDefaultDevice(); + self.metalLayer.contentsScale = [UIScreen mainScreen].scale; + self.metalLayer.opaque = YES; +} + +@end +#endif + #if TARGET_OS_IOS @interface RetroArch_iOS () @end @@ -530,6 +566,11 @@ enum { #ifdef HAVE_COCOA_METAL case APPLE_VIEW_TYPE_VULKAN: + _renderView = [MetalLayerView new]; +#if TARGET_OS_IOS + _renderView.multipleTouchEnabled = YES; +#endif + break; case APPLE_VIEW_TYPE_METAL: { MetalView *v = [MetalView new];