aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner <yuriks@yuriks.net>2015-08-05 23:22:06 -0300
committerGravatar Yuri Kunde Schlesner <yuriks@yuriks.net>2015-08-06 00:59:37 -0300
commit254582aa35306c7bdebb90b0cd2dda88fe188087 (patch)
tree35cd21873666116fba7a3fac3df1580e8d59b79a
parentff68db61bc737327ae122586bedcaf2ce21619ea (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.
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp32
-rw-r--r--src/video_core/renderer_opengl/gl_state.h6
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 dc3ffdf2..70f0ba5f 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 6f9dc012..82173d59 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 7ccf474e..87132401 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 03b7e26f..3e237902 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;
};