summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Hartmann <alex.hart.278@gmail.com>2024-01-19 00:07:28 +0100
committerAlexander Hartmann <alex.hart.278@gmail.com>2024-02-22 00:24:08 +0100
commite17cecf54a4e98ede77e87a08d33742463bddca5 (patch)
tree4097e76f2b4d4a3f6e0c645d218cfb04c436cd6c /drivers
parent16d61427cab3a8e43f0a9a8ee724fc176b6433c6 (diff)
downloadredot-engine-e17cecf54a4e98ede77e87a08d33742463bddca5.tar.gz
Fix Compatibility Rendering (GLES3) on old and low budget devices.
Co-Authored-By: joined72 <19651914+joined72@users.noreply.github.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp17
-rw-r--r--drivers/gles3/rasterizer_gles3.h1
-rw-r--r--drivers/gles3/shaders/canvas.glsl43
-rw-r--r--drivers/gles3/shaders/scene.glsl5
-rw-r--r--drivers/gles3/storage/config.cpp5
-rw-r--r--drivers/gles3/storage/config.h2
6 files changed, 59 insertions, 14 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 14ef0f40cf..da2320c23d 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -194,6 +194,11 @@ typedef void(GLAPIENTRY *DebugMessageCallbackARB)(DEBUGPROCARB callback, const v
void RasterizerGLES3::initialize() {
Engine::get_singleton()->print_header(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name()));
+
+ // FLIP XY Bug: Are more devices affected?
+ // Confirmed so far: all Adreno 3xx
+ // ok on some tested Adreno devices: 4xx, 5xx and 6xx
+ flip_xy_bugfix = GLES3::Config::get_singleton()->adreno_3xx_compatibility;
}
void RasterizerGLES3::finalize() {
@@ -398,8 +403,18 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
}
Vector2i screen_rect_end = p_screen_rect.get_end();
+
+ // Adreno (TM) 3xx devices have a bug that create wrong Landscape rotation of 180 degree
+ // Reversing both the X and Y axis is equivalent to rotating 180 degrees
+ bool flip_x = false;
+ if (flip_xy_bugfix && screen_rect_end.x > screen_rect_end.y) {
+ flip_y = !flip_y;
+ flip_x = !flip_x;
+ }
+
glBlitFramebuffer(0, 0, rt->size.x, rt->size.y,
- p_screen_rect.position.x, flip_y ? screen_rect_end.y : p_screen_rect.position.y, screen_rect_end.x, flip_y ? p_screen_rect.position.y : screen_rect_end.y,
+ flip_x ? screen_rect_end.x : p_screen_rect.position.x, flip_y ? screen_rect_end.y : p_screen_rect.position.y,
+ flip_x ? p_screen_rect.position.x : screen_rect_end.x, flip_y ? p_screen_rect.position.y : screen_rect_end.y,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
if (read_fbo != 0) {
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index fc1315035b..8d52dc2365 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -55,6 +55,7 @@ private:
float delta = 0;
double time_total = 0.0;
+ bool flip_xy_bugfix = false;
static bool gles_over_gl;
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 80e28cf9fc..8da7d7dc80 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -187,8 +187,31 @@ void main() {
#endif // !USE_INSTANCING
#else // !USE_ATTRIBUTES
- vec2 vertex_base_arr[6] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(1.0, 1.0));
- vec2 vertex_base = vertex_base_arr[gl_VertexID % 6];
+
+ // crash on Adreno 320/330
+ //vec2 vertex_base_arr[6] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(1.0, 1.0));
+ //vec2 vertex_base = vertex_base_arr[gl_VertexID % 6];
+ //-----------------------------------------
+ // ID | 0 | 1 | 2 | 3 | 4 | 5 |
+ //-----------------------------------------
+ // X | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 1.0 |
+ // Y | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 |
+ //-----------------------------------------
+ // no crash or freeze on all Adreno 3xx with 'if / else if' and slightly faster!
+ int vertex_id = gl_VertexID % 6;
+ vec2 vertex_base;
+ if (vertex_id == 0)
+ vertex_base = vec2(0.0, 0.0);
+ else if (vertex_id == 1)
+ vertex_base = vec2(0.0, 1.0);
+ else if (vertex_id == 2)
+ vertex_base = vec2(1.0, 1.0);
+ else if (vertex_id == 3)
+ vertex_base = vec2(1.0, 0.0);
+ else if (vertex_id == 4)
+ vertex_base = vec2(0.0, 0.0);
+ else if (vertex_id == 5)
+ vertex_base = vec2(1.0, 1.0);
vec2 uv = read_draw_data_src_rect.xy + abs(read_draw_data_src_rect.zw) * ((read_draw_data_flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy);
vec4 color = read_draw_data_modulation;
@@ -475,16 +498,12 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv
void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) {
uint blend_mode = light_array[light_base].flags & LIGHT_FLAGS_BLEND_MASK;
- switch (blend_mode) {
- case LIGHT_FLAGS_BLEND_MODE_ADD: {
- color.rgb += light_color.rgb * light_color.a;
- } break;
- case LIGHT_FLAGS_BLEND_MODE_SUB: {
- color.rgb -= light_color.rgb * light_color.a;
- } break;
- case LIGHT_FLAGS_BLEND_MODE_MIX: {
- color.rgb = mix(color.rgb, light_color.rgb, light_color.a);
- } break;
+ if (blend_mode == LIGHT_FLAGS_BLEND_MODE_ADD) {
+ color.rgb += light_color.rgb * light_color.a;
+ } else if (blend_mode == LIGHT_FLAGS_BLEND_MODE_SUB) {
+ color.rgb -= light_color.rgb * light_color.a;
+ } else if (blend_mode == LIGHT_FLAGS_BLEND_MODE_MIX) {
+ color.rgb = mix(color.rgb, light_color.rgb, light_color.a);
}
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 27c292d163..a6db90c3f5 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1200,7 +1200,10 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f
vec3 spot_dir = spot_lights[idx].direction;
float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle);
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle));
- spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation);
+
+ mediump float cone_attenuation = spot_lights[idx].cone_attenuation;
+ spot_attenuation *= 1.0 - pow(spot_rim, cone_attenuation);
+
vec3 color = spot_lights[idx].color;
float size_A = 0.0;
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index 5d01ab0346..1a41b60836 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -166,6 +166,11 @@ Config::Config() {
max_renderable_elements = GLOBAL_GET("rendering/limits/opengl/max_renderable_elements");
max_renderable_lights = GLOBAL_GET("rendering/limits/opengl/max_renderable_lights");
max_lights_per_object = GLOBAL_GET("rendering/limits/opengl/max_lights_per_object");
+
+ //Adreno 3xx Compatibility
+ const String rendering_device_name = String::utf8((const char *)glGetString(GL_RENDERER));
+ //TODO: Check the number between 300 and 399(?)
+ adreno_3xx_compatibility = (rendering_device_name.left(13) == "Adreno (TM) 3");
}
Config::~Config() {
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index 1c0a5178bd..c3ab65f0bc 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -91,6 +91,8 @@ public:
bool rt_msaa_multiview_supported = false;
bool multiview_supported = false;
+ bool adreno_3xx_compatibility = false;
+
#ifdef ANDROID_ENABLED
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC eglFramebufferTextureMultiviewOVR = nullptr;
PFNGLTEXSTORAGE3DMULTISAMPLEPROC eglTexStorage3DMultisample = nullptr;