mirror of https://github.com/PCSX2/pcsx2.git
GS: Use accumulation blend when alpha is known to be 1
This commit is contained in:
parent
9150e69783
commit
e89612e5b9
|
@ -2504,9 +2504,10 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
|||
const bool alpha_c2_zero = (m_conf.ps.blend_c == 2 && ALPHA.FIX == 0u);
|
||||
const bool alpha_c2_one = (m_conf.ps.blend_c == 2 && ALPHA.FIX == 128u);
|
||||
const bool alpha_c2_high_one = (m_conf.ps.blend_c == 2 && ALPHA.FIX > 128u);
|
||||
const bool alpha_one = alpha_c0_one || alpha_c2_one;
|
||||
|
||||
// Optimize blending equations, must be done before index calculation
|
||||
if ((m_conf.ps.blend_a == m_conf.ps.blend_b) || ((m_conf.ps.blend_b == m_conf.ps.blend_d) && (alpha_c0_one || alpha_c2_one)))
|
||||
if ((m_conf.ps.blend_a == m_conf.ps.blend_b) || ((m_conf.ps.blend_b == m_conf.ps.blend_d) && alpha_one))
|
||||
{
|
||||
// Condition 1:
|
||||
// A == B
|
||||
|
@ -2546,7 +2547,8 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
|||
blend_ad_alpha_masked = false;
|
||||
|
||||
u8 blend_index = u8(((m_conf.ps.blend_a * 3 + m_conf.ps.blend_b) * 3 + m_conf.ps.blend_c) * 3 + m_conf.ps.blend_d);
|
||||
const int blend_flag = GSDevice::GetBlendFlags(blend_index);
|
||||
const HWBlend blend_preliminary = GSDevice::GetBlend(blend_index, false);
|
||||
const int blend_flag = blend_preliminary.flags;
|
||||
|
||||
// Re set alpha, it was modified, must be done after index calculation
|
||||
if (blend_ad_alpha_masked)
|
||||
|
@ -2557,6 +2559,11 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
|||
|
||||
// Do the multiplication in shader for blending accumulation: Cs*As + Cd or Cs*Af + Cd
|
||||
bool accumulation_blend = !!(blend_flag & BLEND_ACCU);
|
||||
// If alpha == 1.0, almost everything is an accumulation blend!
|
||||
// Ones that use (1 + Alpha) can't guarante the mixed sw+hw blending this enables will give an identical result to sw due to clamping
|
||||
// But enable for everything else that involves dst color
|
||||
if (alpha_one && (m_conf.ps.blend_a != m_conf.ps.blend_d) && blend_preliminary.dst != GSDevice::CONST_ZERO)
|
||||
accumulation_blend = true;
|
||||
|
||||
// Blending doesn't require barrier, or sampling of the rt
|
||||
const bool blend_non_recursive = !!(blend_flag & BLEND_NO_REC);
|
||||
|
@ -2832,6 +2839,23 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
|||
{
|
||||
// Keep HW blending to do the addition/subtraction
|
||||
m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::CONST_ONE, blend.op, false, 0};
|
||||
// Remove Cd from sw blend, it's handled in hw
|
||||
if (m_conf.ps.blend_a == 1)
|
||||
m_conf.ps.blend_a = 2;
|
||||
if (m_conf.ps.blend_b == 1)
|
||||
m_conf.ps.blend_b = 2;
|
||||
if (m_conf.ps.blend_d == 1)
|
||||
m_conf.ps.blend_d = 2;
|
||||
|
||||
if (m_conf.ps.blend_a == 2)
|
||||
{
|
||||
// Accumulation blend is only available in (Cs - 0)*Something + Cd, or with alpha == 1
|
||||
ASSERT(m_conf.ps.blend_d == 2 || alpha_one);
|
||||
// A bit of normalization
|
||||
m_conf.ps.blend_a = m_conf.ps.blend_d;
|
||||
m_conf.ps.blend_d = 2;
|
||||
}
|
||||
|
||||
if (m_conf.ps.blend_a == 2)
|
||||
{
|
||||
// The blend unit does a reverse subtraction so it means
|
||||
|
@ -2840,8 +2864,6 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
|||
m_conf.ps.blend_a = m_conf.ps.blend_b;
|
||||
m_conf.ps.blend_b = 2;
|
||||
}
|
||||
// Remove the addition/substraction from the SW blending
|
||||
m_conf.ps.blend_d = 2;
|
||||
|
||||
// Dual source output not needed (accumulation blend replaces it with ONE).
|
||||
m_conf.ps.no_color1 = true;
|
||||
|
|
Loading…
Reference in New Issue