From e964060a6a30fe699bc7e7b95a9ddbeadccfb66f Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 26 May 2022 02:10:59 +0300 Subject: [PATCH] gl: Handle texture binding using the global state tracker --- rpcs3/Emu/RSX/GL/GLDraw.cpp | 18 ++++++------------ rpcs3/Emu/RSX/GL/GLExecutionState.h | 15 +++++++++++++++ rpcs3/Emu/RSX/GL/GLGSRender.cpp | 6 ++---- rpcs3/Emu/RSX/GL/GLHelpers.h | 10 ++++------ 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index ebd4b97224..8122c7e36b 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -359,8 +359,6 @@ void GLGSRender::bind_texture_env() if (!(textures_ref & 1)) continue; - _SelectTexture(GL_FRAGMENT_TEXTURES_START + i); - gl::texture_view* view = nullptr; auto sampler_state = static_cast(fs_sampler_state[i].get()); @@ -375,26 +373,23 @@ void GLGSRender::bind_texture_env() if (view) [[likely]] { - view->bind(); + view->bind(cmd, GL_FRAGMENT_TEXTURES_START + i); if (current_fragment_program.texture_state.redirected_textures & (1 << i)) { - _SelectTexture(GL_STENCIL_MIRRORS_START + i); - auto root_texture = static_cast(view->image()); auto stencil_view = root_texture->get_view(0xAAE4, rsx::default_remap_vector, gl::image_aspect::stencil); - stencil_view->bind(); + stencil_view->bind(cmd, GL_STENCIL_MIRRORS_START + i); } } else { auto target = gl::get_target(current_fragment_program.get_texture_dimension(i)); - glBindTexture(target, m_null_textures[target]->id()); + cmd->bind_texture(GL_FRAGMENT_TEXTURES_START + i, target, m_null_textures[target]->id()); if (current_fragment_program.texture_state.redirected_textures & (1 << i)) { - _SelectTexture(GL_STENCIL_MIRRORS_START + i); - glBindTexture(target, m_null_textures[target]->id()); + cmd->bind_texture(GL_STENCIL_MIRRORS_START + i, target, m_null_textures[target]->id()); } } } @@ -405,18 +400,17 @@ void GLGSRender::bind_texture_env() continue; auto sampler_state = static_cast(vs_sampler_state[i].get()); - _SelectTexture(GL_VERTEX_TEXTURES_START + i); if (rsx::method_registers.vertex_textures[i].enabled() && sampler_state->validate()) { if (sampler_state->image_handle) [[likely]] { - sampler_state->image_handle->bind(); + sampler_state->image_handle->bind(cmd, GL_VERTEX_TEXTURES_START + i); } else { - m_gl_texture_cache.create_temporary_subresource(cmd, sampler_state->external_subresource_desc)->bind(); + m_gl_texture_cache.create_temporary_subresource(cmd, sampler_state->external_subresource_desc)->bind(cmd, GL_VERTEX_TEXTURES_START + i); } } else diff --git a/rpcs3/Emu/RSX/GL/GLExecutionState.h b/rpcs3/Emu/RSX/GL/GLExecutionState.h index 41c06c8d2d..660674ef32 100644 --- a/rpcs3/Emu/RSX/GL/GLExecutionState.h +++ b/rpcs3/Emu/RSX/GL/GLExecutionState.h @@ -233,6 +233,7 @@ namespace gl std::unordered_map> indexed_properties = {}; GLuint current_program = GL_NONE; + std::array, 48> bound_textures{ {} }; bool enable(u32 test, GLenum cap) { @@ -500,6 +501,20 @@ namespace gl current_program = program; glUseProgram(program); } + + void bind_texture(GLuint layer, GLenum target, GLuint name) + { + ensure(layer < 48); + + auto& bound = bound_textures[layer][target]; + if (bound != name) + { + glActiveTexture(GL_TEXTURE0 + layer); + glBindTexture(target, name); + + bound = name; + } + } }; class command_context diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index bae819394e..03fe365da3 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -168,15 +168,13 @@ void GLGSRender::on_init_thread() // Array stream buffer { m_gl_persistent_stream_buffer = std::make_unique(GL_TEXTURE_BUFFER, 0, 0, 0, 0, GL_R8UI); - _SelectTexture(GL_STREAM_BUFFER_START + 0); - glBindTexture(GL_TEXTURE_BUFFER, m_gl_persistent_stream_buffer->id()); + gl_state.bind_texture(GL_STREAM_BUFFER_START + 0, GL_TEXTURE_BUFFER, m_gl_persistent_stream_buffer->id()); } // Register stream buffer { m_gl_volatile_stream_buffer = std::make_unique(GL_TEXTURE_BUFFER, 0, 0, 0, 0, GL_R8UI); - _SelectTexture(GL_STREAM_BUFFER_START + 1); - glBindTexture(GL_TEXTURE_BUFFER, m_gl_volatile_stream_buffer->id()); + gl_state.bind_texture(GL_STREAM_BUFFER_START + 1, GL_TEXTURE_BUFFER, m_gl_volatile_stream_buffer->id()); } // Fallback null texture instead of relying on texture0 diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 7dd27e3989..d3ae704d87 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -43,8 +43,6 @@ #define APIENTRY #endif -inline static void _SelectTexture(int unit) { glActiveTexture(GL_TEXTURE0 + unit); } - //using enum rsx::format_class; using namespace ::rsx::format_class_; @@ -1861,9 +1859,9 @@ namespace gl argb_swizzle[3] == component_swizzle[2]); } - void bind() const + void bind(gl::command_context& cmd, GLuint layer) const { - glBindTexture(m_target, m_id); + cmd->bind_texture(layer, m_target, m_id); } texture* image() const @@ -2534,14 +2532,14 @@ public: return result; } - int texture(GLint location, int active_texture, const gl::texture_view& texture) + /*int texture(GLint location, int active_texture, const gl::texture_view& texture) { glActiveTexture(GL_TEXTURE0 + active_texture); texture.bind(); (*this)[location] = active_texture; return active_texture; - } + }*/ uniform_t operator[](GLint location) {