c++macoscocoavulkanmoltenvk

How to call vkCreateMacOSSurfaceMVK from Vulkan library?


I try to create a small app based on Vulkan v1.3.275.0 (and MoltenVK driver for macOS).

I successfully bundle my app into *.app with recommended Vulkan structure for macOS. My app opens a window using metal-cpp library and creates a Vulkan instance using MoltenVK driver.

However, now I need to create a surface for Vulkan device and here I hit troubles.

As I got to create a surface on macOS, I need to call vkCreateMacOSSurfaceMVK() (ref) from #include <vulkan/vulkan_macos.h> but when I try to include this header my app crashes with errors:

[build] /Projects/my/third-party/vulkan/include/vulkan/vulkan_macos.h:26:9: error: unknown type name 'VkFlags'
[build] typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
[build]         ^
[build] /Projects/my/third-party/vulkan/include/vulkan/vulkan_macos.h:28:5: error: unknown type name 'VkStructureType'
[build]     VkStructureType                 sType;
[build]     ^
[build] /Projects/my/third-party/vulkan/include/vulkan/vulkan_macos.h:34:19: error: unknown type name 'VKAPI_PTR'
[build] typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
[build]                   ^
[build] /Projects/my/third-party/vulkan/include/vulkan/vulkan_macos.h:34:59: error: unknown type name 'VkInstance'
[build] typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);

And if to open this header there are really no declarations or other includes for these types:

#ifndef VULKAN_MACOS_H_
#define VULKAN_MACOS_H_ 1

/*
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/


#ifdef __cplusplus
extern "C" {
#endif



// VK_MVK_macos_surface is a preprocessor guard. Do not pass it to API calls.
#define VK_MVK_macos_surface 1
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3
#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface"
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef struct VkMacOSSurfaceCreateInfoMVK {
    VkStructureType                 sType;
    const void*                     pNext;
    VkMacOSSurfaceCreateFlagsMVK    flags;
    const void*                     pView;
} VkMacOSSurfaceCreateInfoMVK;

typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);

#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(
    VkInstance                                  instance,
    const VkMacOSSurfaceCreateInfoMVK*          pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkSurfaceKHR*                               pSurface);
#endif

#ifdef __cplusplus
}
#endif

#endif

I found yet one header <vulkan/vulkan_metal.h> but it didn't help too.

What's a right way to create a Metal surface for Vulkan on macOS?

P.S. I know there are GLFW and similar libraries but I just want to dig into clean Cocoa and Vulkan (MoltenVK) to understand how to connect them manually.

P.P.S. I am not sure if it's right to call AppKit, MetalKit and other frameworks a part of Cocoa, fix me if I am wrong.


Solution

  • This is the combination of the two following questions and their answers (one of them being mine):

    TL;DR:

    #ifndef YOUR_VULKAN_H
    #define YOUR_VULKAN_H
    
    #include <vulkan/vulkan_core.h>
    
    #if defined(VK_USE_PLATFORM_XXXX)
    
    // Some forward declarations
    
    #include <vulkan/the_platform_header.h>
    
    #endif // #if defined(VK_USE_PLATFORM_XXXX)
    
    #endif // YOUR_VULKAN_H
    

    Note: this is what Volk does.