diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 9a46daf2c7..c606cd0602 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -336,6 +336,7 @@ namespace gl temp_image_cache.clear(); resources.clear(); font_cache.clear(); + view_cache.clear(); overlay_pass::destroy(); } diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index 040fb718c5..3813a856d6 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -123,6 +123,13 @@ namespace gl m_format_class = format_class; } + texture::~texture() + { + gl::get_command_context()->unbind_texture(static_cast(m_target), m_id); + glDeleteTextures(1, &m_id); + m_id = GL_NONE; + } + void texture::copy_from(const void* src, texture::format format, texture::type type, int level, const coord3u region, const pixel_unpack_settings& pixel_settings) { pixel_settings.apply(); @@ -260,6 +267,13 @@ namespace gl } } + texture_view::~texture_view() + { + gl::get_command_context()->unbind_texture(static_cast(m_target), m_id); + glDeleteTextures(1, &m_id); + m_id = GL_NONE; + } + void texture_view::bind(gl::command_context& cmd, GLuint layer) const { cmd->bind_texture(layer, m_target, m_id); diff --git a/rpcs3/Emu/RSX/GL/glutils/image.h b/rpcs3/Emu/RSX/GL/glutils/image.h index 63dff29506..063fa7b55e 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.h +++ b/rpcs3/Emu/RSX/GL/glutils/image.h @@ -159,12 +159,7 @@ namespace gl texture(texture&& texture_) = delete; texture(GLenum target, GLuint width, GLuint height, GLuint depth, GLuint mipmaps, GLenum sized_format, rsx::format_class format_class = rsx::RSX_FORMAT_CLASS_UNDEFINED); - - virtual ~texture() - { - glDeleteTextures(1, &m_id); - m_id = GL_NONE; - } + virtual ~texture(); // Getters/setters void set_native_component_layout(const std::array& layout) @@ -324,11 +319,7 @@ namespace gl create(data, target, sized_format, aspect_flags, argb_swizzle); } - virtual ~texture_view() - { - glDeleteTextures(1, &m_id); - m_id = GL_NONE; - } + virtual ~texture_view(); GLuint id() const { diff --git a/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp b/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp index 6f2c584d24..836d5b7b8d 100644 --- a/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp +++ b/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp @@ -300,6 +300,28 @@ namespace gl bound = name; } } + + void unbind_texture(GLenum target, GLuint name) + { + // To be called with glDeleteTextures. + // OpenGL internally unbinds the texture on delete, but then reuses the same ID when GenTextures is called again! + // This can also be avoided using unique internal names, such as 64-bit handles, but that involves changing a lot of code for little benefit + for (auto& layer : bound_textures) + { + if (layer.empty()) + { + continue; + } + + if (auto found = layer.find(target); + found != layer.end() && found->second == name) + { + // Actually still bound! + found->second = GL_NONE; + return; + } + } + } }; class command_context