diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index ed19e002a0..19a3236765 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -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) { diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index 9051079fcf..45f804efb7 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -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(); diff --git a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp index 49530534af..618bbf85f6 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp @@ -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;