From 863edeefe0b533a89f177dc1b4656c9e1677b6f8 Mon Sep 17 00:00:00 2001 From: tfarley Date: Sun, 17 May 2015 15:12:27 -0700 Subject: [PATCH] Skip pass-thru tev stages, upper_bound calc once --- .../renderer_opengl/gl_rasterizer.cpp | 50 +++++++++++------- .../renderer_opengl/gl_rasterizer.h | 1 + .../renderer_opengl/gl_rasterizer_cache.cpp | 4 +- src/video_core/renderer_opengl/gl_shaders.h | 51 +++++++++---------- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ae450f4f4..0f5102a35 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -43,6 +43,7 @@ void RasterizerOpenGL::InitObjects() { auto& uniform_tev = uniform_tev_cfgs[i]; std::string tev_ref_str = "tev_cfgs[" + std::to_string(i) + "]"; + uniform_tev.enabled = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + ".enabled").c_str()); uniform_tev.color_sources = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + ".color_sources").c_str()); uniform_tev.alpha_sources = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + ".alpha_sources").c_str()); uniform_tev.color_modifiers = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + ".color_modifiers").c_str()); @@ -479,25 +480,38 @@ void RasterizerOpenGL::SyncDrawState() { const auto& stage = tev_stages[tev_stage_idx]; const auto& uniform_tev_cfg = uniform_tev_cfgs[tev_stage_idx]; - GLint color_srcs[3] = { (GLint)stage.color_source1.Value(), (GLint)stage.color_source2.Value(), (GLint)stage.color_source3.Value() }; - GLint alpha_srcs[3] = { (GLint)stage.alpha_source1.Value(), (GLint)stage.alpha_source2.Value(), (GLint)stage.alpha_source3.Value() }; - GLint color_mods[3] = { (GLint)stage.color_modifier1.Value(), (GLint)stage.color_modifier2.Value(), (GLint)stage.color_modifier3.Value() }; - GLint alpha_mods[3] = { (GLint)stage.alpha_modifier1.Value(), (GLint)stage.alpha_modifier2.Value(), (GLint)stage.alpha_modifier3.Value() }; - GLfloat const_color[4] = { stage.const_r / 255.0f, - stage.const_g / 255.0f, - stage.const_b / 255.0f, - stage.const_a / 255.0f }; + // No need to process the tev stage if it simply passes the previous stage results through + if (stage.color_op == Pica::Regs::TevStageConfig::Operation::Replace && + stage.alpha_op == Pica::Regs::TevStageConfig::Operation::Replace && + stage.color_source1 == Pica::Regs::TevStageConfig::Source::Previous && + stage.alpha_source1 == Pica::Regs::TevStageConfig::Source::Previous && + stage.color_modifier1 == Pica::Regs::TevStageConfig::ColorModifier::SourceColor && + stage.alpha_modifier1 == Pica::Regs::TevStageConfig::AlphaModifier::SourceAlpha && + stage.GetColorMultiplier() == 1 && + stage.GetAlphaMultiplier() == 1) { + glUniform1i(uniform_tev_cfg.enabled, 0); + } else { + GLint color_srcs[3] = { (GLint)stage.color_source1.Value(), (GLint)stage.color_source2.Value(), (GLint)stage.color_source3.Value() }; + GLint alpha_srcs[3] = { (GLint)stage.alpha_source1.Value(), (GLint)stage.alpha_source2.Value(), (GLint)stage.alpha_source3.Value() }; + GLint color_mods[3] = { (GLint)stage.color_modifier1.Value(), (GLint)stage.color_modifier2.Value(), (GLint)stage.color_modifier3.Value() }; + GLint alpha_mods[3] = { (GLint)stage.alpha_modifier1.Value(), (GLint)stage.alpha_modifier2.Value(), (GLint)stage.alpha_modifier3.Value() }; + GLfloat const_color[4] = { stage.const_r / 255.0f, + stage.const_g / 255.0f, + stage.const_b / 255.0f, + stage.const_a / 255.0f }; - glUniform3iv(uniform_tev_cfg.color_sources, 1, color_srcs); - glUniform3iv(uniform_tev_cfg.alpha_sources, 1, alpha_srcs); - glUniform3iv(uniform_tev_cfg.color_modifiers, 1, color_mods); - glUniform3iv(uniform_tev_cfg.alpha_modifiers, 1, alpha_mods); - glUniform2i(uniform_tev_cfg.color_alpha_op, (GLint)stage.color_op.Value(), (GLint)stage.alpha_op.Value()); - glUniform2i(uniform_tev_cfg.color_alpha_multiplier, stage.GetColorMultiplier(), stage.GetAlphaMultiplier()); - glUniform4fv(uniform_tev_cfg.const_color, 1, const_color); - glUniform2i(uniform_tev_cfg.updates_combiner_buffer_color_alpha, - Pica::registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_idx), - Pica::registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_idx)); + glUniform1i(uniform_tev_cfg.enabled, 1); + glUniform3iv(uniform_tev_cfg.color_sources, 1, color_srcs); + glUniform3iv(uniform_tev_cfg.alpha_sources, 1, alpha_srcs); + glUniform3iv(uniform_tev_cfg.color_modifiers, 1, color_mods); + glUniform3iv(uniform_tev_cfg.alpha_modifiers, 1, alpha_mods); + glUniform2i(uniform_tev_cfg.color_alpha_op, (GLint)stage.color_op.Value(), (GLint)stage.alpha_op.Value()); + glUniform2i(uniform_tev_cfg.color_alpha_multiplier, stage.GetColorMultiplier(), stage.GetAlphaMultiplier()); + glUniform4fv(uniform_tev_cfg.const_color, 1, const_color); + glUniform2i(uniform_tev_cfg.updates_combiner_buffer_color_alpha, + Pica::registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_idx), + Pica::registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_idx)); + } } // Sync alpha testing to hw shader diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index f6de10a1d..4cf8dc0fc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -35,6 +35,7 @@ public: private: /// Structure used for managing texture environment states struct TEVConfigUniforms { + GLuint enabled; GLuint color_sources; GLuint alpha_sources; GLuint color_modifiers; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 9b7a40aa8..d2fd70bc9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -60,7 +60,9 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, int texture_u void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) { // Flush any texture that falls in the flushed region - for (auto it = texture_cache.begin(); it != texture_cache.upper_bound(addr + size);) { + // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound + auto cache_upper_bound = texture_cache.upper_bound(addr + size); + for (auto it = texture_cache.begin(); it != cache_upper_bound;) { PAddr max_low_addr_bound = std::max(addr, it->first); PAddr min_hi_addr_bound = std::min(addr + size, it->first + it->second->size); diff --git a/src/video_core/renderer_opengl/gl_shaders.h b/src/video_core/renderer_opengl/gl_shaders.h index 34d3ac28d..3527f8601 100644 --- a/src/video_core/renderer_opengl/gl_shaders.h +++ b/src/video_core/renderer_opengl/gl_shaders.h @@ -144,6 +144,7 @@ uniform vec4 tev_combiner_buffer_color; struct TEVConfig { + bool enabled; ivec3 color_sources; ivec3 alpha_sources; ivec3 color_modifiers; @@ -286,35 +287,33 @@ float AlphaCombine(int op, float alpha[3]) { return 0.0; } -void ProcessTexEnv(int tex_env_idx) { - g_const_color = tev_cfgs[tex_env_idx].const_color; - - vec3 color_results[3] = vec3[3](GetColorModifier(tev_cfgs[tex_env_idx].color_modifiers.x, GetSource(tev_cfgs[tex_env_idx].color_sources.x)), - GetColorModifier(tev_cfgs[tex_env_idx].color_modifiers.y, GetSource(tev_cfgs[tex_env_idx].color_sources.y)), - GetColorModifier(tev_cfgs[tex_env_idx].color_modifiers.z, GetSource(tev_cfgs[tex_env_idx].color_sources.z))); - vec3 color_output = ColorCombine(tev_cfgs[tex_env_idx].color_alpha_op.x, color_results); - - float alpha_results[3] = float[3](GetAlphaModifier(tev_cfgs[tex_env_idx].alpha_modifiers.x, GetSource(tev_cfgs[tex_env_idx].alpha_sources.x)), - GetAlphaModifier(tev_cfgs[tex_env_idx].alpha_modifiers.y, GetSource(tev_cfgs[tex_env_idx].alpha_sources.y)), - GetAlphaModifier(tev_cfgs[tex_env_idx].alpha_modifiers.z, GetSource(tev_cfgs[tex_env_idx].alpha_sources.z))); - float alpha_output = AlphaCombine(tev_cfgs[tex_env_idx].color_alpha_op.y, alpha_results); - - g_last_tex_env_out = vec4(min(color_output * tev_cfgs[tex_env_idx].color_alpha_multiplier.x, 1.0), min(alpha_output * tev_cfgs[tex_env_idx].color_alpha_multiplier.y, 1.0)); - - if (tev_cfgs[tex_env_idx].updates_combiner_buffer_color_alpha.x) { - g_combiner_buffer.rgb = g_last_tex_env_out.rgb; - } - - if (tev_cfgs[tex_env_idx].updates_combiner_buffer_color_alpha.y) { - g_combiner_buffer.a = g_last_tex_env_out.a; - } -} - void main(void) { g_combiner_buffer = tev_combiner_buffer_color; - for (int i = 0; i < NUM_TEV_STAGES; ++i) { - ProcessTexEnv(i); + for (int tex_env_idx = 0; tex_env_idx < NUM_TEV_STAGES; ++tex_env_idx) { + if (tev_cfgs[tex_env_idx].enabled) { + g_const_color = tev_cfgs[tex_env_idx].const_color; + + vec3 color_results[3] = vec3[3](GetColorModifier(tev_cfgs[tex_env_idx].color_modifiers.x, GetSource(tev_cfgs[tex_env_idx].color_sources.x)), + GetColorModifier(tev_cfgs[tex_env_idx].color_modifiers.y, GetSource(tev_cfgs[tex_env_idx].color_sources.y)), + GetColorModifier(tev_cfgs[tex_env_idx].color_modifiers.z, GetSource(tev_cfgs[tex_env_idx].color_sources.z))); + vec3 color_output = ColorCombine(tev_cfgs[tex_env_idx].color_alpha_op.x, color_results); + + float alpha_results[3] = float[3](GetAlphaModifier(tev_cfgs[tex_env_idx].alpha_modifiers.x, GetSource(tev_cfgs[tex_env_idx].alpha_sources.x)), + GetAlphaModifier(tev_cfgs[tex_env_idx].alpha_modifiers.y, GetSource(tev_cfgs[tex_env_idx].alpha_sources.y)), + GetAlphaModifier(tev_cfgs[tex_env_idx].alpha_modifiers.z, GetSource(tev_cfgs[tex_env_idx].alpha_sources.z))); + float alpha_output = AlphaCombine(tev_cfgs[tex_env_idx].color_alpha_op.y, alpha_results); + + g_last_tex_env_out = vec4(min(color_output * tev_cfgs[tex_env_idx].color_alpha_multiplier.x, 1.0), min(alpha_output * tev_cfgs[tex_env_idx].color_alpha_multiplier.y, 1.0)); + } + + if (tev_cfgs[tex_env_idx].updates_combiner_buffer_color_alpha.x) { + g_combiner_buffer.rgb = g_last_tex_env_out.rgb; + } + + if (tev_cfgs[tex_env_idx].updates_combiner_buffer_color_alpha.y) { + g_combiner_buffer.a = g_last_tex_env_out.a; + } } if (alphatest_func == COMPAREFUNC_NEVER) {