From baf691acab4fd81164b001a44238d4679787643e Mon Sep 17 00:00:00 2001 From: clayjohn Date: Tue, 21 Jun 2022 12:59:06 -0700 Subject: [PATCH] Unbind used texture bindings when changing framebuffer --- drivers/gles3/rasterizer_canvas_gles3.cpp | 2 ++ drivers/gles3/rasterizer_gles3.cpp | 12 ++++++++++++ drivers/gles3/rasterizer_scene_gles3.cpp | 1 + drivers/gles3/rasterizer_storage_gles3.cpp | 1 + drivers/gles3/rasterizer_storage_gles3.h | 1 + 5 files changed, 17 insertions(+) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 4323d741260a..485eb75f55b6 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -182,6 +182,7 @@ void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemSta } int tc = material_ptr->textures.size(); + storage->frame.max_texture_binding = MAX(tc, storage->frame.max_texture_binding); RID *textures = material_ptr->textures.ptrw(); ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw(); @@ -1262,6 +1263,7 @@ void RasterizerCanvasGLES3::render_joined_item(const BItemJoined &p_bij, RenderI } int tc = material_ptr->textures.size(); + storage->frame.max_texture_binding = MAX(tc, storage->frame.max_texture_binding); RID *textures = material_ptr->textures.ptrw(); ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw(); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 1d34c085f768..f1d39afaa5f3 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -248,6 +248,18 @@ void RasterizerGLES3::set_current_render_target(RID p_render_target) { glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height); glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); } + // Unbind user textures that have been set since the last render target change. + // Unbind the internal slots that may have been used by Godot. + for (int i = 1; i <= 13; i++) { + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - i); + glBindTexture(GL_TEXTURE_2D, 0); + } + // Unbind from 0 up to the max texture slot used by the user. + for (int i = 0; i < storage->frame.max_texture_binding + 2; i++) { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + } + storage->frame.max_texture_binding = 0; } void RasterizerGLES3::restore_render_target(bool p_3d_was_drawn) { diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index ae8d71d91911..250938833f98 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1145,6 +1145,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m } int tc = p_material->textures.size(); + storage->frame.max_texture_binding = MAX(tc, storage->frame.max_texture_binding); RID *textures = p_material->textures.ptrw(); ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw(); const ShaderLanguage::DataType *texture_types = p_material->shader->texture_types.ptr(); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 8d36927f78f0..fa55bbff2591 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -8337,6 +8337,7 @@ void RasterizerStorageGLES3::initialize() { frame.count = 0; frame.delta = 0; frame.current_rt = nullptr; + frame.max_texture_binding = 0; config.keep_original_textures = false; config.generate_wireframes = false; config.use_texture_array_environment = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections"); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index a1c5e4774ae4..02fa5edc3666 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -1491,6 +1491,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage { float time[4]; float delta; uint64_t count; + int max_texture_binding; } frame;