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

macOS Support via MoltenVK #13

Open
nicholas-ochoa opened this issue Jan 31, 2019 · 16 comments
Open

macOS Support via MoltenVK #13

nicholas-ochoa opened this issue Jan 31, 2019 · 16 comments

Comments

@nicholas-ochoa
Copy link

Is it possible to utilize MoltenVK to add support for macOS? It's a thin wrapper around the native Metal API available on macOS. As an example, the Dolphin project was able to add support using MoltenVK - though that's a C++ project versus Java - hopefully there aren't a significant number of differences or issues preventing implementation.

@Ealrann
Copy link
Owner

Ealrann commented Feb 1, 2019

In fact, VSand should be really close to support MoltenVK. LWJGL seems to support it natively.
My main problem is... I have no mac computer to make the build and test. I will do it one day.

However, if you have a jdk11, gradle and git (with LFS) installed on your computer, running the project 'should' be as easy as :

git clone --recursive https://github.com/Ealrann/VSand.git
cd VSand
gradle run

@kvark
Copy link

kvark commented Feb 19, 2019

I just tried that on MacOS 10.14 after installing Java and Gradle from Homebrew, got the following:

Starting a Gradle Daemon (subsequent builds will be faster)

> Configure project :
Found module name 'org.eclipse.emf.common'
Found module name 'org.eclipse.emf.ecore'
Found module name 'org.eclipse.emf.ecore.xmi'
Found module name 'org.sheepy.lily.core.api'
Found module name 'org.sheepy.lily.core.impl'
Found module name 'org.sheepy.lily.vulkan.api'
Found module name 'org.sheepy.lily.vulkan.common'
Found module name 'org.sheepy.lily.vulkan.demo'
Found module name 'org.sheepy.lily.vulkan.gameoflife'
Found module name 'org.sheepy.lily.vulkan.nuklear'
Found module name 'org.sheepy.lily.vulkan.process'
Found module name 'org.sheepy.lily.vulkan.process.compute'
Found module name 'org.sheepy.lily.vulkan.process.graphic'
Found module name 'org.sheepy.lily.vulkan.resource'
Found module name 'org.sheepy.vsand'

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/dmalyshau/Code/VSand/org.sheepy.vsand/build.gradle' line: 32

* What went wrong:
A problem occurred evaluating project ':org.sheepy.vsand'.
> Could not find method runClient() for arguments [build_30byraxjrj9qbliumqviimz2k$_run_closure4@3962c8f2] on project ':org.sheepy.vsand' of type org.gradle.api.Project.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 11s

I don't intend to investigate the build issues, but if you reach a point where you can build, I'd be happy to assist with making sure it works with Vulkan Portability.

@Ealrann
Copy link
Owner

Ealrann commented Feb 20, 2019

Thank you for the log. I made a commit to fix this error, but I'm still blind without OSX test platform.
I will probably investigate/build in April.

@kvark
Copy link

kvark commented Feb 20, 2019

Assuming LWJGL supports Vulkan on MacOS already, I tried to investigate further. With some trial and error, I convinced it to locate libvulkan.1.dylib by adding the following configuration:

application {
    applicationDefaultJvmArgs = ["-Dorg.lwjgl.librarypath=/Users/dmalyshau/Code/vulkansdk/macOS/lib/"]
}

However, now I'm getting the following error:

[LWJGL] [ERROR] Incompatible Java and native library versions detected.
Possible reasons:
        a) -Djava.library.path is set to a folder containing shared libraries of an older LWJGL version.
        b) The classpath contains jar files of an older LWJGL version.
Possible solutions:
        a) Make sure to not set -Djava.library.path (it is not needed for developing with LWJGL 3) or make
           sure the folder it points to contains the shared libraries of the correct LWJGL version.
        b) Check the classpath and make sure to only have jar files of the same LWJGL version in it.
java.lang.ExceptionInInitializerError
        at org.lwjgl.glfw/org.lwjgl.glfw.GLFW.glfwCreateWindow(GLFW.java:1842)
        at org.sheepy.lily.vulkan.common/org.sheepy.lily.vulkan.common.window.Window.open(Window.java:51)
        at org.sheepy.lily.vulkan.common/org.sheepy.lily.vulkan.common.engine.VulkanEngineAdapter.start(VulkanEngineAdapter.java:170)
        at org.sheepy.lily.vulkan.common/org.sheepy.lily.vulkan.common.engine.VulkanEngineAdapter.load(VulkanEngineAdapter.java:142)
        at org.sheepy.lily.core.impl/org.sheepy.lily.core.adapter.ServiceAdapterFactory$AutoEContentAdapter.loadAutoAdapters(ServiceAdapterFactory.java:105)
        at org.sheepy.lily.core.impl/org.sheepy.lily.core.adapter.ServiceAdapterFactory$AutoEContentAdapter.setTarget(ServiceAdapterFactory.java:87)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.util.EContentAdapter.setTarget(EContentAdapter.java:212)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.impl.MinimalEObjectImpl$1ArrayDelegatingAdapterList.didAdd(MinimalEObjectImpl.java:488)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.impl.MinimalEObjectImpl$1ArrayDelegatingAdapterList.didAdd(MinimalEObjectImpl.java:453)
        at org.eclipse.emf.common/org.eclipse.emf.common.util.ArrayDelegatingEList.addUnique(ArrayDelegatingEList.java:389)
        at org.eclipse.emf.common/org.eclipse.emf.common.util.AbstractEList.add(AbstractEList.java:304)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.util.EContentAdapter.addAdapter(EContentAdapter.java:412)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.util.EContentAdapter.setTarget(EContentAdapter.java:251)
        at org.sheepy.lily.core.impl/org.sheepy.lily.core.adapter.ServiceAdapterFactory$AutoEContentAdapter.setTarget(ServiceAdapterFactory.java:88)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.util.EContentAdapter.setTarget(EContentAdapter.java:212)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.impl.MinimalEObjectImpl$1ArrayDelegatingAdapterList.didAdd(MinimalEObjectImpl.java:488)
        at org.eclipse.emf.ecore/org.eclipse.emf.ecore.impl.MinimalEObjectImpl$1ArrayDelegatingAdapterList.didAdd(MinimalEObjectImpl.java:453)
        at org.eclipse.emf.common/org.eclipse.emf.common.util.ArrayDelegatingEList.addUnique(ArrayDelegatingEList.java:389)
        at org.eclipse.emf.common/org.eclipse.emf.common.util.AbstractEList.add(AbstractEList.java:304)
        at org.sheepy.lily.core.impl/org.sheepy.lily.core.adapter.ServiceAdapterFactory.setupAutoAdapters(ServiceAdapterFactory.java:65)
        at org.sheepy.lily.core.impl/org.sheepy.lily.core.cadence.common.Cadencer.load(Cadencer.java:86)
        at org.sheepy.lily.core.impl/org.sheepy.lily.core.application.ApplicationAdapter$2.run(ApplicationAdapter.java:58)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalStateException: GLFW windows may only be created on the main thread and that thread must be the first thread in the process. Please run the JVM with -XstartOnFirstThread. For offscreen rendering, make sure another window toolkit (e.g. AWT or JavaFX) is initialized before GLFW.
        at org.lwjgl.glfw/org.lwjgl.glfw.EventLoop$OffScreen.<clinit>(EventLoop.java:39)
        ... 27 more

I tried adding -XstartOnFirstThread to the applicationDefaultJvmArgs list with no result. Sorry if this is a trivial issue in Java/LWJGL/Gradle world, but I couldn't resolve it myself. It surprisingly sounds like a general issue that isn't necessarily tied to macOS, unless the application threading takes a different path here.

@Ealrann
Copy link
Owner

Ealrann commented Feb 21, 2019

Maybe you use an old java version ? You can know with the command java --version.

To build VSand, you need the 11.

@kvark
Copy link

kvark commented Feb 21, 2019

@Ealrann it builds fine. Java version is 11.0.2
I double checked, and adding -XstartOnFirstThread does have a bit of an effect - the error message no longer suggests to add this option :) The stack trace implies that the application tries to initialize Vulkan on a thread (see "at java.base/java.lang.Thread.run(Thread.java:834)" at the bottom), so asking JVM to start on the first thread doesn't fix it. Is there any way to configure VSand/lily/lwjgl/whatever-else-in-the-stack to not spawn a thread for graphics initialization?

Ealrann added a commit that referenced this issue Feb 21, 2019
@Ealrann
Copy link
Owner

Ealrann commented Feb 21, 2019

Thank you very much for your interest!

Assuming LWJGL supports Vulkan on MacOS already, I tried to investigate further. With some trial and error, I convinced it to locate libvulkan.1.dylib by adding the following configuration:

application {
    applicationDefaultJvmArgs = ["-Dorg.lwjgl.librarypath=/Users/dmalyshau/Code/vulkansdk/macOS/lib/"]
}

Ok, I think you no longer need to do that with the previous commit (I advice you to update your local repo with git pull --recurse-submodules).

About the GLFW error:

GLFW windows may only be created on the main thread and that thread must be the first thread in the process.

Haha, I don't have this error on linux/windows... Indeed, the window creation happen inside a thread. Since VSand is based on a big abstraction layer, it's not easy to change that properly.

@Ealrann
Copy link
Owner

Ealrann commented Feb 21, 2019

More informations (but no solutions for now):

The relevant code in LWJGL (EventLoop.java (l.60)):

if (Platform.get() == Platform.MACOSX && !isMainThread()) {
        throw new IllegalStateException("Please run the JVM with -XstartOnFirstThread and make sure a window toolkit other than GLFW (e.g. AWT or JavaFX) is not initialized.");
}

So it's definitely specific to MacOSX.

Spasi gave a way to disable this check (it would probably crash):

You could also try Configuration.GLFW_CHECK_THREAD0.set(false); (or launch the JVM with -Dorg.lwjgl.glfw.checkThread0=false). This will disable the check and you won't get that exception (but you may get a crash, depending on what your tests are doing).

@kvark
Copy link

kvark commented Feb 21, 2019

With this option, it's getting slightly further but essentially failing at the same thing:

[LWJGL] [ERROR] Incompatible Java and native library versions detected.
Possible reasons:
        a) -Djava.library.path is set to a folder containing shared libraries of an older LWJGL version.
        b) The classpath contains jar files of an older LWJGL version.
Possible solutions:
        a) Make sure to not set -Djava.library.path (it is not needed for developing with LWJGL 3) or make
           sure the folder it points to contains the shared libraries of the correct LWJGL version.
        b) Check the classpath and make sure to only have jar files of the same LWJGL version in it.
2019-02-21 09:18:36.675 java[2780:41058] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /BuildRoot/Library/Caches/com.apple.xbs/Sources/Foundation/Foundation-1570.12/Foundation/Misc.subproj/NSUndoManager.m:361
2019-02-21 09:18:36.677 java[2780:41058] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.'
*** First throw call stack:
(
        0   CoreFoundation                      0x00007fff3238cdb9 __exceptionPreprocess + 256
        1   libobjc.A.dylib                     0x00007fff5d01fa17 objc_exception_throw + 48
        2   CoreFoundation                      0x00007fff323a7ad6 +[NSException raise:format:arguments:] + 98
        3   Foundation                          0x00007fff346fbe11 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
        4   Foundation                          0x00007fff3462ee7c +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 473
        5   AppKit                              0x00007fff2f958fd5 -[NSApplication run] + 916
        6   libglfw.dylib                       0x0000000131212245 libglfw.dylib + 70213
        7   libglfw.dylib                       0x0000000131211582 libglfw.dylib + 66946
        8   libglfw.dylib                       0x000000013120b6d6 libglfw.dylib + 42710
        9   ???                                 0x00000001157148b0 0x0 + 4654713008
        10  ???                                 0x000000011570e750 0x0 + 4654688080
)
libc++abi.dylib: terminating with uncaught exception of type NSException

@Ealrann
Copy link
Owner

Ealrann commented Mar 8, 2019

With recent commits, the error with GLFW shouldn't appear anymore, the calls are no longer made in a thread.

About [LWJGL] [ERROR] Incompatible Java and native library versions detected., I think it's due to

application {
    applicationDefaultJvmArgs = ["-Dorg.lwjgl.librarypath=/Users/dmalyshau/Code/vulkansdk/macOS/lib/"]
}

Don't keep that in your build.gradle.

@kvark
Copy link

kvark commented Mar 8, 2019

@Ealrann after updating the source, I'm now getting "cannot find symbol import org.sheepy.lily.vulkan.model.XXX" errors. What am I missing?

@Ealrann
Copy link
Owner

Ealrann commented Mar 8, 2019

Mhhh, weird. Maybe the submodules are not up to date? Try git submodule update

Otherwise, you could try to make a fresh clone

git clone --recursive https://github.com/Ealrann/VSand.git
cd VSand
gradle run

I just tried to be sure, it works here at least.

@kvark
Copy link

kvark commented Mar 8, 2019

Ok, that worked. It is now failing to create a shader module, claiming the magic number to be invalid (73726576). I'm not used to debugging Java apps, and the usual VK_ICD_FILENAMES=XXX doesn't appear to be respected when I do gradle run, hmm...

@Ealrann
Copy link
Owner

Ealrann commented Mar 8, 2019

Ok, about the magic number invalid: I think you need to setup git lfs (an extension of git). After that, I think you have no choices but clone again the repository.

I'm not totally sure if it's a good idea to manage the compiled shaders with git lfs...

@kvark
Copy link

kvark commented Mar 8, 2019

Alright, that helped. I'd expect a different error message in case some files are missing, and at an earlier stage than running, but that's not critical.

The good news is that I was able to run VSand via both gfx-portability and MoltenVK 🎉
vsand

A caveat though that I wasn't able to convince gradle to find the vulkan SDK by any other way than adding applicationDefaultJvmArgs to the config as specified above.

On this note, it doesn't appear that my assistance is needed any more. Please feel free to ping if encounter any technical issues.
My only request for you is to implement and document the support in a generic way that expects a Vulkan Portability implementation as opposed to MoltenVK specifically... starting with the issue title ;)

@Ealrann
Copy link
Owner

Ealrann commented Mar 9, 2019

Yeay, thank you for your testing. I see that the game is working, but the UI is not displayed correctly. I'll make a proper MacOS support sooner or latter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants