如何从Vulkan库调用vkCreateMacOSSurfaceMVK?

问题描述 投票:0回答:1

我尝试创建一个基于 Vulkan v1.3.275.0(以及适用于 macOS 的 MoltenVK 驱动程序)的小应用程序。

我成功地将我的应用程序捆绑到

*.app
中,并使用推荐的 macOS Vulkan 结构。我的应用程序使用 metal-cpp 库打开一个窗口,并使用 MoltenVK 驱动程序创建一个 Vulkan 实例。

但是,现在我需要为 Vulkan 设备创建一个表面,但在这里我遇到了麻烦。

当我要在 macOS 上创建一个 Surface 时,我需要从

vkCreateMacOSSurfaceMVK()
调用 #include <vulkan/vulkan_macos.h> (
ref
),但是当我尝试包含此标头时,我的应用程序崩溃并出现错误:

[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);

如果要打开此标头,这些类型实际上没有声明或其他包含:

#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

我发现了一个标题

<vulkan/vulkan_metal.h>
,但也没有帮助。

在 macOS 上为 Vulkan 创建金属表面的正确方法是什么?

P.S. 我知道有

GLFW
和类似的库,但我只想深入研究干净的 Cocoa 和 Vulkan (MoltenVK) 以了解如何手动连接它们。

P.P.S. 我不确定将 AppKit、MetalKit 和其他框架称为 Cocoa 的一部分是否正确,如果我错了请纠正我。

c++ macos cocoa vulkan moltenvk
1个回答
0
投票

研究了GLFW的源代码我终于知道了如何调用

vkCreateMacOSSurfaceMVK(...)

  1. 我们需要打开两个扩展中的一个(取决于版本):

     #define VK_EXT_METAL_SURFACE_NAME "VK_EXT_metal_surface"
     #define VK_MVK_MACOS_SURFACE_NAME "VK_MVK_macos_surface"
    
     std::vector<const char*> ext_names = {
         VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
         VK_EXT_METAL_SURFACE_NAME,
         VK_MVK_MACOS_SURFACE_NAME,
         // VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
     };
    
     // initialize the VkInstanceCreateInfo structure
     VkInstanceCreateInfo inst_info = {};
     inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
     inst_info.pNext = NULL;
     inst_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
     inst_info.pApplicationInfo = &app_info;
     inst_info.enabledExtensionCount = static_cast<uint32_t>(ext_names.size());;
     inst_info.ppEnabledExtensionNames = ext_names.data();
     inst_info.enabledLayerCount = 0;
     inst_info.ppEnabledLayerNames = NULL;
    
  2. 需要为这些扩展中的函数定义原型:

     // A little changed code of GLFW
     typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
     typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
    
     typedef struct VkMacOSSurfaceCreateInfoMVK
     {
         VkStructureType                 sType;
         const void*                     pNext;
         VkMacOSSurfaceCreateFlagsMVK    flags;
         const void*                     pView;
     } VkMacOSSurfaceCreateInfoMVK;
    
     typedef struct VkMetalSurfaceCreateInfoEXT
     {
         VkStructureType                 sType;
         const void*                     pNext;
         VkMetalSurfaceCreateFlagsEXT    flags;
         const void*                     pLayer;
     } VkMetalSurfaceCreateInfoEXT;
    
     typedef VkResult (*PFN_vkCreateMacOSSurfaceMVK)(VkInstance, const VkMacOSSurfaceCreateInfoMVK*, const VkAllocationCallbacks*, VkSurfaceKHR*);
     typedef VkResult (*PFN_vkCreateMetalSurfaceEXT)(VkInstance, const VkMetalSurfaceCreateInfoEXT*, const VkAllocationCallbacks*, VkSurfaceKHR*);
    
  3. 第三步,我们需要从这些函数中找到任意一个的地址:

     #define VK_CREATE_MACOS_SURFACE_MVK "vkCreateMacOSSurfaceMVK"
     #define VK_CREATE_METAL_SURFACE_EXT "vkCreateMetalSurfaceEXT"
    
     // In my case it's `vkCreateMacOSSurfaceMVK`, so I will call this variant
     auto address = (PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr(instance, VK_CREATE_MACOS_SURFACE_MVK);
    
  4. 利润!

P.S. 上面的所有代码大部分都是 GLFW 的复制粘贴,因此您可以通过研究 GLFW 的源代码来了解更多信息。不幸的是,我是 C++ 新手,如果你也是,我希望这个代码片段能够节省你几个小时的时间和几杯咖啡。

© www.soinside.com 2019 - 2024. All rights reserved.