From c32c1b0a62ab0297bd019592e1eee418cf8651fa Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 18 Jun 2019 16:49:01 +0300 Subject: [PATCH] gl: Minor API tweaks - Avoid spamming the driver with samplerParameter calls unless the parameters have actually changed --- rpcs3/Emu/RSX/GL/GLTexture.cpp | 88 +++++++++++++++++++--------------- rpcs3/Emu/RSX/GL/GLTexture.h | 40 ++++++++++++++++ 2 files changed, 90 insertions(+), 38 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 43c5efb41f..f66eadb215 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -209,12 +209,18 @@ namespace gl //Apply sampler state settings void sampler_state::apply(const rsx::fragment_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image) { - const color4f border_color = rsx::decode_border_color(tex.border_color()); + set_parameteri(GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s())); + set_parameteri(GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t())); + set_parameteri(GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r())); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s())); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t())); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r())); - glSamplerParameterfv(samplerHandle, GL_TEXTURE_BORDER_COLOR, border_color.rgba); + if (const auto color = tex.border_color(); + get_parameteri(GL_TEXTURE_BORDER_COLOR) != color) + { + m_propertiesi[GL_TEXTURE_BORDER_COLOR] = color; + + const color4f border_color = rsx::decode_border_color(color); + glSamplerParameterfv(samplerHandle, GL_TEXTURE_BORDER_COLOR, border_color.rgba); + } if (sampled_image->upload_context != rsx::texture_upload_context::shader_read || tex.get_exact_mipmap_count() == 1) @@ -237,23 +243,23 @@ namespace gl } } - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, min_filter); - glSamplerParameterf(samplerHandle, GL_TEXTURE_LOD_BIAS, 0.f); - glSamplerParameterf(samplerHandle, GL_TEXTURE_MIN_LOD, -1000.f); - glSamplerParameterf(samplerHandle, GL_TEXTURE_MAX_LOD, 1000.f); + set_parameteri(GL_TEXTURE_MIN_FILTER, min_filter); + set_parameterf(GL_TEXTURE_LOD_BIAS, 0.f); + set_parameterf(GL_TEXTURE_MIN_LOD, -1000.f); + set_parameterf(GL_TEXTURE_MAX_LOD, 1000.f); } else { - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, tex_min_filter(tex.min_filter())); - glSamplerParameterf(samplerHandle, GL_TEXTURE_LOD_BIAS, tex.bias()); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); + set_parameteri(GL_TEXTURE_MIN_FILTER, tex_min_filter(tex.min_filter())); + set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias()); + set_parameteri(GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); + set_parameteri(GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); } const bool aniso_override = !g_cfg.video.strict_rendering_mode && g_cfg.video.anisotropic_level_override > 0; f32 af_level = aniso_override ? g_cfg.video.anisotropic_level_override : max_aniso(tex.max_aniso()); - glSamplerParameterf(samplerHandle, GL_TEXTURE_MAX_ANISOTROPY_EXT, af_level); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, tex_mag_filter(tex.mag_filter())); + set_parameterf(GL_TEXTURE_MAX_ANISOTROPY_EXT, af_level); + set_parameteri(GL_TEXTURE_MAG_FILTER, tex_mag_filter(tex.mag_filter())); const u32 texture_format = tex.format() & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN); if (texture_format == CELL_GCM_TEXTURE_DEPTH16 || texture_format == CELL_GCM_TEXTURE_DEPTH24_D8 || @@ -270,40 +276,46 @@ namespace gl case GL_LEQUAL: compare_mode = GL_GEQUAL; break; } - glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_FUNC, compare_mode); + set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + set_parameteri(GL_TEXTURE_COMPARE_FUNC, compare_mode); } else - glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE); + set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE); } void sampler_state::apply(const rsx::vertex_texture& tex, const rsx::sampled_image_descriptor_base* /*sampled_image*/) { - const color4f border_color = rsx::decode_border_color(tex.border_color()); - glSamplerParameterfv(samplerHandle, GL_TEXTURE_BORDER_COLOR, border_color.rgba); + if (const auto color = tex.border_color(); + get_parameteri(GL_TEXTURE_BORDER_COLOR) != color) + { + m_propertiesi[GL_TEXTURE_BORDER_COLOR] = color; - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s())); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t())); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r())); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glSamplerParameterf(samplerHandle, GL_TEXTURE_LOD_BIAS, tex.bias()); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); - glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE); + const color4f border_color = rsx::decode_border_color(color); + glSamplerParameterfv(samplerHandle, GL_TEXTURE_BORDER_COLOR, border_color.rgba); + } + + set_parameteri(GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s())); + set_parameteri(GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t())); + set_parameteri(GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r())); + set_parameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST); + set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST); + set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias()); + set_parameteri(GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); + set_parameteri(GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); + set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE); } void sampler_state::apply_defaults(GLenum default_filter) { - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, GL_REPEAT); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, GL_REPEAT); - glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, GL_REPEAT); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, default_filter); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, default_filter); - glSamplerParameterf(samplerHandle, GL_TEXTURE_LOD_BIAS, 0.f); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_LOD, 0); - glSamplerParameteri(samplerHandle, GL_TEXTURE_MAX_LOD, 0); - glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE); + set_parameteri(GL_TEXTURE_WRAP_S, GL_REPEAT); + set_parameteri(GL_TEXTURE_WRAP_T, GL_REPEAT); + set_parameteri(GL_TEXTURE_WRAP_R, GL_REPEAT); + set_parameteri(GL_TEXTURE_MIN_FILTER, default_filter); + set_parameteri(GL_TEXTURE_MAG_FILTER, default_filter); + set_parameterf(GL_TEXTURE_LOD_BIAS, 0.f); + set_parameteri(GL_TEXTURE_MIN_LOD, 0); + set_parameteri(GL_TEXTURE_MAX_LOD, 0); + set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE); } bool is_compressed_format(u32 texture_format) diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index 2d1b828046..4168353560 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -39,6 +39,8 @@ namespace gl class sampler_state { GLuint samplerHandle = 0; + std::unordered_map m_propertiesi; + std::unordered_map m_propertiesf; public: @@ -57,6 +59,44 @@ namespace gl glBindSampler(index, samplerHandle); } + void set_parameteri(GLenum pname, GLuint value) + { + auto prop = m_propertiesi.find(pname); + if (prop != m_propertiesi.end() && + prop->second == value) + { + return; + } + + m_propertiesi[pname] = value; + glSamplerParameteri(samplerHandle, pname, value); + } + + void set_parameterf(GLenum pname, GLfloat value) + { + auto prop = m_propertiesf.find(pname); + if (prop != m_propertiesf.end() && + prop->second == value) + { + return; + } + + m_propertiesf[pname] = value; + glSamplerParameterf(samplerHandle, pname, value); + } + + GLuint get_parameteri(GLenum pname) + { + auto prop = m_propertiesi.find(pname); + return (prop == m_propertiesi.end()) ? 0 : prop->second; + } + + GLfloat get_parameterf(GLenum pname) + { + auto prop = m_propertiesf.find(pname); + return (prop == m_propertiesf.end()) ? 0 : prop->second; + } + void apply(const rsx::fragment_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image); void apply(const rsx::vertex_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image);