From 254582aa35306c7bdebb90b0cd2dda88fe188087 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Wed, 5 Aug 2015 23:22:06 -0300 Subject: [PATCH] OpenGL: Fix state tracking in situations with reused object handles If an OpenGL object is created, bound to a binding using the state tracker, and then destroyed, a newly created object can be assigned the same numeric handle by OpenGL. However, even though it is a new object, and thus needs to be bound to the binding again, the state tracker compared the current and previous handles and concluded that no change needed to be made, leading to failure to bind objects in certain cases. This manifested as broken text in VVVVVV, which this commit fixes along with similar texturing problems in other games. --- .../renderer_opengl/gl_rasterizer_cache.cpp | 1 + .../renderer_opengl/gl_resource_manager.h | 6 ++++ src/video_core/renderer_opengl/gl_state.cpp | 32 +++++++++++++++++++ src/video_core/renderer_opengl/gl_state.h | 6 ++++ 4 files changed, 45 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index dc3ffdf228..70f0ba5f10 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -30,6 +30,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text new_texture->texture.Create(); state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.Apply(); + glActiveTexture(GL_TEXTURE0 + texture_unit); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter)); diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 6f9dc012d6..82173d59a6 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -10,6 +10,7 @@ #include "video_core/renderer_opengl/generated/gl_3_2_core.h" #include "video_core/renderer_opengl/gl_shader_util.h" +#include "video_core/renderer_opengl/gl_state.h" class OGLTexture : private NonCopyable { public: @@ -28,6 +29,7 @@ public: void Release() { if (handle == 0) return; glDeleteTextures(1, &handle); + OpenGLState::ResetTexture(handle); handle = 0; } @@ -51,6 +53,7 @@ public: void Release() { if (handle == 0) return; glDeleteProgram(handle); + OpenGLState::ResetProgram(handle); handle = 0; } @@ -74,6 +77,7 @@ public: void Release() { if (handle == 0) return; glDeleteBuffers(1, &handle); + OpenGLState::ResetBuffer(handle); handle = 0; } @@ -97,6 +101,7 @@ public: void Release() { if (handle == 0) return; glDeleteVertexArrays(1, &handle); + OpenGLState::ResetVertexArray(handle); handle = 0; } @@ -120,6 +125,7 @@ public: void Release() { if (handle == 0) return; glDeleteFramebuffers(1, &handle); + OpenGLState::ResetFramebuffer(handle); handle = 0; } diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 7ccf474e17..871324014f 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -174,3 +174,35 @@ void OpenGLState::Apply() { cur_state = *this; } + +void OpenGLState::ResetTexture(GLuint id) { + for (auto& unit : cur_state.texture_units) { + if (unit.texture_2d == id) { + unit.texture_2d = 0; + } + } +} + +void OpenGLState::ResetProgram(GLuint id) { + if (cur_state.draw.shader_program == id) { + cur_state.draw.shader_program = 0; + } +} + +void OpenGLState::ResetBuffer(GLuint id) { + if (cur_state.draw.vertex_buffer == id) { + cur_state.draw.vertex_buffer = 0; + } +} + +void OpenGLState::ResetVertexArray(GLuint id) { + if (cur_state.draw.vertex_array == id) { + cur_state.draw.vertex_array = 0; + } +} + +void OpenGLState::ResetFramebuffer(GLuint id) { + if (cur_state.draw.framebuffer == id) { + cur_state.draw.framebuffer = 0; + } +} diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 03b7e26f78..3e23790219 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -73,6 +73,12 @@ public: /// Apply this state as the current OpenGL state void Apply(); + static void ResetTexture(GLuint id); + static void ResetProgram(GLuint id); + static void ResetBuffer(GLuint id); + static void ResetVertexArray(GLuint id); + static void ResetFramebuffer(GLuint id); + private: static OpenGLState cur_state; };