GS/HW: Extend blend second pass to more blend formulas v2.

Cd*(1 + Alpha).
Alpha = As, Ad or Af.
For As or Af case when alpha > 128.
For Ad case when there is no RTA correction.
This commit is contained in:
lightningterror 2024-06-02 12:25:00 +02:00
parent 480bd2da4b
commit abec2738b9
4 changed files with 37 additions and 8 deletions

View File

@ -976,8 +976,10 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)
}
else if (PS_BLEND_HW == 4)
{
// Needed for Cd * (1 - Ad)
Color.rgb = (float3)128.0f;
// Needed for Cd * (1 - Ad) and Cd*(1 + Alpha)
float Alpha = PS_BLEND_C == 2 ? Af : As;
As_rgba.rgb = (float3)Alpha * (float3)(128.0f / 255.0f);
Color.rgb = (float3)127.5f;
}
}
}

View File

@ -936,8 +936,15 @@ float As = As_rgba.a;
float color_compensate = 255.0f / max(128.0f, max_color);
Color.rgb *= vec3(color_compensate);
#elif PS_BLEND_HW == 4
// Needed for Cd * (1 - Ad)
Color.rgb = vec3(128.0f);
// Needed for Cd * (1 - Ad) and Cd*(1 + Alpha)
#if PS_BLEND_C == 2
float Alpha = Af;
#else
float Alpha = As;
#endif
As_rgba.rgb = vec3(Alpha) * vec3(128.0f / 255.0f);
Color.rgb = vec3(127.5f);
#endif
#endif

View File

@ -1203,8 +1203,16 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba)
float color_compensate = 255.0f / max(128.0f, max_color);
Color.rgb *= vec3(color_compensate);
#elif PS_BLEND_HW == 4
// Needed for Cd * (1 - Ad)
Color.rgb = vec3(128.0f);
// Needed for Cd * (1 - Ad) and Cd*(1 + Alpha)
#if PS_BLEND_C == 2
float Alpha = Af;
#else
float Alpha = As;
#endif
As_rgba.rgb = vec3(Alpha) * vec3(128.0f / 255.0f);
Color.rgb = vec3(127.5f);
#endif
#endif
}

View File

@ -4496,6 +4496,18 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
m_conf.blend_second_pass.blend_hw = 2;
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, (m_conf.ps.blend_c == 2) ? GSDevice::CONST_COLOR : GSDevice::SRC1_COLOR, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, m_conf.ps.blend_c == 2, AFIX};
}
else if ((alpha_c0_high_max_one || alpha_c1_high_no_rta_correct || alpha_c2_high_one) && (blend_flag & BLEND_HW1))
{
// Alpha = As, Ad or Af.
// Cd*(1 + Alpha).
// Render pass 1: Do Cd*(1 + Alpha) with a half result in the end.
m_conf.ps.blend_hw = 4;
blend.dst = (m_conf.ps.blend_c == 1) ? GSDevice::DST_ALPHA : GSDevice::SRC1_COLOR;
// Render pass 2: Take result (Cd) from render pass 1 and double it.
m_conf.blend_second_pass.enable = true;
m_conf.blend_second_pass.blend_hw = 1;
m_conf.blend_second_pass.blend = {true, blend_second_pass.src, GSDevice::CONST_ONE, blend_second_pass.op, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
}
else if (alpha_c1_high_no_rta_correct && (blend_flag & BLEND_HW3))
{
// Alpha = Ad.
@ -4580,7 +4592,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
}
}
if (blend_flag & BLEND_HW1)
if (!m_conf.blend_second_pass.enable && blend_flag & BLEND_HW1)
{
m_conf.ps.blend_hw = 1;
}
@ -4593,7 +4605,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
m_conf.ps.blend_hw = 3;
}
if (m_conf.ps.blend_c == 2 && (m_conf.ps.blend_hw == 2 || m_conf.blend_second_pass.blend_hw == 2))
if (m_conf.ps.blend_c == 2 && (m_conf.ps.blend_hw == 2 || m_conf.ps.blend_hw == 4 || m_conf.blend_second_pass.blend_hw == 2))
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(AFIX) / 128.0f;
const GSDevice::BlendFactor src_factor_alpha = m_conf.blend_second_pass.enable ? GSDevice::CONST_ZERO : GSDevice::CONST_ONE;