summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2015-08-11 17:19:45 -0400
committerGravatar bunnei2015-08-11 17:19:45 -0400
commit93f607f5497a5fee142a0d2010881444a4ff0c80 (patch)
tree3728be088656eed0f4d53fde0f4ca194d640bf82
parentMerge pull request #1028 from aroulin/arm-disas-media-instr (diff)
parentOpenGL: Fix state tracking in situations with reused object handles (diff)
downloadyuzu-93f607f5497a5fee142a0d2010881444a4ff0c80.tar.gz
yuzu-93f607f5497a5fee142a0d2010881444a4ff0c80.tar.xz
yuzu-93f607f5497a5fee142a0d2010881444a4ff0c80.zip
Merge pull request #1023 from yuriks/gl-state-bugs
OpenGL: Fix state tracking in situations with reused object handles
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp11
-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.cpp44
-rw-r--r--src/video_core/renderer_opengl/gl_state.h7
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp5
6 files changed, 48 insertions, 26 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 1fc4e56b1..e7c1cfeb7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -99,7 +99,6 @@ void RasterizerOpenGL::InitObjects() {
99 fb_color_texture.texture.Create(); 99 fb_color_texture.texture.Create();
100 ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1); 100 ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1);
101 101
102 state.texture_units[0].enabled_2d = true;
103 state.texture_units[0].texture_2d = fb_color_texture.texture.handle; 102 state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
104 state.Apply(); 103 state.Apply();
105 104
@@ -115,7 +114,6 @@ void RasterizerOpenGL::InitObjects() {
115 fb_depth_texture.texture.Create(); 114 fb_depth_texture.texture.Create();
116 ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1); 115 ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
117 116
118 state.texture_units[0].enabled_2d = true;
119 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; 117 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
120 state.Apply(); 118 state.Apply();
121 119
@@ -493,7 +491,6 @@ void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs:
493 break; 491 break;
494 } 492 }
495 493
496 state.texture_units[0].enabled_2d = true;
497 state.texture_units[0].texture_2d = texture.texture.handle; 494 state.texture_units[0].texture_2d = texture.texture.handle;
498 state.Apply(); 495 state.Apply();
499 496
@@ -537,7 +534,6 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
537 break; 534 break;
538 } 535 }
539 536
540 state.texture_units[0].enabled_2d = true;
541 state.texture_units[0].texture_2d = texture.texture.handle; 537 state.texture_units[0].texture_2d = texture.texture.handle;
542 state.Apply(); 538 state.Apply();
543 539
@@ -766,10 +762,9 @@ void RasterizerOpenGL::SyncDrawState() {
766 const auto& texture = pica_textures[texture_index]; 762 const auto& texture = pica_textures[texture_index];
767 763
768 if (texture.enabled) { 764 if (texture.enabled) {
769 state.texture_units[texture_index].enabled_2d = true;
770 res_cache.LoadAndBindTexture(state, texture_index, texture); 765 res_cache.LoadAndBindTexture(state, texture_index, texture);
771 } else { 766 } else {
772 state.texture_units[texture_index].enabled_2d = false; 767 state.texture_units[texture_index].texture_2d = 0;
773 } 768 }
774 } 769 }
775 770
@@ -804,7 +799,6 @@ void RasterizerOpenGL::ReloadColorBuffer() {
804 } 799 }
805 } 800 }
806 801
807 state.texture_units[0].enabled_2d = true;
808 state.texture_units[0].texture_2d = fb_color_texture.texture.handle; 802 state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
809 state.Apply(); 803 state.Apply();
810 804
@@ -862,7 +856,6 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
862 } 856 }
863 } 857 }
864 858
865 state.texture_units[0].enabled_2d = true;
866 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; 859 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
867 state.Apply(); 860 state.Apply();
868 861
@@ -887,7 +880,6 @@ void RasterizerOpenGL::CommitColorBuffer() {
887 880
888 std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]); 881 std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
889 882
890 state.texture_units[0].enabled_2d = true;
891 state.texture_units[0].texture_2d = fb_color_texture.texture.handle; 883 state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
892 state.Apply(); 884 state.Apply();
893 885
@@ -927,7 +919,6 @@ void RasterizerOpenGL::CommitDepthBuffer() {
927 919
928 std::unique_ptr<u8[]> temp_gl_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]); 920 std::unique_ptr<u8[]> temp_gl_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]);
929 921
930 state.texture_units[0].enabled_2d = true;
931 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; 922 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
932 state.Apply(); 923 state.Apply();
933 924
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
30 new_texture->texture.Create(); 30 new_texture->texture.Create();
31 state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; 31 state.texture_units[texture_unit].texture_2d = new_texture->texture.handle;
32 state.Apply(); 32 state.Apply();
33 glActiveTexture(GL_TEXTURE0 + texture_unit);
33 34
34 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter)); 35 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter));
35 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter)); 36 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 @@
10 10
11#include "video_core/renderer_opengl/generated/gl_3_2_core.h" 11#include "video_core/renderer_opengl/generated/gl_3_2_core.h"
12#include "video_core/renderer_opengl/gl_shader_util.h" 12#include "video_core/renderer_opengl/gl_shader_util.h"
13#include "video_core/renderer_opengl/gl_state.h"
13 14
14class OGLTexture : private NonCopyable { 15class OGLTexture : private NonCopyable {
15public: 16public:
@@ -28,6 +29,7 @@ public:
28 void Release() { 29 void Release() {
29 if (handle == 0) return; 30 if (handle == 0) return;
30 glDeleteTextures(1, &handle); 31 glDeleteTextures(1, &handle);
32 OpenGLState::ResetTexture(handle);
31 handle = 0; 33 handle = 0;
32 } 34 }
33 35
@@ -51,6 +53,7 @@ public:
51 void Release() { 53 void Release() {
52 if (handle == 0) return; 54 if (handle == 0) return;
53 glDeleteProgram(handle); 55 glDeleteProgram(handle);
56 OpenGLState::ResetProgram(handle);
54 handle = 0; 57 handle = 0;
55 } 58 }
56 59
@@ -74,6 +77,7 @@ public:
74 void Release() { 77 void Release() {
75 if (handle == 0) return; 78 if (handle == 0) return;
76 glDeleteBuffers(1, &handle); 79 glDeleteBuffers(1, &handle);
80 OpenGLState::ResetBuffer(handle);
77 handle = 0; 81 handle = 0;
78 } 82 }
79 83
@@ -97,6 +101,7 @@ public:
97 void Release() { 101 void Release() {
98 if (handle == 0) return; 102 if (handle == 0) return;
99 glDeleteVertexArrays(1, &handle); 103 glDeleteVertexArrays(1, &handle);
104 OpenGLState::ResetVertexArray(handle);
100 handle = 0; 105 handle = 0;
101 } 106 }
102 107
@@ -120,6 +125,7 @@ public:
120 void Release() { 125 void Release() {
121 if (handle == 0) return; 126 if (handle == 0) return;
122 glDeleteFramebuffers(1, &handle); 127 glDeleteFramebuffers(1, &handle);
128 OpenGLState::ResetFramebuffer(handle);
123 handle = 0; 129 handle = 0;
124 } 130 }
125 131
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 9efc15337..871324014 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -40,7 +40,6 @@ OpenGLState::OpenGLState() {
40 logic_op = GL_COPY; 40 logic_op = GL_COPY;
41 41
42 for (auto& texture_unit : texture_units) { 42 for (auto& texture_unit : texture_units) {
43 texture_unit.enabled_2d = false;
44 texture_unit.texture_2d = 0; 43 texture_unit.texture_2d = 0;
45 } 44 }
46 45
@@ -147,16 +146,9 @@ void OpenGLState::Apply() {
147 146
148 // Textures 147 // Textures
149 for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) { 148 for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
150 if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d || 149 if (texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) {
151 texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) {
152
153 glActiveTexture(GL_TEXTURE0 + texture_index); 150 glActiveTexture(GL_TEXTURE0 + texture_index);
154 151 glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d);
155 if (texture_units[texture_index].enabled_2d) {
156 glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d);
157 } else {
158 glBindTexture(GL_TEXTURE_2D, 0);
159 }
160 } 152 }
161 } 153 }
162 154
@@ -182,3 +174,35 @@ void OpenGLState::Apply() {
182 174
183 cur_state = *this; 175 cur_state = *this;
184} 176}
177
178void OpenGLState::ResetTexture(GLuint id) {
179 for (auto& unit : cur_state.texture_units) {
180 if (unit.texture_2d == id) {
181 unit.texture_2d = 0;
182 }
183 }
184}
185
186void OpenGLState::ResetProgram(GLuint id) {
187 if (cur_state.draw.shader_program == id) {
188 cur_state.draw.shader_program = 0;
189 }
190}
191
192void OpenGLState::ResetBuffer(GLuint id) {
193 if (cur_state.draw.vertex_buffer == id) {
194 cur_state.draw.vertex_buffer = 0;
195 }
196}
197
198void OpenGLState::ResetVertexArray(GLuint id) {
199 if (cur_state.draw.vertex_array == id) {
200 cur_state.draw.vertex_array = 0;
201 }
202}
203
204void OpenGLState::ResetFramebuffer(GLuint id) {
205 if (cur_state.draw.framebuffer == id) {
206 cur_state.draw.framebuffer = 0;
207 }
208}
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 26b916360..3e2379021 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -53,7 +53,6 @@ public:
53 53
54 // 3 texture units - one for each that is used in PICA fragment shader emulation 54 // 3 texture units - one for each that is used in PICA fragment shader emulation
55 struct { 55 struct {
56 bool enabled_2d; // GL_TEXTURE_2D
57 GLuint texture_2d; // GL_TEXTURE_BINDING_2D 56 GLuint texture_2d; // GL_TEXTURE_BINDING_2D
58 } texture_units[3]; 57 } texture_units[3];
59 58
@@ -74,6 +73,12 @@ public:
74 /// Apply this state as the current OpenGL state 73 /// Apply this state as the current OpenGL state
75 void Apply(); 74 void Apply();
76 75
76 static void ResetTexture(GLuint id);
77 static void ResetProgram(GLuint id);
78 static void ResetBuffer(GLuint id);
79 static void ResetVertexArray(GLuint id);
80 static void ResetFramebuffer(GLuint id);
81
77private: 82private:
78 static OpenGLState cur_state; 83 static OpenGLState cur_state;
79}; 84};
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 96e12839a..79a940ff6 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -163,7 +163,6 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
163 // only allows rows to have a memory alignement of 4. 163 // only allows rows to have a memory alignement of 4.
164 ASSERT(pixel_stride % 4 == 0); 164 ASSERT(pixel_stride % 4 == 0);
165 165
166 state.texture_units[0].enabled_2d = true;
167 state.texture_units[0].texture_2d = texture.handle; 166 state.texture_units[0].texture_2d = texture.handle;
168 state.Apply(); 167 state.Apply();
169 168
@@ -191,7 +190,6 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
191 */ 190 */
192void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, 191void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
193 const TextureInfo& texture) { 192 const TextureInfo& texture) {
194 state.texture_units[0].enabled_2d = true;
195 state.texture_units[0].texture_2d = texture.handle; 193 state.texture_units[0].texture_2d = texture.handle;
196 state.Apply(); 194 state.Apply();
197 195
@@ -239,7 +237,6 @@ void RendererOpenGL::InitOpenGLObjects() {
239 // Allocation of storage is deferred until the first frame, when we 237 // Allocation of storage is deferred until the first frame, when we
240 // know the framebuffer size. 238 // know the framebuffer size.
241 239
242 state.texture_units[0].enabled_2d = true;
243 state.texture_units[0].texture_2d = texture.handle; 240 state.texture_units[0].texture_2d = texture.handle;
244 state.Apply(); 241 state.Apply();
245 242
@@ -305,7 +302,6 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
305 UNIMPLEMENTED(); 302 UNIMPLEMENTED();
306 } 303 }
307 304
308 state.texture_units[0].enabled_2d = true;
309 state.texture_units[0].texture_2d = texture.handle; 305 state.texture_units[0].texture_2d = texture.handle;
310 state.Apply(); 306 state.Apply();
311 307
@@ -325,7 +321,6 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x
325 ScreenRectVertex(x+w, y+h, 0.f, 1.f), 321 ScreenRectVertex(x+w, y+h, 0.f, 1.f),
326 }; 322 };
327 323
328 state.texture_units[0].enabled_2d = true;
329 state.texture_units[0].texture_2d = texture.handle; 324 state.texture_units[0].texture_2d = texture.handle;
330 state.Apply(); 325 state.Apply();
331 326