vulkaninfo: Add VK_EXT_metal_surface info
authorJeremy Kniager <jeremyk@lunarg.com>
Tue, 10 Dec 2019 20:51:42 +0000 (13:51 -0700)
committerjeremyk-lunarg <jeremyk@lunarg.com>
Tue, 10 Dec 2019 23:56:39 +0000 (16:56 -0700)
Added functions to create a Metal Surface and report its
information.

Change-Id: Ic94b00fd6c083bd7b852e3cee9f11601d0fa1675

vulkaninfo/CMakeLists.txt
vulkaninfo/macOS/vulkaninfo/metal_view.h
vulkaninfo/macOS/vulkaninfo/metal_view.mm
vulkaninfo/vulkaninfo.cpp
vulkaninfo/vulkaninfo.h

index f17493b..14776d9 100644 (file)
@@ -120,7 +120,7 @@ if(WIN32)
 
     file(COPY vulkaninfo.vcxproj.user DESTINATION ${CMAKE_BINARY_DIR}/vulkaninfo)
 elseif(APPLE)
-    add_definitions(-DVK_USE_PLATFORM_MACOS_MVK)
+    add_definitions(-DVK_USE_PLATFORM_MACOS_MVK -DVK_USE_PLATFORM_METAL_EXT)
 endif()
 
 if(APPLE)
index 82e98ec..31429d4 100644 (file)
@@ -25,4 +25,6 @@ void* CreateMetalView(uint32_t width, uint32_t height);
 
 void DestroyMetalView(void* view);
 
+void* GetCAMetalLayerFromMetalView(void* view);
+
 #endif /* metal_view_h */
index 0e08653..90bff4c 100644 (file)
 @end
 
 @implementation NativeMetalView
-- (id)initWithFrame:(NSRect) frame {
-    if(self = [super initWithFrame: frame]){
+- (id)initWithFrame:(NSRect)frame {
+    if (self = [super initWithFrame:frame]) {
         self.wantsLayer = YES;
     }
     return self;
 }
 
++ (Class)layerClass {
+    return [CAMetalLayer class];
+}
+
 - (CALayer*)makeBackingLayer {
-    return [CAMetalLayer layer];
+    CALayer* layer = [self.class.layerClass layer];
+    CGSize viewScale = [self convertSizeToBacking:CGSizeMake(1.0, 1.0)];
+    layer.contentsScale = MIN(viewScale.width, viewScale.height);
+    return layer;
 }
 @end
 
@@ -41,6 +48,6 @@ void* CreateMetalView(uint32_t width, uint32_t height) {
     return [[NativeMetalView alloc] initWithFrame:NSMakeRect(0, 0, width, height)];
 }
 
-void DestroyMetalView(void* view) {
-    [(NativeMetalView*)view dealloc];
-}
+void DestroyMetalView(void* view) { [(NativeMetalView*)view dealloc]; }
+
+void* GetCAMetalLayerFromMetalView(void* view) { return ((NativeMetalView*)view).layer; }
index bab61ee..4bc5349 100644 (file)
@@ -729,7 +729,7 @@ int main(int argc, char **argv) {
 
     std::vector<std::unique_ptr<AppSurface>> surfaces;
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
     for (auto &surface_extension : instance.surface_extensions) {
         surface_extension.create_window(instance);
         surface_extension.surface = surface_extension.create_surface(instance);
@@ -778,7 +778,7 @@ int main(int argc, char **argv) {
 
         if (p->Type() != OutputType::json) {
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
             DumpPresentableSurfaces(*p.get(), instance, gpus, surfaces);
 #endif
             DumpGroups(*p.get(), instance);
@@ -799,7 +799,7 @@ int main(int argc, char **argv) {
     }
 
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
 
     for (auto &surface_extension : instance.surface_extensions) {
         AppDestroySurface(instance, surface_extension.surface);
index c0b0282..a88b11c 100644 (file)
@@ -61,7 +61,7 @@
 #include <X11/Xutil.h>
 #endif
 
-#if defined(VK_USE_PLATFORM_MACOS_MVK)
+#if defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
 #include "metal_view.h"
 #endif
 
@@ -317,7 +317,10 @@ struct AppInstance {
     Window xlib_window;
 #endif
 #ifdef VK_USE_PLATFORM_MACOS_MVK
-    void *window;
+    void *macos_window;
+#endif
+#ifdef VK_USE_PLATFORM_METAL_EXT
+    void *metal_window;
 #endif
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
     wl_display *wayland_display;
@@ -550,8 +553,9 @@ static void AppDestroyWin32Window(AppInstance &inst) { CALL_PFN(DestroyWindow)(i
 #endif  // VK_USE_PLATFORM_WIN32_KHR
 //-----------------------------------------------------------
 
-#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || defined(VK_USE_PLATFORM_ANDROID_KHR)
+#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) ||      \
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
+    defined(VK_USE_PLATFORM_ANDROID_KHR)
 static void AppDestroySurface(AppInstance &inst, VkSurfaceKHR surface) {  // same for all platforms
     vkDestroySurfaceKHR(inst.instance, surface, nullptr);
 }
@@ -670,8 +674,8 @@ static void AppDestroyXlibWindow(AppInstance &inst) {
 //------------------------MACOS_MVK--------------------------
 #ifdef VK_USE_PLATFORM_MACOS_MVK
 static void AppCreateMacOSWindow(AppInstance &inst) {
-    inst.window = CreateMetalView(inst.width, inst.height);
-    if (inst.window == nullptr) {
+    inst.macos_window = CreateMetalView(inst.width, inst.height);
+    if (inst.macos_window == nullptr) {
         fprintf(stderr, "Could not create a native Metal view.\nExiting...\n");
         exit(1);
     }
@@ -682,7 +686,7 @@ static VkSurfaceKHR AppCreateMacOSSurface(AppInstance &inst) {
     createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
     createInfo.pNext = nullptr;
     createInfo.flags = 0;
-    createInfo.pView = inst.window;
+    createInfo.pView = inst.macos_window;
 
     VkSurfaceKHR surface;
     VkResult err = vkCreateMacOSSurfaceMVK(inst.instance, &createInfo, nullptr, &surface);
@@ -690,10 +694,37 @@ static VkSurfaceKHR AppCreateMacOSSurface(AppInstance &inst) {
     return surface;
 }
 
-static void AppDestroyMacOSWindow(AppInstance &inst) { DestroyMetalView(inst.window); }
+static void AppDestroyMacOSWindow(AppInstance &inst) { DestroyMetalView(inst.macos_window); }
 #endif  // VK_USE_PLATFORM_MACOS_MVK
 //-----------------------------------------------------------
 
+//------------------------METAL_EXT--------------------------
+#ifdef VK_USE_PLATFORM_METAL_EXT
+static void AppCreateMetalWindow(AppInstance &inst) {
+    inst.metal_window = CreateMetalView(inst.width, inst.height);
+    if (inst.metal_window == nullptr) {
+        fprintf(stderr, "Could not create a native Metal view.\nExiting...\n");
+        exit(1);
+    }
+}
+
+static VkSurfaceKHR AppCreateMetalSurface(AppInstance &inst) {
+    VkMetalSurfaceCreateInfoEXT createInfo;
+    createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
+    createInfo.pNext = nullptr;
+    createInfo.flags = 0;
+    createInfo.pLayer = static_cast<CAMetalLayer *>(GetCAMetalLayerFromMetalView(inst.metal_window));
+
+    VkSurfaceKHR surface;
+    VkResult err = vkCreateMetalSurfaceEXT(inst.instance, &createInfo, nullptr, &surface);
+    if (err) ERR_EXIT(err);
+    return surface;
+}
+
+static void AppDestroyMetalWindow(AppInstance &inst) { DestroyMetalView(inst.metal_window); }
+#endif  // VK_USE_PLATFORM_METAL_EXT
+//-----------------------------------------------------------
+
 //-------------------------WAYLAND---------------------------
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
 static void wayland_registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
@@ -822,6 +853,18 @@ void SetupWindowExtensions(AppInstance &inst) {
         inst.AddSurfaceExtension(surface_ext_macos);
     }
 #endif
+
+#ifdef VK_USE_PLATFORM_METAL_EXT
+    SurfaceExtension surface_ext_metal;
+    if (inst.CheckExtensionEnabled(VK_EXT_METAL_SURFACE_EXTENSION_NAME)) {
+        surface_ext_metal.name = VK_EXT_METAL_SURFACE_EXTENSION_NAME;
+        surface_ext_metal.create_window = AppCreateMetalWindow;
+        surface_ext_metal.create_surface = AppCreateMetalSurface;
+        surface_ext_metal.destroy_window = AppDestroyMetalWindow;
+
+        inst.AddSurfaceExtension(surface_ext_metal);
+    }
+#endif
 //--WAYLAND--
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
     SurfaceExtension surface_ext_wayland;