From d9eb6a5b206b0a2f67022b7bae32fb8e46badb95 Mon Sep 17 00:00:00 2001 From: marxin Date: Fri, 18 Jan 2019 22:58:42 +0100 Subject: [PATCH] Fix #19633 by proper store to &ubo_data.shadow_matrix[1234]. It is not valid in C++ to store into shadow_matrix1[16] with shadow_matrix1[16 * j] (for j > 0). Even though there's a valid space in a struct after shadow_matrix1. Knowing that GCC performs aggressive optimizations that eventually lead to a wrong code. Code has been changed into union where one can either use shadow_matrix[4 * 16], or individual shadow_matrix1, shadow_matrix2, etc. GCC pragma is not needed any longer. --- drivers/gles3/rasterizer_scene_gles3.cpp | 16 +++------------- drivers/gles3/rasterizer_scene_gles3.h | 13 +++++++++---- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index d53b27eb885..1fba8535d81 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2677,13 +2677,6 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr glBindBuffer(GL_UNIFORM_BUFFER, 0); } -// Drop -O3 for this function as it triggers a GCC bug up until at least GCC 8.2.1. -// This refers to GH issue #19633. -// The bug has been reported to the GCC project. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC push_options -#pragma GCC optimize("-O2") -#endif void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform &p_camera_inverse_transform, bool p_use_shadows) { LightInstance *li = directional_lights[p_index]; @@ -2784,7 +2777,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform CameraMatrix shadow_mtx = rectm * bias * li->shadow_transform[j].camera * modelview; - store_camera(shadow_mtx, &ubo_data.shadow_matrix1[16 * j]); + store_camera(shadow_mtx, &ubo_data.shadow.matrix[16 * j]); ubo_data.light_clamp[0] = atlas_rect.position.x; ubo_data.light_clamp[1] = atlas_rect.position.y; @@ -2801,9 +2794,6 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.directional_ubo); } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC pop_options -#endif void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix &p_camera_projection, RID p_shadow_atlas) { @@ -2898,7 +2888,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c Transform proj = (p_camera_inverse_transform * li->transform).inverse(); - store_transform(proj, ubo_data.shadow_matrix1); + store_transform(proj, ubo_data.shadow.matrix1); ubo_data.light_params[3] = 1.0; //means it has shadow ubo_data.light_clamp[0] = float(x) / atlas_size; @@ -2987,7 +2977,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c CameraMatrix shadow_mtx = rectm * bias * li->shadow_transform[0].camera * modelview; - store_camera(shadow_mtx, ubo_data.shadow_matrix1); + store_camera(shadow_mtx, ubo_data.shadow.matrix1); } li->light_index = state.spot_light_count; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 9772b5dd23c..325617745a3 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -569,10 +569,15 @@ public: float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled float light_clamp[4]; float light_shadow_color_contact[4]; - float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional - float shadow_matrix2[16]; - float shadow_matrix3[16]; - float shadow_matrix4[16]; + union { + struct { + float matrix1[16]; //up to here for spot and omni, rest is for directional + float matrix2[16]; + float matrix3[16]; + float matrix4[16]; + }; + float matrix[4 * 16]; + } shadow; float shadow_split_offsets[4]; };