diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-08-05 23:22:06 -0300 |
---|---|---|
committer | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-08-06 00:59:37 -0300 |
commit | 254582aa35306c7bdebb90b0cd2dda88fe188087 (patch) | |
tree | 35cd21873666116fba7a3fac3df1580e8d59b79a /src | |
parent | ff68db61bc737327ae122586bedcaf2ce21619ea (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 1 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.h | 6 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 32 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 6 |
4 files changed, 45 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index dc3ffdf22..70f0ba5f1 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 6f9dc012d..82173d59a 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 7ccf474e1..871324014 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 03b7e26f7..3e2379021 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; }; |