LWJGL / lwjgl3

LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL, Vulkan, bgfx), audio (OpenAL, Opus), parallel computing (OpenCL, CUDA) and XR (OpenVR, LibOVR, OpenXR) applications.
https://www.lwjgl.org
BSD 3-Clause "New" or "Revised" License
4.75k stars 635 forks source link

Vulkan on MacOS - Why not use the Vulkan Loader first? #923

Closed RefuX closed 1 year ago

RefuX commented 1 year ago

Description

in org.lwjgl.vulkan.VK.create() for MACOSX we try to load the MoltenVK library and if it cannot be found we try to load the libvulkan.1.dylib (Vulkan Loader) library

What I propose is to switch this order and include the libvulkan.1.dylib in the lwjgl-vulkan macos native jar. My rational is to make the process more straightforward for developers, with the only downside for end-users is we're going through the Vulkan Loader, which is recommend anyway (reference below).

As a developer, one of the first things you will do is download the Vulkan SDK to use the Validation Layers, but they won't work because lwjgl uses the MoltenVK directly. The MacOS developer will have to read through all the documentation to figure out (over a day or two I might add) that they need to reference the Vulkan Loader and not MoltenVK.

Recommendation by the SDK provider: https://vulkan.lunarg.com/doc/sdk/1.3.261.1/mac/getting_started.html

For desktop applications, the recommended usage model is to use the MoltenVK dynamic library in conjunction with the Vulkan Loader. In this scenario the MoltenVK library takes on the role of the ICD from the point of view of the application and the Vulkan Loader. In this mode, you link only to the Vulkan Loader, and not the MoltenVK library directly. You will include the MoltenVK and the Vulkan Loader dynamic libraries in your application's bundle when distributing your software. When the Vulkan SDK is installed on macOS, these runtime components are placed in system directories and can be easily used during development without embedding them in the app bundle. Even if you decide to ship your application linked to the static MoltenVK library, during development we recommend you make use of the Vulkan Loader and Vulkan Validation Layers as they are a tremendous boon for debugging your Vulkan-based rendering code.

Spasi commented 1 year ago

Hey @RefuX,

I'd like to avoid having to build yet another native library, just for macOS. For macOS development, the Vulkan Loader should already be installed and available by the Vulkan SDK.

So, the question becomes whether we should try loading MoltenVK or the loader first. The current behavior was chosen for simplicity. If the loader is loaded first and it's not available, you get the Failed to load a library [...] output, which could confuse users. By loading the bundled MoltenVK, you always get a known MoltenVK build, regardless of where/how the application is deployed. That build is also usually newer than the one shipped by the Vulkan SDK (e.g. the build in LWJGL 3.3.3 includes fixes that are not available in MoltenVK 1.2.5, shipped by the latest Vulkan SDK).

On the other hand, the concern you raise is fair and I acknowledge that it's not immediately obvious how to interact with the Vulkan SDK during development. Would it help if we added javadoc to the VK class that explains what to do? (which is call Configuration.VULKAN_LIBRARY_NAME.set("<path_to>/libvulkan.1.dylib"); or pass -Dorg.lwjgl.vulkan.libname=<path_to>/libvulkan.1.dylib)

Alternatively, we could add another Configuration option that flips the order. However, as we've seen in #845, libvulkan.1.dylib is not always globally accessible and you have to set the full path with VULKAN_LIBRARY_NAME anyway.

Finally, you could run the application without lwjgl-vulkan-natives-macos.jar in the class/module-path. This will cause a fallback to libvulkan.1.dylib (but, again, you get the "failed to load a library" message).

RefuX commented 1 year ago

Hi @Spasi

If only everything could be straightforward? :)

I did do a test this morning, and to get my app to work I have to have full path to /usr/local/lib/libvulkan.1.dylib in the org.lwjgl.vulkan.libname property. Which means (for me) even if we tried to find the Vulcan Loader (libvulkan.1.dylib) first, we would not of found it since we need to hardcode the full path.

As a developer I always like to have not too much surprising behaviour, and getting the validation libraries working on masOS was surprisingly difficult! I think it would certainly help to add javadoc to the VK class, and we've also got the vulkanbook documentation updated, so at least developers now have some clues.

Spasi commented 1 year ago

I've added some documentation to VK. Thank you for the feedback @RefuX!