From 194ed96e893e9af4e7916775aa04f03b7cb5e9ca 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. (cherry picked from commit d9eb6a5b206b0a2f67022b7bae32fb8e46badb95) --- drivers/gles3/rasterizer_scene_gles3.cpp | 6 +++--- drivers/gles3/rasterizer_scene_gles3.h | 13 +++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index bf765f8dadb..dcb87748d4f 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2693,7 +2693,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; @@ -2804,7 +2804,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; @@ -2893,7 +2893,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 4866ce6a6f8..a36ca43f95a 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -568,10 +568,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]; };