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 d9eb6a5b20)
This commit is contained in:
marxin 2019-01-18 22:58:42 +01:00 committed by Rémi Verschelde
parent 740e77f47f
commit 194ed96e89
2 changed files with 12 additions and 7 deletions

View file

@ -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;

View file

@ -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];
};