VulkanRenderer: implement metal view

The metal view backing the MoltenVK compatibility wrapper is written in
Obj-C.

It would have been possible to use the Objective-C runtime in C++ but
the code is less performant (the symbol binding is done at first use
instead of the beginning of the program) and actually harder to get
right.

Note that MoltenVK is not linked to the loader, so the libMoltenVK.dylib
object must be available for loading.
This commit is contained in:
Alexandre Janniaux
2022-03-20 20:12:40 +01:00
committed by Jérôme Leclercq
parent 162456c5b6
commit f146661a76
8 changed files with 81 additions and 0 deletions

View File

@@ -244,6 +244,10 @@ namespace Nz
enabledExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
enabledExtensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
#endif
if (availableExtensions.count(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
enabledExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);

View File

@@ -7,8 +7,17 @@
#include <vulkan/vk_sdk_platform.h>
#include <Nazara/VulkanRenderer/Debug.hpp>
#ifdef VK_USE_PLATFORM_METAL_EXT
#include <objc/runtime.h>
#include <vulkan/vulkan_metal.h>
#endif
namespace Nz
{
#ifdef VK_USE_PLATFORM_METAL_EXT
id CreateAndAttachMetalLayer(void* window);
#endif
VulkanSurface::VulkanSurface() :
m_surface(Vulkan::GetInstance())
{
@@ -60,6 +69,11 @@ namespace Nz
}
}
#elif defined(NAZARA_PLATFORM_MACOS)
{
NazaraAssert(handle.type == WindowBackend::Cocoa, "expected cocoa window");
id layer = CreateAndAttachMetalLayer(handle.cocoa.window);
success = m_surface.Create(layer);
}
#else
#error This OS is not supported by Vulkan
#endif

View File

@@ -0,0 +1,16 @@
#import <AppKit/NSView.h>
#import <AppKit/NSWindow.h>
#import <QuartzCore/CAMetalLayer.h>
namespace Nz
{
id CreateAndAttachMetalLayer(void* window) {
NSWindow* obj = (__bridge NSWindow*)window;
NSView* view = [[NSView alloc] initWithFrame:obj.frame];
[view setLayer:[CAMetalLayer layer]];
[view setWantsLayer:YES];
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[obj.contentView addSubview:view];
return view.layer;
}
}