GS: Redo GetAlphaMinMax.

Cleaner this way, also fix recent regression on Full Blend with alpha max.
This commit is contained in:
lightningterror 2021-12-21 01:45:37 +01:00
parent f4b38662fa
commit bf8dc05fac
3 changed files with 23 additions and 24 deletions

View File

@ -2736,7 +2736,7 @@ void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFR
r = vr;
}
void GSState::GetAlphaMinMax()
void GSState::CalcAlphaMinMax()
{
if (m_vt.m_alpha.valid)
return;
@ -2841,12 +2841,10 @@ bool GSState::TryAlphaTest(u32& fm, u32& zm)
}
else
{
GetAlphaMinMax();
const int amin = GetAlphaMinMax().min;
const int amax = GetAlphaMinMax().max;
int amin = m_vt.m_alpha.min;
int amax = m_vt.m_alpha.max;
int aref = m_context->TEST.AREF;
const int aref = m_context->TEST.AREF;
switch (m_context->TEST.ATST)
{
@ -2951,10 +2949,8 @@ bool GSState::IsOpaque()
{
if (context->ALPHA.C == 0)
{
GetAlphaMinMax();
amin = m_vt.m_alpha.min;
amax = m_vt.m_alpha.max;
amin = GetAlphaMinMax().min;
amax = GetAlphaMinMax().max;
}
else if (context->ALPHA.C == 1)
{

View File

@ -139,6 +139,9 @@ class GSState : public GSAlignedClass<32>
} m_tr;
private:
void CalcAlphaMinMax();
protected:
bool IsBadFrame();
void SetupCrcHack();
@ -186,9 +189,13 @@ protected:
// following functions need m_vt to be initialized
GSVertexTrace m_vt;
GSVertexTrace::VertexAlpha& GetAlphaMinMax()
{
if (!m_vt.m_alpha.valid)
CalcAlphaMinMax();
return m_vt.m_alpha;
}
void GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear);
void GetAlphaMinMax();
bool TryAlphaTest(u32& fm, u32& zm);
bool IsOpaque();
bool IsMipMapDraw();

View File

@ -541,11 +541,8 @@ void GSRendererNew::EmulateBlending(bool& DATE_GL42, bool& DATE_GL45)
const bool blend_mix2 = !!(blend_flag & BLEND_MIX2);
const bool blend_mix3 = !!(blend_flag & BLEND_MIX3);
bool blend_mix = (blend_mix1 || blend_mix2 || blend_mix3);
// Checking alpha mix is costly, isolate it as an optimization.
if (!m_vt.m_alpha.valid && blend_mix && (ALPHA.C == 0))
GetAlphaMinMax();
// Do not enable if As > 128 or F > 128, hw blend clamps to 1
blend_mix &= !((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
blend_mix &= !((ALPHA.C == 0 && GetAlphaMinMax().max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
// SW Blend is (nearly) free. Let's use it.
const bool impossible_or_free_blend = (blend_flag & BLEND_A_MAX) // Impossible blending
@ -565,7 +562,7 @@ void GSRendererNew::EmulateBlending(bool& DATE_GL42, bool& DATE_GL45)
sw_blending |= true;
[[fallthrough]];
case AccBlendLevel::Full:
sw_blending |= (ALPHA.A != ALPHA.B) && ((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
sw_blending |= (ALPHA.A != ALPHA.B) && ((ALPHA.C == 0 && GetAlphaMinMax().max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
[[fallthrough]];
case AccBlendLevel::High:
sw_blending |= (ALPHA.C == 1);
@ -1237,24 +1234,23 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// Performance note: check alpha range with GetAlphaMinMax()
// Note: all my dump are already above 120fps, but it seems to reduce GPU load
// with big upscaling
GetAlphaMinMax();
if (m_context->TEST.DATM && m_vt.m_alpha.max < 128)
if (m_context->TEST.DATM && GetAlphaMinMax().max < 128)
{
// Only first pixel (write 0) will pass (alpha is 1)
GL_PERF("DATE: Fast with alpha %d-%d", m_vt.m_alpha.min, m_vt.m_alpha.max);
GL_PERF("DATE: Fast with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
DATE_one = true;
}
else if (!m_context->TEST.DATM && m_vt.m_alpha.min >= 128)
else if (!m_context->TEST.DATM && GetAlphaMinMax().min >= 128)
{
// Only first pixel (write 1) will pass (alpha is 0)
GL_PERF("DATE: Fast with alpha %d-%d", m_vt.m_alpha.min, m_vt.m_alpha.max);
GL_PERF("DATE: Fast with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
DATE_one = true;
}
else if ((m_vt.m_primclass == GS_SPRITE_CLASS && m_drawlist.size() < 50) || (m_index.tail < 100))
{
// texture barrier will split the draw call into n draw call. It is very efficient for
// few primitive draws. Otherwise it sucks.
GL_PERF("DATE: Slow with alpha %d-%d", m_vt.m_alpha.min, m_vt.m_alpha.max);
GL_PERF("DATE: Slow with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
if (m_dev->Features().texture_barrier)
{
m_conf.require_full_barrier = true;
@ -1264,7 +1260,7 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
else if (m_accurate_date)
{
// Note: Fast level (DATE_one) was removed as it's less accurate.
GL_PERF("DATE: Full AD with alpha %d-%d", m_vt.m_alpha.min, m_vt.m_alpha.max);
GL_PERF("DATE: Full AD with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
if (m_dev->Features().image_load_store)
{
DATE_GL42 = true;