Skip pass-thru tev stages, upper_bound calc once

This commit is contained in:
tfarley 2015-05-17 15:12:27 -07:00
parent dfc807daf9
commit 863edeefe0
4 changed files with 61 additions and 45 deletions

View File

@ -43,6 +43,7 @@ void RasterizerOpenGL::InitObjects() {
auto& uniform_tev = uniform_tev_cfgs[i]; auto& uniform_tev = uniform_tev_cfgs[i];
std::string tev_ref_str = "tev_cfgs[" + std::to_string(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.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.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()); 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& stage = tev_stages[tev_stage_idx];
const auto& uniform_tev_cfg = uniform_tev_cfgs[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() }; // No need to process the tev stage if it simply passes the previous stage results through
GLint alpha_srcs[3] = { (GLint)stage.alpha_source1.Value(), (GLint)stage.alpha_source2.Value(), (GLint)stage.alpha_source3.Value() }; if (stage.color_op == Pica::Regs::TevStageConfig::Operation::Replace &&
GLint color_mods[3] = { (GLint)stage.color_modifier1.Value(), (GLint)stage.color_modifier2.Value(), (GLint)stage.color_modifier3.Value() }; stage.alpha_op == Pica::Regs::TevStageConfig::Operation::Replace &&
GLint alpha_mods[3] = { (GLint)stage.alpha_modifier1.Value(), (GLint)stage.alpha_modifier2.Value(), (GLint)stage.alpha_modifier3.Value() }; stage.color_source1 == Pica::Regs::TevStageConfig::Source::Previous &&
GLfloat const_color[4] = { stage.const_r / 255.0f, stage.alpha_source1 == Pica::Regs::TevStageConfig::Source::Previous &&
stage.const_g / 255.0f, stage.color_modifier1 == Pica::Regs::TevStageConfig::ColorModifier::SourceColor &&
stage.const_b / 255.0f, stage.alpha_modifier1 == Pica::Regs::TevStageConfig::AlphaModifier::SourceAlpha &&
stage.const_a / 255.0f }; 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); glUniform1i(uniform_tev_cfg.enabled, 1);
glUniform3iv(uniform_tev_cfg.alpha_sources, 1, alpha_srcs); glUniform3iv(uniform_tev_cfg.color_sources, 1, color_srcs);
glUniform3iv(uniform_tev_cfg.color_modifiers, 1, color_mods); glUniform3iv(uniform_tev_cfg.alpha_sources, 1, alpha_srcs);
glUniform3iv(uniform_tev_cfg.alpha_modifiers, 1, alpha_mods); glUniform3iv(uniform_tev_cfg.color_modifiers, 1, color_mods);
glUniform2i(uniform_tev_cfg.color_alpha_op, (GLint)stage.color_op.Value(), (GLint)stage.alpha_op.Value()); glUniform3iv(uniform_tev_cfg.alpha_modifiers, 1, alpha_mods);
glUniform2i(uniform_tev_cfg.color_alpha_multiplier, stage.GetColorMultiplier(), stage.GetAlphaMultiplier()); glUniform2i(uniform_tev_cfg.color_alpha_op, (GLint)stage.color_op.Value(), (GLint)stage.alpha_op.Value());
glUniform4fv(uniform_tev_cfg.const_color, 1, const_color); glUniform2i(uniform_tev_cfg.color_alpha_multiplier, stage.GetColorMultiplier(), stage.GetAlphaMultiplier());
glUniform2i(uniform_tev_cfg.updates_combiner_buffer_color_alpha, glUniform4fv(uniform_tev_cfg.const_color, 1, const_color);
Pica::registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_idx), glUniform2i(uniform_tev_cfg.updates_combiner_buffer_color_alpha,
Pica::registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_idx)); 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 // Sync alpha testing to hw shader

View File

@ -35,6 +35,7 @@ public:
private: private:
/// Structure used for managing texture environment states /// Structure used for managing texture environment states
struct TEVConfigUniforms { struct TEVConfigUniforms {
GLuint enabled;
GLuint color_sources; GLuint color_sources;
GLuint alpha_sources; GLuint alpha_sources;
GLuint color_modifiers; GLuint color_modifiers;

View File

@ -60,7 +60,9 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, int texture_u
void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) { void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) {
// Flush any texture that falls in the flushed region // 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 max_low_addr_bound = std::max(addr, it->first);
PAddr min_hi_addr_bound = std::min(addr + size, it->first + it->second->size); PAddr min_hi_addr_bound = std::min(addr + size, it->first + it->second->size);

View File

@ -144,6 +144,7 @@ uniform vec4 tev_combiner_buffer_color;
struct TEVConfig struct TEVConfig
{ {
bool enabled;
ivec3 color_sources; ivec3 color_sources;
ivec3 alpha_sources; ivec3 alpha_sources;
ivec3 color_modifiers; ivec3 color_modifiers;
@ -286,35 +287,33 @@ float AlphaCombine(int op, float alpha[3]) {
return 0.0; 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) { void main(void) {
g_combiner_buffer = tev_combiner_buffer_color; g_combiner_buffer = tev_combiner_buffer_color;
for (int i = 0; i < NUM_TEV_STAGES; ++i) { for (int tex_env_idx = 0; tex_env_idx < NUM_TEV_STAGES; ++tex_env_idx) {
ProcessTexEnv(i); 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) { if (alphatest_func == COMPAREFUNC_NEVER) {