From ad4f13d92d3e7bd17e05794c6bcd9be2c745131d Mon Sep 17 00:00:00 2001 From: lightningterror <18107717+lightningterror@users.noreply.github.com> Date: Fri, 13 Sep 2024 06:46:21 +0200 Subject: [PATCH] GS/HW: Reduce sw/hdr colclip in more cases. When doing `Cs*alpha + Cd*(1 - Alpha)` or `Cd*As + Cs*(1 - As)` with an alpha of 128 or lower we don't really need to hdr or sw colclip blend it because color range of the result will be betwee 0-1 (0-255) without it overflowing. Also update previous optimizations to include Ad cases when RTA is already scaled. --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 2563f239a6dac7..6344368782add2 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -4149,6 +4149,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo const bool alpha_c0_eq_less_max_one = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().max <= 128); const bool alpha_c1_high_min_one = (m_conf.ps.blend_c == 1 && rt_alpha_min > 128); const bool alpha_c1_high_max_one = (m_conf.ps.blend_c == 1 && rt_alpha_max > 128); + const bool alpha_c1_eq_less_max_one = (m_conf.ps.blend_c == 1 && rt_alpha_max <= 128); bool alpha_c1_high_no_rta_correct = m_conf.ps.blend_c == 1 && !(new_rt_alpha_scale || can_scale_rt_alpha); const bool alpha_c2_eq_zero = (m_conf.ps.blend_c == 2 && AFIX == 0u); const bool alpha_c2_eq_one = (m_conf.ps.blend_c == 2 && AFIX == 128u); @@ -4233,8 +4234,12 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo // HW blend can handle Cd output. bool color_dest_blend = !!(blend_flag & BLEND_CD); - // HW blend can handle it, no need for sw blend or hdr, Cd*Alpha or Cd*(1 - Alpha) where Alpha <= 128, Alpha is As or Af. - bool color_dest_blend2 = alpha_eq_less_one && ((blend_flag & BLEND_HW2) || (m_conf.ps.blend_b == m_conf.ps.blend_d == 1 && m_conf.ps.blend_a == 2)); + // HW blend can handle it, no need for sw or hdr colclip, Cd*Alpha or Cd*(1 - Alpha) where Alpha <= 128. + bool color_dest_blend2 = !m_draw_env->PABE.PABE && ((m_conf.ps.blend_a == 1 && m_conf.ps.blend_b == 2 && m_conf.ps.blend_d == 2) || ((m_conf.ps.blend_b == m_conf.ps.blend_d == 1) && m_conf.ps.blend_a == 2)) && + (alpha_eq_less_one || (alpha_c1_eq_less_max_one && new_rt_alpha_scale)); + // HW blend can handle it, no need for sw or hdr colclip, Cs*Alpha + Cd*(1 - Alpha) or Cd*Alpha + Cs*(1 - Alpha) where Alpha <= 128. + bool blend_zero_to_one_range = !m_draw_env->PABE.PABE && (((m_conf.ps.blend_b == m_conf.ps.blend_d == 1) && m_conf.ps.blend_a == 0) || (blend_flag & BLEND_MIX3)) && + (alpha_eq_less_one || (alpha_c1_eq_less_max_one && new_rt_alpha_scale)); // Do the multiplication in shader for blending accumulation: Cs*As + Cd or Cs*Af + Cd bool accumulation_blend = !!(blend_flag & BLEND_ACCU); @@ -4311,6 +4316,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo // Prefer sw blend if possible. color_dest_blend &= !prefer_sw_blend; color_dest_blend2 &= !prefer_sw_blend; + blend_zero_to_one_range &= !prefer_sw_blend; accumulation_blend &= !prefer_sw_blend; // Enable sw blending for barriers. sw_blending |= blend_requires_barrier; @@ -4351,6 +4357,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo // Prefer sw blend if possible. color_dest_blend &= !prefer_sw_blend; color_dest_blend2 &= !prefer_sw_blend; + blend_zero_to_one_range &= !prefer_sw_blend; accumulation_blend &= !prefer_sw_blend; // Enable sw blending for reading fb. sw_blending |= prefer_sw_blend; @@ -4384,7 +4391,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo const bool free_colclip = features.framebuffer_fetch || no_prim_overlap || blend_non_recursive; GL_DBG("COLCLIP Info (Blending: %u/%u/%u/%u, OVERLAP: %d)", m_conf.ps.blend_a, m_conf.ps.blend_b, m_conf.ps.blend_c, m_conf.ps.blend_d, m_prim_overlap); - if (color_dest_blend || color_dest_blend2) + if (color_dest_blend || color_dest_blend2 || blend_zero_to_one_range) { // No overflow, disable colclip. GL_INS("COLCLIP mode DISABLED");