apple: switch from MTKView to CAMetalLayer for vulkan (#16959)

This commit is contained in:
Eric Warmenhoven 2024-09-03 22:02:00 -04:00 committed by GitHub
parent a32c43cc3a
commit 95d53183f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 67 additions and 37 deletions

View File

@ -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 <vulkan/vulkan_symbol_wrapper.h>

View File

@ -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)

View File

@ -236,7 +236,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))
@ -285,7 +285,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))

View File

@ -70,6 +70,12 @@ 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
@interface RetroArch_iOS : UINavigationController<ApplePlatform, UIApplicationDelegate,
UINavigationControllerDelegate> {
UIView *_renderView;

View File

@ -665,6 +665,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];

View File

@ -490,6 +490,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 () <MXMetricManagerSubscriber, UIPointerInteractionDelegate>
@end
@ -520,6 +556,8 @@ enum
{
#ifdef HAVE_COCOA_METAL
case APPLE_VIEW_TYPE_VULKAN:
_renderView = [MetalLayerView new];
break;
case APPLE_VIEW_TYPE_METAL:
{
MetalView *v = [MetalView new];