mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 12:01:04 +00:00
Skip pass-thru tev stages, upper_bound calc once
This commit is contained in:
parent
dfc807daf9
commit
863edeefe0
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user