GS/HW: Optimise usage of 24bit alphas

This commit is contained in:
refractionpcsx2 2023-08-01 12:27:12 +01:00
parent d812d83dda
commit 9c99a624d7
2 changed files with 48 additions and 22 deletions

View File

@ -3689,7 +3689,7 @@ void GSState::CalcAlphaMinMax(const int tex_alpha_min, const int tex_alpha_max)
return;
// We wanted to force an update as we now know the alpha of the non-indexed texture.
// Limit max to 255 as we send 500 when we don't know, makes calculating 16bit easier.
// Limit max to 255 as we send 500 when we don't know, makes calculating 24/16bit easier.
int min = tex_alpha_min, max = std::min(tex_alpha_max, 255);
if (IsCoverageAlpha())
@ -3712,12 +3712,14 @@ void GSState::CalcAlphaMinMax(const int tex_alpha_min, const int tex_alpha_max)
a.w = max;
break;
case 1:
a.y = env.TEXA.AEM ? 0 : env.TEXA.TA0;
a.w = env.TEXA.TA0;
// If we're using the alpha from the texture, not the whole range, we can just use tex_alpha_min/max.
// AEM and TA0 re precomputed with GSBlock::ReadAndExpandBlock24, so already worked out for tex_alpha.
a.y = (tex_alpha_max < 500) ? min : (env.TEXA.AEM ? 0 : env.TEXA.TA0);
a.w = (tex_alpha_max < 500) ? max : env.TEXA.TA0;
break;
case 2:
// If we're using the alpha from the texture, not the whole range, we can just use tex_alpha_min/max.
// TA0/TA1 is precomputed with GSBlock::ReadAndExpandBlock16, so already worked out for tex_alpha.
// AEM, TA0 and TA1 are precomputed with GSBlock::ReadAndExpandBlock16, so already worked out for tex_alpha.
a.y = (tex_alpha_max < 500) ? min : (env.TEXA.AEM ? 0 : std::min(env.TEXA.TA0, env.TEXA.TA1));
a.w = (tex_alpha_max < 500) ? max : std::max(env.TEXA.TA0, env.TEXA.TA1);
break;

View File

@ -3646,17 +3646,25 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_target = true;
src->m_from_target = dst;
src->m_from_target_TEX0 = dst->m_TEX0;
src->m_alpha_minmax.first = dst->m_alpha_min;
src->m_alpha_minmax.second = dst->m_alpha_max;
// This is a bit rough, since if AEM is on, without rescanning the whole texture, we don't know if anything is transparent, so just go the hard way.
if (!dst->m_32_bits_fmt)
if ((src->m_TEX0.PSM & 0xf) == PSMCT24)
{
const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128;
const bool using_ta1 = (src->m_alpha_minmax.second & 128);
src->m_alpha_minmax.first = TEXA.AEM ? 0 : TEXA.TA0;
src->m_alpha_minmax.second = TEXA.TA0;
}
else
{
src->m_alpha_minmax.first = dst->m_alpha_min;
src->m_alpha_minmax.second = dst->m_alpha_max;
src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
if (!dst->m_32_bits_fmt)
{
const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128;
const bool using_ta1 = (src->m_alpha_minmax.second & 128);
src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
}
}
if (psm.pal > 0)
@ -3698,17 +3706,25 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_from_target_TEX0 = dst->m_TEX0;
src->m_valid_rect = dst->m_valid;
src->m_end_block = dst->m_end_block;
src->m_alpha_minmax.first = dst->m_alpha_min;
src->m_alpha_minmax.second = dst->m_alpha_max;
// This is a bit rough, since if AEM is on, without rescanning the whole texture, we don't know if anything is transparent, so just go the hard way.
if (!dst->m_32_bits_fmt)
if ((src->m_TEX0.PSM & 0xf) == PSMCT24)
{
const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128;
const bool using_ta1 = (src->m_alpha_minmax.second & 128);
src->m_alpha_minmax.first = TEXA.AEM ? 0 : TEXA.TA0;
src->m_alpha_minmax.second = TEXA.TA0;
}
else
{
src->m_alpha_minmax.first = dst->m_alpha_min;
src->m_alpha_minmax.second = dst->m_alpha_max;
src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
if (!dst->m_32_bits_fmt)
{
const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128;
const bool using_ta1 = (src->m_alpha_minmax.second & 128);
src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0));
}
}
dst->Update();
@ -5210,8 +5226,16 @@ void GSTextureCache::Target::Update()
g_gs_device->DrawMultiStretchRects(drects, ndrects, m_texture, shader);
}
m_alpha_min = 0;
m_alpha_max = m_32_bits_fmt ? 255 : 128;
if ((m_TEX0.PSM & 0xf) == PSMCT24)
{
m_alpha_min = 128;
m_alpha_max = 128;
}
else
{
m_alpha_min = 0;
m_alpha_max = m_32_bits_fmt ? 255 : 128;
}
g_gs_device->Recycle(t);
m_dirty.clear();
}