www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - SDL2 Android vulkan question

reply Danny Arends <Danny.Arends gmail.com> writes:
Dear all,

I've written a 2D/3D engine in D before which runs on windows, 
linux and android using SDL2 as the window manager and uses 
Modern OpenGL /OpenGLES for rendering. It compiles fine for 
android using ldc and works like a charm, although the garbage 
collection under android has multi-threading issues.

Since OpenGL is abandoned, I am currently adding Vulkan support 
to future proof it.

I have done this in D with the help of the bindbc-sdl and erupted 
packages and managed to get the whole vulkan-tutorial.com example 
working under windows without much hassle. (I bet it would run on 
linux without much issues as well)

So I have now been stuck for a week on getting the tutorial 
example to successfully run on android. To do this I get a DLL 
compiled with ldc, I have setup the SDL2 toolchain for android, 
with symlinks to SDL2/IMAGE/TTF/etc, I hook the call to SDL_main 
from the JNI:

```D
/* Main entry point to the program */
version (Android) {
   import core.memory;
   import core.runtime : rt_init;

   extern(C) int SDL_main(int argc, char* argv) { // Hijack the 
SDL main
     rt_init();
     GC.disable(); // The GC crashes on android
     run(["android"]);
     return(0);
   }
// Other OS can just call run() directly (No known issues with 
garbage collection)
} else { void main (string[] args) { run(args); } }
```

I create my APK using Android Studio, and load it onto my phone. 
The hook succeeds, I can do:

```D
loadSDL();
SDL_Log("SDL loaded");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
SDL_Log("SDL init");
SDL_Vulkan_LoadLibrary();
SDL_Log("SDL_Vulkan_LoadLibrary");
```

I see SDL being loaded and initialized (successfully) on my 
phone. However, the SDL_Vulkan_LoadLibrary call just crashes the 
whole thing dead, with a:

```cmd
I/SDL/APP: SDL loaded
I/SDL/APP: SDL init
A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault 
addr 0x0 in tid 25878 (SDLThread), pid 25794 (SDLActivity)
```

I was wondering if I am missing something obvious. Since it works 
for SDL2 and opengles

Any thoughts on why loading the Vulkan library using SDL2 would 
not work ?
thoughts in general about the process ?

Danny
May 02 2021
parent reply evilrat <evilrat666 gmail.com> writes:
On Sunday, 2 May 2021 at 08:58:30 UTC, Danny Arends wrote:

 Any thoughts on why loading the Vulkan library using SDL2 would 
 not work ?
 thoughts in general about the process ?
Just few tips. GC "crashes" since you have custom main, D default main has runtime initialization code so it "just works", in you custom main function try to do this before any call to D code. https://dlang.org/phobos/core_runtime.html#.Runtime.initialize ```d extern(C) main() { import core.runtime; Runtime.initialize(); scope(exit) Runtime.terminate(); } ``` As for SDL2, are you sure it was built with Vulkan support? Do you have any other Vulkan apps to test if it actually supported by your device?
May 02 2021
next sibling parent reply evilrat <evilrat666 gmail.com> writes:
On Sunday, 2 May 2021 at 12:35:51 UTC, evilrat wrote:
 On Sunday, 2 May 2021 at 08:58:30 UTC, Danny Arends wrote:

 Any thoughts on why loading the Vulkan library using SDL2 
 would not work ?
 thoughts in general about the process ?
Just few tips. GC "crashes" since you have custom main, D default main has runtime initialization code so it "just works", in you custom main function try to do this before any call to D code.
Oops, nevermind. I thought you've missed runtime initialization at all but you have rt_init. In that case you can try disable parallel collection, or it could be a bug. https://dlang.org/spec/garbage.html#gc_config https://dlang.org/spec/garbage.html#gc_parallel
 As for SDL2, are you sure it was built with Vulkan support?
 Do you have any other Vulkan apps to test if it actually 
 supported by your device?
SDL2 docs also says vulkan load library should be called only after you created window surface. It is hard to say from provided code if you have that too. Anyway, I might try to look at this next weekend. Do you have this project available on github/google drive?
May 02 2021
next sibling parent Danny Arends <Danny.Arends gmail.com> writes:
On Sunday, 2 May 2021 at 13:43:11 UTC, evilrat wrote:
 On Sunday, 2 May 2021 at 12:35:51 UTC, evilrat wrote:
 On Sunday, 2 May 2021 at 08:58:30 UTC, Danny Arends wrote:

 Any thoughts on why loading the Vulkan library using SDL2 
 would not work ?
 thoughts in general about the process ?
Just few tips. GC "crashes" since you have custom main, D default main has runtime initialization code so it "just works", in you custom main function try to do this before any call to D code.
Oops, nevermind. I thought you've missed runtime initialization at all but you have rt_init. In that case you can try disable parallel collection, or it could be a bug. https://dlang.org/spec/garbage.html#gc_config https://dlang.org/spec/garbage.html#gc_parallel
 As for SDL2, are you sure it was built with Vulkan support?
 Do you have any other Vulkan apps to test if it actually 
 supported by your device?
SDL2 docs also says vulkan load library should be called only after you created window surface. It is hard to say from provided code if you have that too.
Yeah, it's tricky to create an SDL window sometimes, like on android SDL_CreateWindow not being allowed to have it SDL_WINDOWPOS_CENTERED I thought they meant use it like after SDL_Init(), but before you create the window. I think the function pointer might not be loaded since the SDL_Init returns a which means 2.0.1 for some reason. I think something is going wrong and nothing is doing a dlopen() on vulkan.so
 Anyway, I might try to look at this next weekend. Do you have 
 this project available on github/google drive?
well it's just a bunch of files atm, but with a serious dependency chain, I'll try to minimize it. Guess for now the deprecated openGL has to be the fallback
May 02 2021
prev sibling parent Danny Arends <Danny.Arends gmail.com> writes:
On Sunday, 2 May 2021 at 13:43:11 UTC, evilrat wrote:
 Anyway, I might try to look at this next weekend. Do you have 
 this project available on github/google drive?
Open-sourced the code see: https://github.com/DannyArends/CalderaD Danny
May 14 2021
prev sibling parent reply Danny Arends <Danny.Arends gmail.com> writes:
On Sunday, 2 May 2021 at 12:35:51 UTC, evilrat wrote:
 On Sunday, 2 May 2021 at 08:58:30 UTC, Danny Arends wrote:

 Any thoughts on why loading the Vulkan library using SDL2 
 would not work ?
 thoughts in general about the process ?
Just few tips. GC "crashes" since you have custom main, D default main has runtime initialization code so it "just works", in you custom main function try to do this before any call to D code. https://dlang.org/phobos/core_runtime.html#.Runtime.initialize ```d extern(C) main() { import core.runtime; Runtime.initialize(); scope(exit) Runtime.terminate(); } ```
Yeah, I just use the rt_init() and disable it, no real issue. Most of the code is nogc code anyway.
 As for SDL2, are you sure it was built with Vulkan support?
That's the thing I worry about, since the SDL2 libraries are locally build using android studio and I'm kind of a noob in that. I use the provided android_project (from the sdl zip) and make symbolic links in the app/jni folder to: SDL, SDL2_Image, SDL2_Mixer, Etc I delete the creation of the libmain.so by removing the src/ folder
 Do you have any other Vulkan apps to test if it actually 
 supported by your device?
It's android 10 so it should be, but I could try creating a c minimal example in vulkan, although that's gonna be 500 LoC as well.
May 02 2021
parent reply evilrat <evilrat666 gmail.com> writes:
On Sunday, 2 May 2021 at 16:06:10 UTC, Danny Arends wrote:
 On Sunday, 2 May 2021 at 12:35:51 UTC, evilrat wrote:
 As for SDL2, are you sure it was built with Vulkan support?
That's the thing I worry about, since the SDL2 libraries are locally build using android studio and I'm kind of a noob in that.
Ok, since this is potentially the case, just to clarify, building C/C++ with CMake for Android these days is basically one extra parameter pointing to CMake toolchain file in your local NDK location when configuring your build. https://developer.android.com/ndk/guides/cmake#file (from the docs) ``` $ cmake \ -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=$ABI \ -DANDROID_NATIVE_API_LEVEL=$MINSDKVERSION \ $OTHER_ARGS ``` Then I would probably use gradle for the rest of the process to produce apk, including copy libraries step.
May 02 2021
parent Danny Arends <Danny.Arends gmail.com> writes:
On Sunday, 2 May 2021 at 16:42:07 UTC, evilrat wrote:
 On Sunday, 2 May 2021 at 16:06:10 UTC, Danny Arends wrote:
 On Sunday, 2 May 2021 at 12:35:51 UTC, evilrat wrote:
 As for SDL2, are you sure it was built with Vulkan support?
That's the thing I worry about, since the SDL2 libraries are locally build using android studio and I'm kind of a noob in that.
Ok, since this is potentially the case, just to clarify, building C/C++ with CMake for Android these days is basically one extra parameter pointing to CMake toolchain file in your local NDK location when configuring your build. https://developer.android.com/ndk/guides/cmake#file (from the docs) ``` $ cmake \ -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=$ABI \ -DANDROID_NATIVE_API_LEVEL=$MINSDKVERSION \ $OTHER_ARGS ``` Then I would probably use gradle for the rest of the process to produce apk, including copy libraries step.
Thanks, but the APK builds fine, and installs. OpenGLES and SDL work like a charm, it's just the SDL_Vulkan_LoadLibrary call crashing. I think it might have to do with the bindbc-sdl dependency compiling with SDL_201 support, while Vulkan needs SDL_206 minimum. Even though I set SDL_2014 in DUB, it seems not to get picked up in some way. I also found this: https://developer.android.com/guide/topics/manifest/uses-feature-element So it might be the manifest needs to be updated as well. A real puzzle, Danny
May 02 2021