Vulkan rendering support on Android#36919
Conversation
7354153 to
9596089
Compare
9596089 to
15d968c
Compare
|
@akien-mga Thanks for the review! I've just pushed some changes based on your comments. |
|
I think this is OK, although it may need to be refactored to use the DisplayServer code that will be merged in a week or two. |
15d968c to
15110dd
Compare
There was a problem hiding this comment.
This has to be invoked on the rendering thread; I imagine you moved it here in order to be able to access the value for the video driver.
Instead, in export.cpp, can you push the driver type as a command line argument the same way we do it for the xrMode.
There was a problem hiding this comment.
Yes that's the reason.
I can do it by command line instead as you suggested, but in this case we'll have less options when we want to handle the fallback to OpenGL when Vulkan is not supported on the device (at this point I'm not sure if we'll do that in c++ or java).
This part of the code is supposed to handle the case where Main::setup is called on the UI thread and it seems to work fine so far:
godot/platform/android/java_godot_lib_jni.cpp
Lines 197 to 199 in 989a223
What part of the setup do you think is going to cause problems when not run on the render thread?
There was a problem hiding this comment.
My main worry is regarding thread safety since setup initializes some data structures that setup2 and the rest of the logic access at runtime.
With your changes, setup concludes before the render thread is started, so data access should be safe, especially given that Godot's data structures should be thread-safe.
@akien-mga @reduz It would be good to have someone familiar with Godot's C/C++ thread safety validates these changes as well.
There was a problem hiding this comment.
I think there should not be a problem calling setup2() on a different thread as setup(), if setup2() will later become the rendering thread. That said, eventually we need to look at some point at optionally supporting a dedicated rendering thread on Android, given this works on Godot already in the rest of the platforms.
There was a problem hiding this comment.
Ah nevermind, this will probably need to be changed and probably done again in setup2.
https://github.com/godotengine/godot/blob/master/main/main.cpp#L404
There was a problem hiding this comment.
Ah nevermind, this will probably need to be changed and probably done again in setup2.
https://github.com/godotengine/godot/blob/master/main/main.cpp#L404
This is already done in https://github.com/godotengine/godot/blob/master/platform/android/java_godot_lib_jni.cpp#L201.
There was a problem hiding this comment.
I think there should not be a problem calling setup2() on a different thread as setup(), if setup2() will later become the rendering thread. That said, eventually we need to look at some point at optionally supporting a dedicated rendering thread on Android, given this works on Godot already in the rest of the platforms.
@reduz The thread that setup2() is invoked on is the dedicated rendering thread. Or were you referring to something else?
There was a problem hiding this comment.
oh no, it's the main thread for Godot. On android there is no render thread support, so you should assume both render and main should be the same for now.
I'm sure it could eventually be done, but I would get everything to work first.
There was a problem hiding this comment.
I'd rename the interface to GodotRenderView or RenderView for short, since it's not typical to have the type as a suffix to the name.
There was a problem hiding this comment.
To be consistent with Android naming pattern, can this instead be GodotGLView or GodotGLRenderView to match the interface name.
There was a problem hiding this comment.
To be consistent, these should be onActivityPaused and onActivityResumed.
There was a problem hiding this comment.
To be consistent with Android naming pattern, can this be renamed to GodotVulkanView or GodotVulkanRenderView to match the interface name.
There was a problem hiding this comment.
I'd merge these with the GL* callbacks by renaming them to make them generic. For example, onRenderDrawFrame, onRenderSurfaceChanged, onRenderSurfaceCreated.
There was a problem hiding this comment.
Do you mean that the common functions would take both a Surface and a GL10 as arguments, and one of them would be null depending on the renderer used?
Or maybe we could simply pass a SurfaceView argument instead, but I don't have an example of these callbacks being used so I'm not sure what the actual use cases are.
There was a problem hiding this comment.
On second though let's keep them separate since passing null values seems like a hack as well.
Given that GLESv2 will remain, this might be useful for plugins that'd like to support one but not the other.
There are a couple other methods that use the onGL prefix that should be updated though:
onGLRegisterPluginWithGodotNativeonGLGodotMainLoopStarted
I'll provide a PR to update the naming for these since I'd like these changes to be in as soon as possible so as to be stable enough for plugin writers to start using them.
There was a problem hiding this comment.
You can use val here since the variable is final.
There was a problem hiding this comment.
The method name should be updated to be camelCase (surfaceCreated).
In the native layer, the logic for this method is almost identical to newcontext. The two should be merged into one.
There was a problem hiding this comment.
It's likely that more vulkan logic will be added inside and outside of this class. Can you restore the vulkan directory and keep all android platform vulkan specific logic (including this class) in there.
m4gr3d
left a comment
There was a problem hiding this comment.
@pouleyKetchoupp Nice job! I've added some feedback to be addressed.
15110dd to
1a80e20
Compare
|
Thanks @m4gr3d! I've just pushed some changes that should address your previous comments. So here are the remaining things to do before this PR can be merged:
|
1a80e20 to
69123f4
Compare
m4gr3d
left a comment
There was a problem hiding this comment.
Looks great!
One feedback to address, alongside your comment.
There was a problem hiding this comment.
newcontext must only be called once in onVkSurfaceCreated (see GodotRenderer for reference).
There was a problem hiding this comment.
Ah yes, good point! Right now, I'm not handling the surface re-creation properly, so the workaround is to reset the app by calling newcontext. Instead it should update the surface in the native code, but I haven't looked into that yet.
The consequence is the app gets restarted when paused and resumed again.
It's important to fix and I'll see if I have time for it in the coming days, but I don't think it's a blocker to merge this PR. In the meantime I'll add a comment in the code and in the PR description.
There was a problem hiding this comment.
Sounds good.
For the moment, you could then remove the call to newcontext from onVkSurfaceCreated since it's always followed by onVkSurfaceChanged and leave a comment like you mentioned to restore the proper logic flow when surface recreation is properly handled.
69123f4 to
644812f
Compare
| VkImageFormatListCreateInfoKHR format_list_create_info; | ||
| Vector<VkFormat> allowed_formats; | ||
|
|
||
| // TODO: vkCreateImage fails with format list on Android (VK_ERROR_OUT_OF_HOST_MEMORY) |
There was a problem hiding this comment.
I suppose we should be able to check for support via RenderingDevice. Can you add a #warning there ? I am sure many mobile GPUs support it and we should be able to take advantage of it.
There was a problem hiding this comment.
I think there should not be a problem calling setup2() on a different thread as setup(), if setup2() will later become the rendering thread. That said, eventually we need to look at some point at optionally supporting a dedicated rendering thread on Android, given this works on Godot already in the rest of the platforms.
There was a problem hiding this comment.
Android does support native video, you should be able to port it from 3.x branch
There was a problem hiding this comment.
@reduz The 3.x native video implementation is brittle, lack flexibility and possibly not working. The thinking for 4.0 (and 3.2.2) is to provide video support via the revamped Android plugin system instead.
There was a problem hiding this comment.
Ah nevermind, this will probably need to be changed and probably done again in setup2.
https://github.com/godotengine/godot/blob/master/main/main.cpp#L404
This is already done in https://github.com/godotengine/godot/blob/master/platform/android/java_godot_lib_jni.cpp#L201.
There was a problem hiding this comment.
I think there should not be a problem calling setup2() on a different thread as setup(), if setup2() will later become the rendering thread. That said, eventually we need to look at some point at optionally supporting a dedicated rendering thread on Android, given this works on Godot already in the rest of the platforms.
@reduz The thread that setup2() is invoked on is the dedicated rendering thread. Or were you referring to something else?
91891e2 to
2aa9849
Compare
|
Thanks for the review @reduz! I've just added the #warning you asked for. If everything's good around the display server code, this PR should be ready to merge. |
|
after trying to rebase android editor onto this branch, I found some small things that I think should be refactored... I can open a quick PR to this branch if you're interesed |
|
@thebestnom Ok, that makes sense. Thanks for the feedback! I can change it some time this week, but if you decide to do it in the meantime, please let me know and feel free to open a PR :) |
|
@pouleyKetchoupp working on it :) |
|
@pouleyKetchoupp hey, I commited everything but it doesn't let me open PR into https://github.com/nekomatata/godot/tree/android-vulkan-rendering |
|
@thebestnom It looks like you would have to actually fork from my repo to be able to do that :/ |
I'm not sure, I can open PR to different forks, I think the problem is that it's team only repo or somthing like that, but it doesn't matter that much... I wanted to make some comment on the code in the PR... so Ill just say it here, |
2aa9849 to
e167af3
Compare
|
Ok! I've seen the change with key events and it makes sense too. I've just pushed a new version that includes your changes. |
|
Some comments from IRC: Let's merge as is and refine in future PRs :) |
|
Thanks! |
|
Tested a local build, it's not finding |
It works after upgrading the NDK from |
@akien-mga @pouleyKetchoupp We can specify an NDK version in the |
|
@m4gr3d In order to be more flexible when GLES2 is supported again, we could detect the NDK version during the build, and when the requirement is not met, show a warning and disable Vulkan support. |
@pouleyKetchoupp that sounds overly complex and I'm not sure what the benefit would be done resolving the correct ndk version is a fairly simple task. |
|
can't you just use |
|
Can someone make a tracker issue for all the issues mentioned in first comment? |
|
@Anutrix Ok, I can make one. |
This change enables Vulkan rendering for Android, based on the SurfaceView implementation from PR #36603. There are still some issues to solve, but as a first step Android is now functional again on the 4.0 branch.
Only Vulkan rendering is supported for now, but I've kept the old GL implementation along with this changes, so it should be easy to enable GLES2 again when it's ready.
CC @RandomShaper @m4gr3d @akien-mga @reduz
Remaining issues:
Shaders currently fail because of descriptor set limits (tested on Galaxy Note 5):
Example with
TextureRect:Vulkan validation layers are not working (fails on
vkGetInstanceProcAddr)It's disabled on Android for now to avoid crashes.
Errors when using format list in
RenderingDeviceVulkan::texture_createvmaCreateImagefails withVK_IMAGE_CREATE_MUTABLE_FORMAT_BIT(returnsVK_ERROR_OUT_OF_HOST_MEMORY)It's disabled on Android for now to avoid crashes.
Errors in
RenderingDeviceVulkan::compute_pipeline_createvkCreateComputePipelinesreturnsVK_ERROR_INITIALIZATION_FAILEDin some casesMissing VR support
There's specific initialization for GL, based on
xrMode, it's not handled for Vulkan.Missing fallback to GLES2
Building templates with Android API 18 to 23
Vulkan support should be disabled in this case.
Properly handleonVkSurfaceChangedevent to update the rendering systemRight now, pausing and resuming the app causes it to restart completely instead.edit: addressed in Proper surface reset when resuming app on Android #39004
Implementation Notes:
New Android SDK requirements for building templates (Vulkan headers and libs):
NDK version: 20.0.5594570
Min Android API: 24
The Vulkan loader is taken from the Android NDK, because the one we're using for other platforms doesn't support Android platform.
[Android] wrong signatures for terminator_CreateAndroidSurfaceKHR() and vkCreateAndroidSurfaceKHR() KhronosGroup/Vulkan-Loader#96
VkRenderercalls GodotLib directly, so I got rid ofvk_renderer_jni. It seems easier to have one common place for calls from GL or Vulkan implementations.Fix for
GodotInstrumentationinAndroidManifest.xmlThis is used to force the app to restart.
I've kept the same hack that was used for GL to restart the whole app after paused, but we might want to improve it later by restarting only the rendering system.
Plugins:
Added vulkan specific callbacks in addition to the GL ones, but maybe the interface could be harmonized between the two to make it easier for the user.
Bugsquad edit: Fixes #36919.