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.
This is the combination of the two following questions and their answers (one of them being mine):
As for all Vulkan extensions, function pointers must be loaded dynamically using vkGetInstanceProcAddr
or vkGetDeviceProcAddr
. Note that you will need to specify the corresponding extensions upon instance creation in VkInstanceCreateInfo::ppEnabledExtensionNames
. You can also use some libraries like Volk
that exist for this purpose.
Headers such as vulkan_metal.h
or vulkan_win32.h
and their siblings require the contents of vulkan_core.h
, that must be included before it. Though the vulkan.h
header does this for you (provided you added the correct #define VK_USE_PLATFORM_XXX
), it also #include
s potentially-heavy platform-specific headers, such as <windows.h>
on Windows, or <X11/Xlib.h>
on Linux with X11. This isn't good for compile times. As far as I know, a few forward-declaration suffice, so you may build your own vulkan.h
that may look like this instead:
#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