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

GLES3 not working on android emulator + workaround #74828

Closed
ChibiDenDen opened this issue Mar 12, 2023 · 5 comments · Fixed by #74945
Closed

GLES3 not working on android emulator + workaround #74828

ChibiDenDen opened this issue Mar 12, 2023 · 5 comments · Fixed by #74945

Comments

@ChibiDenDen
Copy link
Contributor

Godot version

9b9bb41

System information

Android12 emulator, GLES3

Issue description

Using Godot 4 on an Android emulator with the GLES3 renderer results in a black screen and no crash / erros.

I managed to resolve the issue with the following change:

--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -1599,9 +1599,9 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
 
        Config *config = Config::get_singleton();
 
-       rt->color_internal_format = rt->is_transparent ? GL_RGBA8 : GL_RGB10_A2;
+       rt->color_internal_format = rt->is_transparent ? GL_RGBA8 : GL_RGBA8;
        rt->color_format = GL_RGBA;
-       rt->color_type = rt->is_transparent ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT_2_10_10_10_REV;
+       rt->color_type = rt->is_transparent ? GL_UNSIGNED_BYTE : GL_UNSIGNED_BYTE;
        rt->image_format = Image::FORMAT_RGBA8;

Which effectively disables the RGB10_A2 internal format for render targets and uses RGBA8 instead.
These 2 format changes fix rendering on my android emulator.

Im not sure what RGB10_A2 is used for (HDR?), but my workaround does not seem like the best solution.

Perhaps someone who knows a little bit more about the code here could suggest a different solution.

Steps to reproduce

Run any godot project on android emulator using GLES3 renderer.

Might be relevant:
my host machine is an M1 macbook pro

Minimal reproduction project

N/A

@clayjohn
Copy link
Member

It sounds like your emulator doesn't fully support OpenGL ES 3.0. Being able to render to a GL_RGB10_A2 render target is a core requirement for a device to claim OpenGL ES 3.0 support.

@ChibiDenDen
Copy link
Contributor Author

I absolutely agree, but I was wondering if I'm missing something else and the format is not really the issue...

I looked for a way to check if a format is supported but like you said, it is assumed to work on all gles3 devices.
The framebuffer is even claimed to be complete and no command results in any glError in this method..

Some questions that come to mind:
Is there anything else you think that might cause this issue?
Does changing the format has any other effect?
Why is 10_A2 used here? Is it for HDR?

For reference, I'm using the standard emulator in Android studio.

@clayjohn
Copy link
Member

clayjohn commented Mar 13, 2023

Is there anything else you think that might cause this issue?
Does changing the format has any other effect?

I can't think of anything else that would be responsible that would also go away when switching to an RGBA8 buffer.

Why is 10_A2 used here? Is it for HDR?

It's used to reduce banding in 3D. 8bits is really low precision for 3D rendering. Using 10 bits helps a lot

@ChibiDenDen
Copy link
Contributor Author

I played with it a bit more and found out another way to "solve" the issue without disabling RGB10_A2:

in rasterizer_gles3.cpp :: _blit_render_target_to_screen

+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -305,7 +305,9 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
                glBindFramebuffer(GL_READ_FRAMEBUFFER, read_fbo);
                glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, p_layer);
        } else {
-               glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
+    glGenFramebuffers(1, &read_fbo);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, read_fbo);
+    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color,  0);
        }

this basically creates a temporary fbo with only the color attachment right before blitting to the screen (similar to what happens in XR with view_count > 1)

I have no idea why this works and the regular fbo does not, the only difference between them is that rt->fbo has a depth buffer attached as well.

Any ideas?

ChibiDenDen added a commit to ChibiDenDen/godot that referenced this issue Apr 29, 2023
Use a temporary framebuffer for screen copy from rendertarget to screen.

This solves GLES3 rendering in android studio emulator (before this change there is just a black screen)

Based on discussion in:
godotengine#74828
@akien-mga akien-mga added this to the 4.1 milestone May 8, 2023
akien-mga pushed a commit to akien-mga/godot that referenced this issue May 12, 2023
Use a temporary framebuffer for screen copy from rendertarget to screen.

This solves GLES3 rendering in android studio emulator (before this change there is just a black screen)

Based on discussion in:
godotengine#74828

(cherry picked from commit 5956aa1)
@akien-mga
Copy link
Member

Fixed by #74945.

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

Successfully merging a pull request may close this issue.

4 participants