VSand
VSand copied to clipboard
macOS Support via MoltenVK
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.
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
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.
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.
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.
Maybe you use an old java version ? You can know with the command java --version
.
To build VSand, you need the 11.
@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?
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.
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).
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
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.
@Ealrann after updating the source, I'm now getting "cannot find symbol import org.sheepy.lily.vulkan.model.XXX" errors. What am I missing?
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.
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...
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...
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 :tada:
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 ;)
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.