diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 51884ac70ff..de5d91d67e4 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -789,7 +789,7 @@ void TextureStorage::texture_free(RID p_texture) { texture_atlas_remove_texture(p_texture); - for (int i = 0; i < t->proxies.size(); i++) { + for (uint32_t i = 0; i < t->proxies.size(); i++) { Texture *p = texture_owner.get_or_null(t->proxies[i]); ERR_CONTINUE(!p); p->proxy_to = RID(); @@ -1064,6 +1064,27 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { proxy_to->proxies.push_back(p_texture); } +void TextureStorage::texture_remap_proxies(RID p_from_texture, RID p_to_texture) { + Texture *from_tex = texture_owner.get_or_null(p_from_texture); + ERR_FAIL_NULL(from_tex); + ERR_FAIL_COND(from_tex->is_proxy); + Texture *to_tex = texture_owner.get_or_null(p_to_texture); + ERR_FAIL_NULL(to_tex); + ERR_FAIL_COND(to_tex->is_proxy); + + if (from_tex == to_tex) { + return; + } + + // Make a local copy, we're about to change the content of the original. + thread_local LocalVector proxies = from_tex->proxies; + + // Now change them to our new texture. + for (RID &proxy : proxies) { + texture_proxy_update(proxy, p_to_texture); + } +} + void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) { texture_2d_initialize(p_texture, texture_2d_placeholder); } @@ -2553,6 +2574,9 @@ void TextureStorage::render_target_set_override(RID p_render_target, RID p_color ERR_FAIL_NULL(rt); ERR_FAIL_COND(rt->direct_to_screen); + // Remember what our current color output is. + RID was_color_texture = render_target_get_texture(p_render_target); + rt->overridden.velocity = p_velocity_texture; if (rt->overridden.color == p_color_texture && rt->overridden.depth == p_depth_texture) { @@ -2560,6 +2584,11 @@ void TextureStorage::render_target_set_override(RID p_render_target, RID p_color } if (p_color_texture.is_null() && p_depth_texture.is_null()) { + // Set this back to our default textures. + if (was_color_texture.is_valid()) { + texture_remap_proxies(was_color_texture, rt->texture); + } + _clear_render_target(rt); _update_render_target(rt); return; @@ -2574,6 +2603,12 @@ void TextureStorage::render_target_set_override(RID p_render_target, RID p_color rt->overridden.depth_has_stencil = p_depth_texture.is_null(); rt->overridden.is_overridden = true; + // Update to our new color output. + RID new_color_texture = render_target_get_texture(p_render_target); + if (was_color_texture.is_valid() && new_color_texture.is_valid()) { + texture_remap_proxies(was_color_texture, new_color_texture); + } + uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id()); hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key); hash_key = hash_fmix32(hash_key); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index ebe94e34adf..373f35e924b 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -151,7 +151,7 @@ struct Texture { bool is_render_target = false; RID proxy_to; - Vector proxies; + LocalVector proxies; String path; int width = 0; @@ -525,6 +525,7 @@ public: virtual void texture_3d_update(RID p_texture, const Vector> &p_data) override; virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override; virtual void texture_proxy_update(RID p_proxy, RID p_base) override; + void texture_remap_proxies(RID p_from_texture, RID p_to_texture); Ref texture_2d_placeholder; Vector> texture_2d_array_placeholder;