KhronosGroup / MoltenVK

MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS.
Apache License 2.0
4.74k stars 414 forks source link

vkCreateMacOSSurfaceMVK crashed with EXC_BAD_ACCESS #1422

Closed SpectralDragon closed 3 years ago

SpectralDragon commented 3 years ago

I try to create surface on my mac using MTKView, but I got crash EXC_BAD_ACCESS, but for SDL2, SDL_Vulkan_CreateSurface return correct VkSurfaceKHR with same VkInstance.

Vulkan SDK: 1.2.182.0

Layers: VK_LAYER_KHRONOS_validation Extensions: VK_KHR_get_physical_device_properties2, VK_KHR_surface, VK_EXT_debug_utils, VK_MVK_macos_surface

This is how my implementation looks:

image

Also, proof that my view contents CAMetalLayer:

image

I can't find any resolved issue with my problem(

cdavis5e commented 3 years ago

How did you get the VkInstance object? How are you linking to vkCreateMacOSSurfaceMVK()? Are you linking to MoltenVK, or to the Vulkan loader (vulkan.framework on macOS)?

If instead of using Swift, you use Objective-C for your class, does it still break?

Where does Xcode say within MoltenVK the crash occurs? It doesn't even matter if you don't have a source location; the function and offset are enough.

SpectralDragon commented 3 years ago

@cdavis5e

How did you get the VkInstance object?

I published source code: https://github.com/LiteCode/AdaEngine AdaEditor/main.swift - Create window and initialize Vulkan Vulkan/ - all wrappers

Are you linking to MoltenVK, or to the Vulkan loader (vulkan.framework on macOS)?

Currenly has libvulkan.dylib and set required env variables:

export VULKAN_SDK="/Users/v.prusakov/VulkanSDK/1.2.182.0/macOS"
export VK_LAYER_PATH="$VULKAN_SDK/etc/vulkan/explicit_layer.d"
export VK_ICD_FILENAMES="$VULKAN_SDK/etc/vulkan/icd.d/MoltenVK_icd.json"
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"

I'm using Swift Package Manager, just for fun, but SPM can connect binary targets and supports compiler flags. Look at my Package.swift file

If instead of using Swift, you use Objective-C for your class, does it still break?

I can try tomorrow.

Where does Xcode say within MoltenVK the crash occurs?

App crashed in MVKSurface constructor

image
cdavis5e commented 3 years ago

So it's crashing trying to figure out whether the passed-in object is an NSView or a CAMetalLayer. To do this, it needs to invoke an Objective-C method. This leads me to suspect that this is the offending line in your code:

            pView: withUnsafePointer(to: view, { $0 }))

That is, you think you're getting a raw pointer to an Objective-C object, but you might not be. It might, for example, be a pointer to the variable holding the Objective-C pointer.

This is why I suspect that it would work if you used Objective-C. If it does, we'll know this is the most likely explanation.

You need to convert the object reference itself to an UnsafeRawPointer. The easiest way to do that, I think, is to simply pass the reference here and let implicit bridging work its magic:

            pView: view)

Did you try that before, and the compiler complained?

cdavis5e commented 3 years ago

Another possibility is that the raw pointer is being destroyed before you expect. According to the docs for withUnsafePointer(to:_:):

The pointer argument is valid only for the duration of the function’s execution.

If what I suggested above doesn't work, then the solution may be to enclose the entire call to vkCreateMacOSSurface() in the closure passed to withUnsafePointer(to:_:).

SpectralDragon commented 3 years ago

Yeah! You was right, that withUnsafePointer(to:_:) return pointer to local variable.

This is why I suspect that it would work if you used Objective-C. If it does, we'll know this is the most likely explanation.

You need to convert the object reference itself to an UnsafeRawPointer. The easiest way to do that, I think, is to simply pass the reference here and let implicit bridging work its magic:

            pView: view)

Did you try that before, and the compiler complained?

If I pass NSView as pView: view, compiler pushed next error:

image

If I use & I got next error:

image

And of course, inout wasn't solved my problem.

I fixed that crash and pass UnsafeMutableRawPointer using Unmanaged.passRetain(view).autorelease().toOpaque() call. It's work very well, but I don't think that is safety way :D

Thanks for your suggestions you saved my day! And thanks, that you answer so fast, like a Flash, that was important for me <3