From 624c767a1e15c8e4ed3cf1ee999ae92621f8ca32 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Fri, 11 Mar 2016 00:54:39 +0100 Subject: [PATCH] VideoCore: Keep track of the active texture. --- .../renderer_opengl/gl_rasterizer.cpp | 18 +++++++++--------- .../renderer_opengl/gl_rasterizer_cache.cpp | 2 +- src/video_core/renderer_opengl/gl_state.cpp | 15 +++++++++++++-- src/video_core/renderer_opengl/gl_state.h | 8 ++++++++ .../renderer_opengl/renderer_opengl.cpp | 10 +++++----- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b3dc6aa19..1cb437992 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -123,7 +123,7 @@ void RasterizerOpenGL::InitObjects() { state.draw.framebuffer = framebuffer.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.handle, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.handle, 0); @@ -131,7 +131,7 @@ void RasterizerOpenGL::InitObjects() { lighting_lut[i].Create(); state.lighting_lut[i].texture_1d = lighting_lut[i].handle; - glActiveTexture(GL_TEXTURE3 + i); + state.SetActiveTexture(GL_TEXTURE3 + i); glBindTexture(GL_TEXTURE_1D, state.lighting_lut[i].texture_1d); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); @@ -621,7 +621,7 @@ void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs: state.texture_units[0].texture_2d = texture.texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, texture.gl_format, texture.gl_type, nullptr); @@ -664,7 +664,7 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica:: state.texture_units[0].texture_2d = texture.texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, texture.gl_format, texture.gl_type, nullptr); @@ -934,7 +934,7 @@ void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) { if (new_data != lighting_lut_data[lut_index]) { lighting_lut_data[lut_index] = new_data; - glActiveTexture(GL_TEXTURE3 + lut_index); + state.SetActiveTexture(GL_TEXTURE3 + lut_index); glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, lighting_lut_data[lut_index].data()); } } @@ -1043,7 +1043,7 @@ void RasterizerOpenGL::ReloadColorBuffer() { state.texture_units[0].texture_2d = fb_color_texture.texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get()); @@ -1100,7 +1100,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() { state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) { // TODO(Subv): There is a bug with Intel Windows drivers that makes glTexSubImage2D not change the stencil buffer. // The bug has been reported to Intel (https://communities.intel.com/message/324464) @@ -1133,7 +1133,7 @@ void RasterizerOpenGL::CommitColorBuffer() { state.texture_units[0].texture_2d = fb_color_texture.texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get()); state.texture_units[0].texture_2d = 0; @@ -1173,7 +1173,7 @@ void RasterizerOpenGL::CommitDepthBuffer() { state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get()); state.texture_units[0].texture_2d = 0; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index a9ad46fe0..25c5a11dc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -34,7 +34,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); + state.SetActiveTexture(GL_TEXTURE0 + texture_unit); u8* texture_src_data = Memory::GetPhysicalPointer(info.physical_address); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 08e4d0b54..86b7307e5 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -163,10 +163,15 @@ void OpenGLState::Apply() { glLogicOp(logic_op); } + GLenum last_texture = active_texture; + // Textures for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { - glActiveTexture(GL_TEXTURE0 + i); + if (last_texture != GL_TEXTURE0 + i) { + glActiveTexture(GL_TEXTURE0 + i); + last_texture = GL_TEXTURE0 + i; + } glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); } if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { @@ -177,11 +182,17 @@ void OpenGLState::Apply() { // Lighting LUTs for (unsigned i = 0; i < ARRAY_SIZE(lighting_lut); ++i) { if (lighting_lut[i].texture_1d != cur_state.lighting_lut[i].texture_1d) { - glActiveTexture(GL_TEXTURE3 + i); + if (last_texture != GL_TEXTURE3 + i) { + glActiveTexture(GL_TEXTURE3 + i); + last_texture = GL_TEXTURE3 + i; + } glBindTexture(GL_TEXTURE_1D, lighting_lut[i].texture_1d); } } + if (last_texture != active_texture) + glActiveTexture(active_texture); + // Framebuffer if (draw.framebuffer != cur_state.draw.framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer); diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index e848058d7..1b5e0f5bd 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -54,6 +54,14 @@ public: } blend; GLenum logic_op; // GL_LOGIC_OP_MODE + GLenum active_texture = GL_TEXTURE0; // GL_ACTIVE_TEXTURE + + void SetActiveTexture(GLenum unit) { + if (unit != active_texture) { + glActiveTexture(unit); + active_texture = unit; + } + } // 3 texture units - one for each that is used in PICA fragment shader emulation struct { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 11c4d0daf..31d54f041 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -192,7 +192,7 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& state.texture_units[0].texture_2d = texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); // Update existing texture @@ -219,7 +219,7 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color state.texture_units[0].texture_2d = texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); u8 framebuffer_data[3] = { color_r, color_g, color_b }; // Update existing texture @@ -267,7 +267,7 @@ void RendererOpenGL::InitOpenGLObjects() { state.texture_units[0].texture_2d = texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -330,7 +330,7 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, state.texture_units[0].texture_2d = texture.handle; state.Apply(); - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, texture.gl_format, texture.gl_type, nullptr); } @@ -371,7 +371,7 @@ void RendererOpenGL::DrawScreens() { glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data()); // Bind texture in Texture Unit 0 - glActiveTexture(GL_TEXTURE0); + state.SetActiveTexture(GL_TEXTURE0); glUniform1i(uniform_color_texture, 0); DrawSingleScreenRotated(textures[0], (float)layout.top_screen.left, (float)layout.top_screen.top,