From 0e04203293bd817c01f50fad958de460e571b87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sat, 11 Nov 2023 15:13:23 +0100 Subject: [PATCH] GLES3: Ensure all ShaderData is properly initialized in set_code Fixes #84418. --- drivers/gles3/storage/material_storage.cpp | 84 ++++++++++++++-------- drivers/gles3/storage/material_storage.h | 44 +++++++----- 2 files changed, 80 insertions(+), 48 deletions(-) diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index a0dc5f7656d2..b7a42141fd31 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -2530,23 +2530,25 @@ LocalVector get_texture_uniform_data(const Vect /* Canvas Shader Data */ void CanvasShaderData::set_code(const String &p_code) { - // compile the shader + // Initialize and compile the shader. code = p_code; valid = false; ubo_size = 0; uniforms.clear(); + uses_screen_texture = false; uses_screen_texture_mipmaps = false; uses_sdf = false; uses_time = false; if (code.is_empty()) { - return; //just invalid, but no error + return; // Just invalid, but no error. } ShaderCompiler::GeneratedCode gen_code; + // Actual enum set further down after compilation. int blend_modei = BLEND_MODE_MIX; ShaderCompiler::IdentifierActions actions; @@ -2573,8 +2575,8 @@ void CanvasShaderData::set_code(const String &p_code) { } blend_mode = BlendMode(blend_modei); - uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; uses_screen_texture = gen_code.uses_screen_texture; + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; #if 0 print_line("**compiling shader:"); @@ -2687,27 +2689,28 @@ GLES3::MaterialData *GLES3::_create_canvas_material_func(ShaderData *p_shader) { // SKY SHADER void SkyShaderData::set_code(const String &p_code) { - //compile + // Initialize and compile the shader. code = p_code; valid = false; ubo_size = 0; uniforms.clear(); + uses_time = false; + uses_position = false; + uses_half_res = false; + uses_quarter_res = false; + uses_light = false; + if (code.is_empty()) { - return; //just invalid, but no error + return; // Just invalid, but no error. } ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT; - uses_time = false; - uses_half_res = false; - uses_quarter_res = false; - uses_position = false; - uses_light = false; - actions.render_mode_flags["use_half_res_pass"] = &uses_half_res; actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res; @@ -2828,25 +2831,13 @@ void SkyMaterialData::bind_uniforms() { // Scene SHADER void SceneShaderData::set_code(const String &p_code) { - //compile + // Initialize and compile the shader. code = p_code; valid = false; ubo_size = 0; uniforms.clear(); - if (code.is_empty()) { - return; //just invalid, but no error - } - - ShaderCompiler::GeneratedCode gen_code; - - int blend_modei = BLEND_MODE_MIX; - int depth_testi = DEPTH_TEST_ENABLED; - int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF; - int cull_modei = CULL_BACK; - int depth_drawi = DEPTH_DRAW_OPAQUE; - uses_point_size = false; uses_alpha = false; uses_alpha_clip = false; @@ -2855,6 +2846,7 @@ void SceneShaderData::set_code(const String &p_code) { uses_discard = false; uses_roughness = false; uses_normal = false; + uses_particle_trails = false; wireframe = false; unshaded = false; @@ -2863,12 +2855,37 @@ void SceneShaderData::set_code(const String &p_code) { uses_sss = false; uses_transmittance = false; uses_screen_texture = false; + uses_screen_texture_mipmaps = false; uses_depth_texture = false; uses_normal_texture = false; uses_time = false; + uses_vertex_time = false; + uses_fragment_time = false; writes_modelview_or_projection = false; uses_world_coordinates = false; - uses_particle_trails = false; + uses_tangent = false; + uses_color = false; + uses_uv = false; + uses_uv2 = false; + uses_custom0 = false; + uses_custom1 = false; + uses_custom2 = false; + uses_custom3 = false; + uses_bones = false; + uses_weights = false; + + if (code.is_empty()) { + return; // Just invalid, but no error. + } + + ShaderCompiler::GeneratedCode gen_code; + + // Actual enums set further down after compilation. + int blend_modei = BLEND_MODE_MIX; + int depth_testi = DEPTH_TEST_ENABLED; + int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF; + int cull_modei = CULL_BACK; + int depth_drawi = DEPTH_DRAW_OPAQUE; ShaderCompiler::IdentifierActions actions; actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX; @@ -2945,11 +2962,12 @@ void SceneShaderData::set_code(const String &p_code) { version = MaterialStorage::get_singleton()->shaders.scene_shader.version_create(); } + blend_mode = BlendMode(blend_modei); + alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei); depth_draw = DepthDraw(depth_drawi); depth_test = DepthTest(depth_testi); cull_mode = Cull(cull_modei); - blend_mode = BlendMode(blend_modei); - alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei); + vertex_input_mask = uint64_t(uses_normal); vertex_input_mask |= uses_tangent << 1; vertex_input_mask |= uses_color << 2; @@ -2961,8 +2979,9 @@ void SceneShaderData::set_code(const String &p_code) { vertex_input_mask |= uses_custom3 << 8; vertex_input_mask |= uses_bones << 9; vertex_input_mask |= uses_weights << 10; - uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; + uses_screen_texture = gen_code.uses_screen_texture; + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; uses_depth_texture = gen_code.uses_depth_texture; uses_normal_texture = gen_code.uses_normal_roughness_texture; uses_vertex_time = gen_code.uses_vertex_time; @@ -3017,7 +3036,7 @@ void SceneShaderData::set_code(const String &p_code) { ubo_offsets = gen_code.uniform_offsets; texture_uniforms = gen_code.texture_uniforms; - // if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage + // If any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage. if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) { blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE; } @@ -3093,19 +3112,22 @@ void SceneMaterialData::bind_uniforms() { /* Particles SHADER */ void ParticlesShaderData::set_code(const String &p_code) { - //compile + // Initialize and compile the shader. code = p_code; valid = false; ubo_size = 0; uniforms.clear(); + uses_collision = false; + uses_time = false; if (code.is_empty()) { - return; //just invalid, but no error + return; // Just invalid, but no error. } ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; actions.entry_point_stages["start"] = ShaderCompiler::STAGE_VERTEX; actions.entry_point_stages["process"] = ShaderCompiler::STAGE_VERTEX; diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 75127bb19813..3c5080c6e1b2 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -139,7 +139,7 @@ struct Material { /* CanvasItem Materials */ struct CanvasShaderData : public ShaderData { - enum BlendMode { //used internally + enum BlendMode { // Used internally. BLEND_MODE_MIX, BLEND_MODE_ADD, BLEND_MODE_SUB, @@ -149,9 +149,11 @@ struct CanvasShaderData : public ShaderData { BLEND_MODE_LCD, }; + // All these members are (re)initialized in `set_code`. + // Make sure to add the init to `set_code` whenever adding new members. + bool valid; RID version; - BlendMode blend_mode = BLEND_MODE_MIX; Vector texture_uniforms; @@ -160,10 +162,12 @@ struct CanvasShaderData : public ShaderData { String code; - bool uses_screen_texture = false; - bool uses_screen_texture_mipmaps = false; - bool uses_sdf = false; - bool uses_time = false; + BlendMode blend_mode; + + bool uses_screen_texture; + bool uses_screen_texture_mipmaps; + bool uses_sdf; + bool uses_time; virtual void set_code(const String &p_Code); virtual bool is_animated() const; @@ -191,6 +195,9 @@ MaterialData *_create_canvas_material_func(ShaderData *p_shader); /* Sky Materials */ struct SkyShaderData : public ShaderData { + // All these members are (re)initialized in `set_code`. + // Make sure to add the init to `set_code` whenever adding new members. + bool valid; RID version; @@ -233,7 +240,7 @@ MaterialData *_create_sky_material_func(ShaderData *p_shader); /* Scene Materials */ struct SceneShaderData : public ShaderData { - enum BlendMode { //used internally + enum BlendMode { // Used internally. BLEND_MODE_MIX, BLEND_MODE_ADD, BLEND_MODE_SUB, @@ -264,6 +271,9 @@ struct SceneShaderData : public ShaderData { ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE }; + // All these members are (re)initialized in `set_code`. + // Make sure to add the init to `set_code` whenever adding new members. + bool valid; RID version; @@ -282,8 +292,8 @@ struct SceneShaderData : public ShaderData { bool uses_point_size; bool uses_alpha; - bool uses_blend_alpha; bool uses_alpha_clip; + bool uses_blend_alpha; bool uses_depth_prepass_alpha; bool uses_discard; bool uses_roughness; @@ -316,10 +326,7 @@ struct SceneShaderData : public ShaderData { bool uses_bones; bool uses_weights; - uint64_t vertex_input_mask = 0; - - uint64_t last_pass = 0; - uint32_t index = 0; + uint64_t vertex_input_mask; virtual void set_code(const String &p_Code); virtual bool is_animated() const; @@ -354,21 +361,24 @@ enum { }; struct ParticlesShaderData : public ShaderData { - bool valid = false; + // All these members are (re)initialized in `set_code`. + // Make sure to add the init to `set_code` whenever adding new members. + + bool valid; RID version; - bool uses_collision = false; Vector texture_uniforms; Vector ubo_offsets; - uint32_t ubo_size = 0; + uint32_t ubo_size; String code; - bool uses_time = false; + bool uses_collision; + bool uses_time; bool userdatas_used[PARTICLES_MAX_USERDATAS] = {}; - uint32_t userdata_count = 0; + uint32_t userdata_count; virtual void set_code(const String &p_Code); virtual bool is_animated() const;