Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instance creation fails on iOS using MoltenVK #49

Open
jadtl opened this issue Mar 22, 2021 · 34 comments
Open

Instance creation fails on iOS using MoltenVK #49

jadtl opened this issue Mar 22, 2021 · 34 comments
Labels
bug Something isn't working

Comments

@jadtl
Copy link

jadtl commented Mar 22, 2021

When using value() on the instance builder, an assertion fails and the error is simply vkb_instance:0. The same doesn't happen under macOS even when using the same XCFramework.

I've tried manually creating the instance to see if something's wrong with the library but it worked so I don't know what's going wrong here.

If you have an idea what could be causing this any help is welcome. Thanks.

@charles-lunarg
Copy link
Owner

Can you report which assertion failed? This should indicate where the issue is coming from.
vk-bootstrap was written to assert if there is no value in the result, eg it is an error. Thus you should check for an error before using the value.

@jadtl
Copy link
Author

jadtl commented Mar 22, 2021

The following assertion failed: T& value () & { assert (m_init); return m_value; }.
And I actually check for an error before using the value:

vkb::InstanceBuilder builder;

auto instanceBuilder = builder.set_engine_name(settings.engineName.c_str())
    .set_engine_version(0, 1)
    .set_app_name(settings.applicationName.c_str())
    .set_app_version(0, 1)
    .require_api_version(1, 1, 0);

if (settings.validate) instanceBuilder.request_validation_layers(true).use_default_debug_messenger();
if (settings.verbose) instanceBuilder.add_debug_messenger_severity(VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT);

auto instanceBuilderSuccess = instanceBuilder.build();

if (!instanceBuilderSuccess)
    std::cerr << "Failed to create Vulkan instance: " << instanceBuilderSuccess.error() << "\n";

vkb::Instance vkbInstance = instanceBuilderSuccess.value();

@charles-lunarg
Copy link
Owner

Thank you for showing the code, this helps me a lot when understanding whats going on. It clears up how you were indeed doing the right thing from the get go, as this code looks correct.

While it shouldn't be a problem, could you try not copying the builder onto instanceBuilder? I hadn't thought about the possibility of users making such copies. The compiler should generate the correct copy constructor, but I fear it hasn't and there are dangling references/pointers.

Beyond that, is there any way for you to get the value of the VkResult? This may be a bug in the return type like incorrect constructor or assignment, but I don't have an iOS device in which I could run this on to reproduce.

@jadtl
Copy link
Author

jadtl commented Mar 22, 2021

I did as you suggested:

vkb::InstanceBuilder builder;

auto instanceBuilder = builder.set_engine_name(settings.engineName.c_str())
    .set_engine_version(0, 1)
    .set_app_name(settings.applicationName.c_str())
    .set_app_version(0, 1)
    .require_api_version(1, 1, 0)
    .build();

if (!instanceBuilder)
    std::cerr << "Failed to create Vulkan instance: " << instanceBuilder.error() << "\n";

vkb::Instance vkbInstance = instanceBuilder.value();

Unfortunately I still end up with the same exact issue.

Regarding the value of vk_result, Xcode's debugger indicates it's VK_SUCCESS.

Here's the output of the debugger:

Screenshot 2021-03-22 at 19 15 16

@charles-lunarg
Copy link
Owner

I figured that the change I suggested wouldn't help. Which is good since I was reasonably confident it wasn't the problem. But better to check and find out its not.

Weird, the m_init is false, which shouldn't be the case if it successfully created an instance.
Which 'version' of vk-bootstrap are you using? I've fixed a few apple related bugs (like the wrong surface extension name) and you may have used an older version, which some tutorials haven't gotten around to updating yet.

Otherwise, i'm not sure whats causing the error.

@jadtl
Copy link
Author

jadtl commented Mar 22, 2021

I was using vk-bootstrap from a 4 days old git clone, I tried your latest release too without any luck.

I don't get the error, what causes it to be vkb_instance:0 exactly? I looked through the library's code but couldn't find out why, maybe it thinks Vulkan is unavailable?

@charles-lunarg
Copy link
Owner

I figured you might of used the latest version, best to be sure.

It not finding vulkan could be possibly the case, maybe its failing to fail properly.
Not sure what vkb_instance:0 means, but I think its simply whatever the assertion is 'returning'.
Maybe the vulkan function loading logic is failing? fp_vkGetInstanceProcAddrlooks correct in the builder but not in the instance (though that may be 'uninitialized' logic happening.

@charles-lunarg
Copy link
Owner

Have you had any success/failure since then? I don't have access to a iOS device in which to reproduce but I certainly am willing to see if I can set one up.

@jadtl
Copy link
Author

jadtl commented Mar 29, 2021

I've been looking at it for a while last week but now I'm too busy studying, I'll probably get back to it next week. In the meantime if you have any changes in the code you'd like me to test I'll sure do it.

You'd only need a Mac (or a VM, but I don't know how that would play out with Metal without GPU passthrough) in order to build and run my project on Xcode's iOS simulator, and either way macOS is needed even if you have an iOS device, so I doubt it's worth the hassle.

@charles-lunarg
Copy link
Owner

Any update on the issue?

@jadtl
Copy link
Author

jadtl commented Jun 9, 2021

Sadly not, I'm focused on my semester right now and I didn't manage to get a better grasp at the issue last time I tried.

@wmarti
Copy link

wmarti commented Oct 5, 2021

Hello, I'm getting the same issue, where this assertion fails:
T& operator* () & { assert (m_init); return m_value; }
I'm running on MacOS in Xcode on the new M1 chip.
I'm also using the latest version of VkBootstrap.
Screen Shot 2021-10-05 at 3 53 20 PM
Screen Shot 2021-10-05 at 3 53 10 PM

Oddly enough, when I build the example code you include in the git repo I don't get this issue.

@charles-lunarg
Copy link
Owner

Wait, is this code being run on iOS? Then the issue is likely that vk-bootstrap is trying to load the loader and it doesn't exist. THe way around it is manually providing it with vkGetInstanceProcAddr.

@wmarti
Copy link

wmarti commented Feb 16, 2022

Wait, is this code being run on iOS? Then the issue is likely that vk-bootstrap is trying to load the loader and it doesn't exist. THe way around it is manually providing it with vkGetInstanceProcAddr.

No, being run on MacOS in XCode targeting the M1. I can give that a go sometime and report back.

@charles-lunarg
Copy link
Owner

That would be much appreciated.
And apologies for letting this lie silent for so long.
This project isn't my primary focus, so I can only really work on it in my free time.

@wmarti
Copy link

wmarti commented Feb 16, 2022

Not to worry, I totally understand. I’ll give it a try tomorrow then.

@jadtl
Copy link
Author

jadtl commented Feb 16, 2022

No, being run on MacOS in XCode targeting the M1. I can give that a go sometime and report back.

Well this is interesting. I'm not able to reproduce this issue when targeting Apple Silicon on CMake, could this be XCode related?

@wmarti
Copy link

wmarti commented Feb 16, 2022

I was able to build with CMake as well, only encountered this issue in XCode.

@charles-lunarg
Copy link
Owner

Is a cmake flag not being applied properly? This is indeed strange

@charles-lunarg charles-lunarg added the bug Something isn't working label Apr 26, 2022
@SteveGremory
Copy link

SteveGremory commented Jul 8, 2022

same issue on an M1 mac, actually; for some reason VKCube works perfectly fine though.

@P7AC1D
Copy link

P7AC1D commented Jul 15, 2022

I am also having this problem.

When stepping through the code it seems to fail here where both khr_surface_added and added_window_exts are false. Can it not find these extensions? If I do the vulkan setup manually without using this lib everything works fine so its definitely that vk-bootstrap is failing to find these extensions for whatever reason.

		bool khr_surface_added = check_add_window_ext("VK_KHR_surface");
#if defined(_WIN32)
		bool added_window_exts = check_add_window_ext("VK_KHR_win32_surface");
#elif defined(__ANDROID__)
		bool added_window_exts = check_add_window_ext("VK_KHR_android_surface");
#elif defined(_DIRECT2DISPLAY)
		bool added_window_exts = check_add_window_ext("VK_KHR_display");
#elif defined(__linux__)
		// make sure all three calls to check_add_window_ext, don't allow short circuiting
		bool added_window_exts = check_add_window_ext("VK_KHR_xcb_surface");
		added_window_exts = check_add_window_ext("VK_KHR_xlib_surface") || added_window_exts;
		added_window_exts = check_add_window_ext("VK_KHR_wayland_surface") || added_window_exts;
#elif defined(__APPLE__)
		bool added_window_exts = check_add_window_ext("VK_EXT_metal_surface");
#endif

@P7AC1D
Copy link

P7AC1D commented Jul 15, 2022

It appears it was an issue with linking with the vulkan libs.

I have solved the issue by following the correct installation guide here: https://vulkan.lunarg.com/doc/view/1.2.148.0/mac/getting_started.html

Basically, I ran the following which is located in the Vullan SDK directory:

./uninstall.sh
./install_vulkan.py

and then from your IDE terminal (I was using VSCode):

source setup-env.sh

After running that, the vk-boostrap can now correctly find the vulkan libs and everything seems to be working.

@charles-lunarg
Copy link
Owner

So the way vulkan finds moltenVK is by looking for the dynamic library, aka libvulkan.dylib. This might cause issues when both vk-bootstrap and moltenvk are linked into a binary (rather than loaded, which is when the app uses dlopen on dynamic libraries).
If someone could try giving the vkGetInstanceProcAddr they get from linking to vk-bootstrap, then the dynamic loading wont happen and instead all function pointers will be gotten using vkGetInstanceProcAddr, then we can root out if the loading is the issue.

@charles-lunarg
Copy link
Owner

After discussing this issue with a user, it was found that a very old bug where VK_EXT_metal_surface was spelled as VK_KHR_metal_surface caused instance creation to fail. This would explain most of the people's issues here, but it doesn't explain the situation where linking to moltenVK causes issue.

IF anyone inspects their version of VkBootstrap.cpp and sees VK_KHR_metal_surface, replace it with VK_EXT_metal_surface. This is an old bug that may exist out in the wild.

@MHDtA-dev
Copy link

MHDtA-dev commented Dec 22, 2022

I have the same issue on Intel MacBook. I checked the VkBootstrap source code, but there was VK_EXT_metal_surface everywhere. CMake file of my project:

cmake_minimum_required(VERSION 3.20)
project(vulkantest)

set(CMAKE_CXX_STANDARD 17)

find_package(SFML 3.0 COMPONENTS Graphics Audio REQUIRED)
find_package(vulkan REQUIRED)

include_directories(/usr/local/include/vkBootstrap/)

add_executable(vulkantest main.cpp Renderer.cpp Renderer.h)

target_link_libraries(vulkantest SFML::Graphics SFML::Audio)
target_link_libraries(vulkantest /usr/local/lib/libvk-bootstrap.dylib)
target_link_libraries(vulkantest Vulkan::Vulkan)

It crashes with error:
Assertion failed: (m_init), function value, file VkBootstrap.h, line 131.

selector.select().error() returns vkb_physical_device:0

I link the library correctly. I don't understand what the problem is.

UPD. I solved the issue by replacing SFML with SDL2. As it turned out, SFML was giving out a null window surface, which is why app was crashing.

@MariusBretzel
Copy link

I’m also encountering the same issue with the Assertion failed: (m_init), function value, file VkBootstrap.h, line 129.
I’m working on an Apple Silicon MacBook Air M2 and trying to get my Vulkan application running.

Has anyone managed to resolve this issue ?

@rojsc
Copy link

rojsc commented Jul 23, 2024

I stumbled over the same issue today, attempting to build for iOS on an M1 MacBook Pro.

So the way vulkan finds moltenVK is by looking for the dynamic library, aka libvulkan.dylib. This might cause issues when both vk-bootstrap and moltenvk are linked into a binary (rather than loaded, which is when the app uses dlopen on dynamic libraries). If someone could try giving the vkGetInstanceProcAddr they get from linking to vk-bootstrap, then the dynamic loading wont happen and instead all function pointers will be gotten using vkGetInstanceProcAddr, then we can root out if the loading is the issue.

I think I am linking to the library. I use CMake's find_package(Vulkan COMPONENTS MoltenVK) and then call target_link_libraries(myapp PRIVATE Vulkan::Vulkan). I furthermore embed the Vulkan and MoltenVK frameworks. See https://www.khronos.org/blog/developing-with-vulkan-on-apple-ios for details on the setup.

Passing the mentioned function-pointer address to vk-bootstrap solves the issue for me:

vkb::InstanceBuilder instance_builder(vkGetInstanceProcAddr);
auto inst_ret = instance_builder.build();
// ...

Thanks a lot for mentioning how to handle linking the library instead of loading it, @charles-lunarg! 🎉

@charles-lunarg
Copy link
Owner

I wonder if I can make vk-bootstrap check if there is a vkGetInstanceProcAddr available in the process and use that? This might fail catastrophically (getting the wrong vkGetInstanceProcAddr would be bad!) but it would automate this process. I'm still unsure the mechanism as for why macOS has difficulty finding anything, but I suppose the platform may have 'hardened' dlopen enough to make my loading code not work.

@rojsc
Copy link

rojsc commented Jul 24, 2024

I'm still unsure the mechanism as for why macOS has difficulty finding anything, but I suppose the platform may have 'hardened' dlopen enough to make my loading code not work.

Not sure about the others who reported here, but for me, this is an iOS-only issue. On macOS, vk-bootstrap works just fine without passing vkGetInstanceProcAddr to the instance builder.

@gloridifice
Copy link

gloridifice commented Oct 1, 2024

I faced the same problem on my M1 Mac. I solved it with following steps:

  • Replace all "VK_KHR_metal_surface" with "VK_EXT_metal_surface" in VkBootsrap.cpp file.
  • Enable "VK_EXT_metal_surface" extension in InstanceBuilder with .enable_extension method in my code.

And there are some other things using Vulkan on mac I noticed:

  • must enable PORTABILITY ENUMERATION extension in InstanceBuilder .enable_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)
  • enable "VK_KHR_portability_subset" in PhysicalDeviceSelector .add_desired_extension("VK_KHR_portability_subset")

Code

...
    auto instance_result = builder.set_app_name("Hello Vulkan Guide")
            .request_validation_layers(true)
            .use_default_debug_messenger()
            .enable_extension("VK_EXT_metal_surface")
            .enable_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)
            .require_api_version(1, 1, 0)
            .build();
...
    vkb::PhysicalDevice physicalDevice = selector
            .set_minimum_version(1, 1)
            .set_surface(_surface)
            .add_desired_extension("VK_KHR_portability_subset")
            .select()
            .value();

@charles-lunarg
Copy link
Owner

charles-lunarg commented Oct 1, 2024

@gloridifice All of the things you are doing aren't necessary - as in fixes for the issue have been implemented, such as KHR_metal -> EXT_metal, auto enabling portability enumeration and portability subset, and enabling VK_EXT_metal_surface automatically.

So it makes me think you are using an older version of vk-bootstrap which didn't have the fixes.

That said, I only did a visual inspection into the code. If you found that any of those steps were absolutely required even with tip-of-main then let me know.

For example: #if defined(__APPLE__) is used for checking if VK_EXT_metal_surface should be added. Maybe that macro needs updating?

@gloridifice
Copy link

@gloridifice All of the things you are doing aren't necessary - as in fixes for the issue have been implemented, such as KHR_metal -> EXT_metal, auto enabling portability enumeration and portability subset, and enabling VK_EXT_metal_surface automatically.

So it makes me think you are using an older version of vk-bootstrap which didn't have the fixes.

That said, I only did a visual inspection into the code. If you found that any of those steps were absolutely required even with tip-of-main then let me know.

For example: #if defined(__APPLE__) is used for checking if VK_EXT_metal_surface should be added. Maybe that macro needs updating?

Oh, yes. I'm following the vulkan guide so the version is old.
I tried update vk-bootstrap to the latest version but my code can't run.

n file included from /Users/yfan/MyProjects/Cpp/vulkan-guide-learning/third_party/vkbootstrap/VkBootstrap.h:29:
/Users/yfan/MyProjects/Cpp/vulkan-guide-learning/third_party/vkbootstrap/VkBootstrapDispatch.h:5258:66: error: unknown type name 'VkDepthClampModeEXT'
 5258 |     void cmdSetDepthClampRangeEXT(VkCommandBuffer commandBuffer, VkDepthClampModeEXT depthClampMode, const VkDepthClampRangeEXT* pDepthClampRange) const noexcept {
      |                                                                  ^
/Users/yfan/MyProjects/Cpp/vulkan-guide-learning/third_party/vkbootstrap/VkBootstrapDispatch.h:5258:108: error: unknown type name 'VkDepthClampRangeEXT'
 5258 |     void cmdSetDepthClampRangeEXT(VkCommandBuffer commandBuffer, VkDepthClampModeEXT depthClampMode, const VkDepthClampRangeEXT* pDepthClampRange) const noexcept {
      |                                                                                                            ^
/Users/yfan/MyProjects/Cpp/vulkan-guide-learning/third_party/vkbootstrap/VkBootstrapDispatch.h:7737:5: error: unknown type name 'PFN_vkCmdSetDepthClampRangeEXT'; did you mean 'PFN_vkCmdSetDepthClampEnableEXT'?
 7737 |     PFN_vkCmdSetDepthClampRangeEXT fp_vkCmdSetDepthClampRangeEXT = nullptr;
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |     PFN_vkCmdSetDepthClampEnableEXT

@charles-lunarg
Copy link
Owner

Ah right that might be TOO new of a version. I would suggest the version matching your sdk version (or whatever your header version is). Like 1.3.290 for example.

@gloridifice
Copy link

Ah right that might be TOO new of a version. I would suggest the version matching your sdk version (or whatever your header version is). Like 1.3.290 for example.

I tried the version matching my sdk version. It works well. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

9 participants