From 41fc0abf771b98b917109e890836213395f17c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Tue, 12 Apr 2022 20:08:09 +0200 Subject: [PATCH] Fix handling of async hidden render mode - Mute errors when conditioned shader is not ready yet - Avoid depth pre-pass on meshes that would end up black --- drivers/gles3/rasterizer_scene_gles3.cpp | 11 ++++++++++ drivers/gles3/shader_gles3.cpp | 28 ++++++++++++++++++++++++ drivers/gles3/shader_gles3.h | 1 + 3 files changed, 40 insertions(+) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index cbaaa440708..cbb3a3f132b 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1136,6 +1136,9 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m state.scene_shader.set_custom_shader(p_material->shader->custom_code_id); bool rebind = state.scene_shader.bind(); + if (!ShaderGLES3::get_active()) { + return false; + } if (p_material->ubo_id) { glBindBufferBase(GL_UNIFORM_BUFFER, 1, p_material->ubo_id); @@ -2173,6 +2176,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ storage->info.render.shader_rebind_count++; } } + if (!ShaderGLES3::get_active()) { + continue; + } if (!(e->sort_key & SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) { _setup_light(e, p_view_transform); @@ -2319,6 +2325,11 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || ((has_base_alpha || p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_OFF) && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test) { return; //bye } + if (!p_material->shader->shader->is_custom_code_ready_for_render(p_material->shader->custom_code_id)) { + // The shader is not guaranteed to be able to render (i.e., a not yet ready async hidden one); + // skip depth rendering because otherwise we risk masking out pixels that won't get written to at the actual render pass + return; + } if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { //shader does not use discard and does not write a vertex position, use generic material diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 32c52bf8e2d..aa07e0e6454 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -148,6 +148,34 @@ bool ShaderGLES3::_bind(bool p_binding_fallback) { } } +bool ShaderGLES3::is_custom_code_ready_for_render(uint32_t p_code_id) { + if (p_code_id == 0) { + return true; + } + if (!is_async_compilation_supported() || get_ubershader_flags_uniform() == -1) { + return true; + } + + CustomCode *cc = custom_code_map.getptr(p_code_id); + ERR_FAIL_COND_V(!cc, false); + if (cc->async_mode == ASYNC_MODE_HIDDEN) { +#ifdef DEBUG_ENABLED + if (VS::get_singleton()->is_force_shader_fallbacks_enabled()) { + return false; + } +#endif + VersionKey effective_version; + effective_version.version = new_conditional_version.version; + effective_version.code_version = p_code_id; + Version *v = version_map.getptr(effective_version); + if (!v || cc->version != v->code_version || v->compile_status != Version::COMPILE_STATUS_OK) { + return false; + } + } + + return true; +} + bool ShaderGLES3::_bind_ubershader() { #ifdef DEBUG_ENABLED ERR_FAIL_COND_V(!is_async_compilation_supported(), false); diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 74d47f2adba..6b77b4ce488 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -397,6 +397,7 @@ public: void set_custom_shader_code(uint32_t p_code_id, const String &p_vertex, const String &p_vertex_globals, const String &p_fragment, const String &p_light, const String &p_fragment_globals, const String &p_uniforms, const Vector &p_texture_uniforms, const Vector &p_custom_defines, AsyncMode p_async_mode); void set_custom_shader(uint32_t p_code_id); void free_custom_shader(uint32_t p_code_id); + bool is_custom_code_ready_for_render(uint32_t p_code_id); uint32_t get_version() const { return new_conditional_version.version; } bool is_version_ubershader() const { return (new_conditional_version.version & VersionKey::UBERSHADER_FLAG); }