VK_EXT_metal_surface extension missing despite being enabled on macOS M1 and M2
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
- Enabled
VK_EXT_metal_surfaceextension - confirmed present in extension list - Added required macOS-specific extensions:
- VK_KHR_portability_enumeration
- VK_KHR_get_physical_device_properties2
- Set proper instance creation flags for macOS
- Verified library linking and loading order
- 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
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]
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.
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
```
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)
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:
- I built the project using:
.\Scripts\BuildEngine.ps1 -Configurations Debug -RunBuilds $True
- 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
- 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.
it should be around the zEngineEditor
❯ ls -f Result.Darwin.x64.Debug/Tetragrama/Debug
. .. Settings zEngineEditor Shaders
It seems there is no Logs folder.