RendererEngine icon indicating copy to clipboard operation
RendererEngine copied to clipboard

VK_EXT_metal_surface extension missing despite being enabled on macOS M1 and M2

Open ZzzhHe opened this issue 1 year ago • 7 comments

Environment

  • macOS on M1
  • Vulkan SDK 1.3.280
  • GLFW
  • MoltenVK
  • Xcode project

Issue

Getting error: Cocoa: Vulkan instance missing VK_EXT_metal_surface extension during window surface creation, despite the extension being properly enabled.

https://github.com/JeanPhilippeKernel/RendererEngine/blob/09456d4df146987149700688cfad8b66f7171c7c/Tetragrama/EditorWindow.cpp#L415-L425

What I've Tried

  1. Enabled VK_EXT_metal_surface extension - confirmed present in extension list
  2. Added required macOS-specific extensions:
    • VK_KHR_portability_enumeration
    • VK_KHR_get_physical_device_properties2
  3. Set proper instance creation flags for macOS
  4. Verified library linking and loading order
  5. Removed potential conflict with VK_MVK_macos_surface

Output (with extension list printed)

❯ ./Result.Darwin.x64.Debug/Tetragrama/Debug/zEngineEditor --projectConfigFile "/Users/Programming/GitRepo/RendererEngine/test/projectConfig.json"
Thread 0, Frame 0:
vkCreateInstance(pCreateInfo, pAllocator, pInstance) returns VkResult VK_SUCCESS (0):
    pCreateInfo:                    const VkInstanceCreateInfo* = 0x16d161c40:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO (1)
        pNext:                          const void* = NULL
        flags:                          VkInstanceCreateFlags = 1 (VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR)
        pApplicationInfo:               const VkApplicationInfo* = 0x16d165ed0:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_APPLICATION_INFO (0)
            pNext:                          const void* = NULL
            pApplicationName:               const char* = "Tetragrama"
            applicationVersion:             uint32_t = 1
            pEngineName:                    const char* = "ZEngine"
            engineVersion:                  uint32_t = 1
            apiVersion:                     uint32_t = 4206592
        enabledLayerCount:              uint32_t = 4
        ppEnabledLayerNames:            const char* const* = 0x6000031b92a0
            ppEnabledLayerNames[0]:         const char* const = "VK_LAYER_LUNARG_screenshot"
            ppEnabledLayerNames[1]:         const char* const = "VK_LAYER_KHRONOS_validation"
            ppEnabledLayerNames[2]:         const char* const = "VK_LAYER_LUNARG_api_dump"
            ppEnabledLayerNames[3]:         const char* const = "VK_LAYER_KHRONOS_synchronization2"
        enabledExtensionCount:          uint32_t = 6
        ppEnabledExtensionNames:        const char* const* = 0x6000024b0800
            ppEnabledExtensionNames[0]:     const char* const = "VK_EXT_debug_report"
            ppEnabledExtensionNames[1]:     const char* const = "VK_EXT_debug_utils"
            ppEnabledExtensionNames[2]:     const char* const = "VK_KHR_surface"
            ppEnabledExtensionNames[3]:     const char* const = "VK_EXT_metal_surface"
            ppEnabledExtensionNames[4]:     const char* const = "VK_KHR_portability_enumeration"
            ppEnabledExtensionNames[5]:     const char* const = "VK_KHR_get_physical_device_properties2"
        pNext:                          const void* = NULL
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pInstance:                      VkInstance* = 0x131813200

Thread 0, Frame 0:
vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices) returns VkResult VK_SUCCESS (0):
    instance:                       VkInstance = 0x131813200
    pPhysicalDeviceCount:           uint32_t* = 1
    pPhysicalDevices:               VkPhysicalDevice* = NULL

Thread 0, Frame 0:
vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices) returns VkResult VK_SUCCESS (0):
    instance:                       VkInstance = 0x131813200
    pPhysicalDeviceCount:           uint32_t* = 1
    pPhysicalDevices:               VkPhysicalDevice* = 0x6000033bc560
        pPhysicalDevices[0]:            VkPhysicalDevice = 0x6000031e0000

Thread 0, Frame 0:
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties) returns void:
    physicalDevice:                 VkPhysicalDevice = 0x6000031e0000
    pQueueFamilyPropertyCount:      uint32_t* = 4
    pQueueFamilyProperties:         VkQueueFamilyProperties* = NULL

Thread 0, Frame 0:
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties) returns void:
    physicalDevice:                 VkPhysicalDevice = 0x6000031e0000
    pQueueFamilyPropertyCount:      uint32_t* = 4
    pQueueFamilyProperties:         VkQueueFamilyProperties* = 0x6000015aaa00
        pQueueFamilyProperties[0]:      VkQueueFamilyProperties = 0x6000015aaa00:
            queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
            queueCount:                     uint32_t = 1
            timestampValidBits:             uint32_t = 64
            minImageTransferGranularity:    VkExtent3D = 0x6000015aaa0c:
                width:                          uint32_t = 1
                height:                         uint32_t = 1
                depth:                          uint32_t = 1
        pQueueFamilyProperties[1]:      VkQueueFamilyProperties = 0x6000015aaa18:
            queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
            queueCount:                     uint32_t = 1
            timestampValidBits:             uint32_t = 64
            minImageTransferGranularity:    VkExtent3D = 0x6000015aaa24:
                width:                          uint32_t = 1
                height:                         uint32_t = 1
                depth:                          uint32_t = 1
        pQueueFamilyProperties[2]:      VkQueueFamilyProperties = 0x6000015aaa30:
            queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
            queueCount:                     uint32_t = 1
            timestampValidBits:             uint32_t = 64
            minImageTransferGranularity:    VkExtent3D = 0x6000015aaa3c:
                width:                          uint32_t = 1
                height:                         uint32_t = 1
                depth:                          uint32_t = 1
        pQueueFamilyProperties[3]:      VkQueueFamilyProperties = 0x6000015aaa48:
            queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
            queueCount:                     uint32_t = 1
            timestampValidBits:             uint32_t = 64
            minImageTransferGranularity:    VkExtent3D = 0x6000015aaa54:
                width:                          uint32_t = 1
                height:                         uint32_t = 1
                depth:                          uint32_t = 1

Active instance extensions:
VK_KHR_device_group_creation
VK_KHR_external_fence_capabilities
VK_KHR_external_memory_capabilities
VK_KHR_external_semaphore_capabilities
VK_KHR_get_physical_device_properties2
VK_KHR_get_surface_capabilities2
VK_KHR_surface
VK_EXT_debug_report
VK_EXT_debug_utils
VK_EXT_headless_surface
VK_EXT_layer_settings
VK_EXT_metal_surface
VK_EXT_surface_maintenance1
VK_EXT_swapchain_colorspace
VK_MVK_macos_surface
VK_KHR_portability_enumeration
VK_LUNARG_direct_driver_loading
Thread 0, Frame 0:
vkCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger) returns VkResult VK_SUCCESS (0):
    instance:                       VkInstance = 0x131813200
    pCreateInfo:                    const VkDebugUtilsMessengerCreateInfoEXT* = 0x16d165b68:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT (1000128004)
        pNext:                          const void* = NULL
        flags:                          VkDebugUtilsMessengerCreateFlagsEXT = 0
        messageSeverity:                VkDebugUtilsMessageSeverityFlagsEXT = 4369 (VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
        messageType:                    VkDebugUtilsMessageTypeFlagsEXT = 7 (VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
        pfnUserCallback:                PFN_vkDebugUtilsMessengerCallbackEXT = 1
        pUserData:                      void* = NULL
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pMessenger:                     VkDebugUtilsMessengerEXT* = 0x6000033bc650

ZzzhHe avatar Jan 10 '25 02:01 ZzzhHe

Thanks for filing that issue! That was a great investigation 🙂

Although I don’t have access to an M1 device, I was able to run the engine on macOS Intel with minimal changes. I believe it should work on M1 as well — at least I hope so!

Would you be interested in giving it a try? You can check out the draft PR here: [PR Link](https://github.com/JeanPhilippeKernel/RendererEngine/pull/415). From there, we could look into re-enabling those features.

Also, just to let you know, this investigation is part of an existing issue that hasn't been picked up yet by anyone. I would be glad if you're interested in working on it! See here: [issue link]

JeanPhilippeKernel avatar Jan 10 '25 19:01 JeanPhilippeKernel

Yes! I’d love to give it a try. Let me check out the draft PR and dive in! I'll let you know how it goes.

ZzzhHe avatar Jan 10 '25 20:01 ZzzhHe

I'm still hitting the same issue on run-on-macos branch. Looks like it's still unable to create the window surface.

Here is the output:

./Result.Darwin.x64.Debug/Tetragrama/Debug/zEngineEditor --projectConfigFile "/path/to/RendererEngine/test/projectConfig.json"

Thread 0, Frame 0:
vkCreateInstance(pCreateInfo, pAllocator, pInstance) returns VkResult VK_SUCCESS (0):
   pCreateInfo:                    const VkInstanceCreateInfo* = 0x16dc45bb0:
       sType:                          VkStructureType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO (1)
       pNext:                          const void* = NULL
       flags:                          VkInstanceCreateFlags = 1 (VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR)
       pApplicationInfo:               const VkApplicationInfo* = 0x16dc49de0:
           sType:                          VkStructureType = VK_STRUCTURE_TYPE_APPLICATION_INFO (0)
           pNext:                          const void* = NULL
           pApplicationName:               const char* = "Tetragrama"
           applicationVersion:             uint32_t = 1
           pEngineName:                    const char* = "ZEngine"
           engineVersion:                  uint32_t = 1
           apiVersion:                     uint32_t = 4206592
       enabledLayerCount:              uint32_t = 3
       ppEnabledLayerNames:            const char* const* = 0x6000012332c0
           ppEnabledLayerNames[0]:         const char* const = "VK_LAYER_KHRONOS_validation"
           ppEnabledLayerNames[1]:         const char* const = "VK_LAYER_LUNARG_api_dump"
           ppEnabledLayerNames[2]:         const char* const = "VK_LAYER_KHRONOS_synchronization2"
       enabledExtensionCount:          uint32_t = 5
       ppEnabledExtensionNames:        const char* const* = 0x600000711300
           ppEnabledExtensionNames[0]:     const char* const = "VK_EXT_debug_report"
           ppEnabledExtensionNames[1]:     const char* const = "VK_EXT_debug_utils"
           ppEnabledExtensionNames[2]:     const char* const = "VK_KHR_surface"
           ppEnabledExtensionNames[3]:     const char* const = "VK_EXT_metal_surface"
           ppEnabledExtensionNames[4]:     const char* const = "VK_KHR_portability_enumeration"
       pNext:                          const void* = NULL
   pAllocator:                     const VkAllocationCallbacks* = NULL
   pInstance:                      VkInstance* = 0x11f03a200

Thread 0, Frame 0:
vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices) returns VkResult VK_SUCCESS (0):
   instance:                       VkInstance = 0x11f03a200
   pPhysicalDeviceCount:           uint32_t* = 1
   pPhysicalDevices:               VkPhysicalDevice* = NULL

Thread 0, Frame 0:
vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices) returns VkResult VK_SUCCESS (0):
   instance:                       VkInstance = 0x11f03a200
   pPhysicalDeviceCount:           uint32_t* = 1
   pPhysicalDevices:               VkPhysicalDevice* = 0x600001013e40
       pPhysicalDevices[0]:            VkPhysicalDevice = 0x60000122a440

Thread 0, Frame 0:
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties) returns void:
   physicalDevice:                 VkPhysicalDevice = 0x60000122a440
   pQueueFamilyPropertyCount:      uint32_t* = 4
   pQueueFamilyProperties:         VkQueueFamilyProperties* = NULL

Thread 0, Frame 0:
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties) returns void:
   physicalDevice:                 VkPhysicalDevice = 0x60000122a440
   pQueueFamilyPropertyCount:      uint32_t* = 4
   pQueueFamilyProperties:         VkQueueFamilyProperties* = 0x6000036003c0
       pQueueFamilyProperties[0]:      VkQueueFamilyProperties = 0x6000036003c0:
           queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
           queueCount:                     uint32_t = 1
           timestampValidBits:             uint32_t = 64
           minImageTransferGranularity:    VkExtent3D = 0x6000036003cc:
               width:                          uint32_t = 1
               height:                         uint32_t = 1
               depth:                          uint32_t = 1
       pQueueFamilyProperties[1]:      VkQueueFamilyProperties = 0x6000036003d8:
           queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
           queueCount:                     uint32_t = 1
           timestampValidBits:             uint32_t = 64
           minImageTransferGranularity:    VkExtent3D = 0x6000036003e4:
               width:                          uint32_t = 1
               height:                         uint32_t = 1
               depth:                          uint32_t = 1
       pQueueFamilyProperties[2]:      VkQueueFamilyProperties = 0x6000036003f0:
           queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
           queueCount:                     uint32_t = 1
           timestampValidBits:             uint32_t = 64
           minImageTransferGranularity:    VkExtent3D = 0x6000036003fc:
               width:                          uint32_t = 1
               height:                         uint32_t = 1
               depth:                          uint32_t = 1
       pQueueFamilyProperties[3]:      VkQueueFamilyProperties = 0x600003600408:
           queueFlags:                     VkQueueFlags = 7 (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)
           queueCount:                     uint32_t = 1
           timestampValidBits:             uint32_t = 64
           minImageTransferGranularity:    VkExtent3D = 0x600003600414:
               width:                          uint32_t = 1
               height:                         uint32_t = 1
               depth:                          uint32_t = 1

Thread 0, Frame 0:
vkCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger) returns VkResult VK_SUCCESS (0):
   instance:                       VkInstance = 0x11f03a200
   pCreateInfo:                    const VkDebugUtilsMessengerCreateInfoEXT* = 0x16dc49aa8:
       sType:                          VkStructureType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT (1000128004)
       pNext:                          const void* = NULL
       flags:                          VkDebugUtilsMessengerCreateFlagsEXT = 0
       messageSeverity:                VkDebugUtilsMessageSeverityFlagsEXT = 4369 (VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
       messageType:                    VkDebugUtilsMessageTypeFlagsEXT = 7 (VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
       pfnUserCallback:                PFN_vkDebugUtilsMessengerCallbackEXT = 1
       pUserData:                      void* = NULL
   pAllocator:                     const VkAllocationCallbacks* = NULL
   pMessenger:                     VkDebugUtilsMessengerEXT* = 0x600001014db0
   ```

ZzzhHe avatar Jan 10 '25 23:01 ZzzhHe

well, I guess I'd need to find a M1 device for further investigation -any info from the log? (Should be available at Tetragrama/Debug/Log/engine_dump.log)

JeanPhilippeKernel avatar Jan 11 '25 16:01 JeanPhilippeKernel

well, I guess I'd need to find a M1 device for further investigation -any info from the log? (Should be available at Tetragrama/Debug/Log/engine_dump.log)

I couldn’t find the Log folder in Tetragrama/Debug/. Did I miss a step?

Here’s what I did:

  1. I built the project using:
.\Scripts\BuildEngine.ps1 -Configurations Debug -RunBuilds $True
  1. Then, I ran the Panzerfaust, but I encountered an error when clicking the "Open" button:
./Result.Darwin.x64.Debug/Panzerfaust/Debug/net8.0/osx-arm64/Panzerfaust                                                     2025-01-11 14:40:16.864 Panzerfaust[5519:78689] +[IMKClient subclass]: chose IMKClient_Modern
2025-01-11 14:40:16.864 Panzerfaust[5519:78689] +[IMKInputSession subclass]: chose IMKInputSession_Modern
Unhandled exception. System.ComponentModel.Win32Exception (2): An error occurred trying to start process '/Users/h/Programming/GitRepo/RendererEngine/Editor/zEngineEditor' with working directory '/Users/h/Programming/GitRepo/RendererEngine/Editor'. No such file or directory
   at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec)
   at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Panzerfaust.Service.EngineService.StartAsync(String path) in /Users/h/Programming/GitRepo/RendererEngine/Panzerfaust/Service/EngineService.cs:line 40
   at Panzerfaust.ViewModels.ProjectViewModel.OnOpenProjectCommand() in /Users/h/Programming/GitRepo/RendererEngine/Panzerfaust/ViewModels/ProjectViewModel.cs:line 56
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
   at Avalonia.Threading.SendOrPostCallbackDispatcherOperation.InvokeCore()
   at Avalonia.Threading.DispatcherOperation.Execute()
   at Avalonia.Threading.Dispatcher.ExecuteJob(DispatcherOperation job)
   at Avalonia.Threading.Dispatcher.ExecuteJobsCore(Boolean fromExplicitBackgroundProcessingCallback)
   at Avalonia.Threading.Dispatcher.Signaled()
   at Avalonia.Native.DispatcherImpl.Events.Signaled()
   at Avalonia.Native.Interop.Impl.__MicroComIAvnPlatformThreadingInterfaceEventsVTable.Signaled(Void* this)
--- End of stack trace from previous location ---
   at Avalonia.Native.DispatcherImpl.RunLoop(CancellationToken token)
   at Avalonia.Threading.DispatcherFrame.Run(IControlledDispatcherImpl impl)
   at Avalonia.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.StartCore(String[] args)
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, Action`1 lifetimeBuilder)
   at Panzerfaust.Program.Main(String[] args) in /Users/h/Programming/GitRepo/RendererEngine/Panzerfaust/Program.cs:line 14
  1. So I ran the Engine with:
./Result.Darwin.x64.Debug/Tetragrama/Debug/zEngineEditor --projectConfigFile "/path/to/RendererEngine/test/projectConfig.json"

and result to that Vulkan error.

ZzzhHe avatar Jan 11 '25 19:01 ZzzhHe

it should be around the zEngineEditor

Screenshot 2025-01-11 at 21 49 01

JeanPhilippeKernel avatar Jan 11 '25 20:01 JeanPhilippeKernel

❯ ls -f Result.Darwin.x64.Debug/Tetragrama/Debug
.             ..            Settings      zEngineEditor Shaders

It seems there is no Logs folder.

ZzzhHe avatar Jan 11 '25 21:01 ZzzhHe