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.
This commit is contained in:
parent
7f9209781c
commit
d9eb6a5b20
2 changed files with 12 additions and 17 deletions
|
@ -2677,13 +2677,6 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
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) {
|
void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform &p_camera_inverse_transform, bool p_use_shadows) {
|
||||||
|
|
||||||
LightInstance *li = directional_lights[p_index];
|
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;
|
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[0] = atlas_rect.position.x;
|
||||||
ubo_data.light_clamp[1] = atlas_rect.position.y;
|
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);
|
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) {
|
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();
|
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_params[3] = 1.0; //means it has shadow
|
||||||
ubo_data.light_clamp[0] = float(x) / atlas_size;
|
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;
|
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;
|
li->light_index = state.spot_light_count;
|
||||||
|
|
|
@ -569,10 +569,15 @@ public:
|
||||||
float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
|
float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
|
||||||
float light_clamp[4];
|
float light_clamp[4];
|
||||||
float light_shadow_color_contact[4];
|
float light_shadow_color_contact[4];
|
||||||
float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional
|
union {
|
||||||
float shadow_matrix2[16];
|
struct {
|
||||||
float shadow_matrix3[16];
|
float matrix1[16]; //up to here for spot and omni, rest is for directional
|
||||||
float shadow_matrix4[16];
|
float matrix2[16];
|
||||||
|
float matrix3[16];
|
||||||
|
float matrix4[16];
|
||||||
|
};
|
||||||
|
float matrix[4 * 16];
|
||||||
|
} shadow;
|
||||||
float shadow_split_offsets[4];
|
float shadow_split_offsets[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue