mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Improve float precision of blend second pass.
This commit is contained in:
parent
47606400fa
commit
09f3a6bb73
|
@ -982,6 +982,16 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)
|
||||||
As_rgba.rgb = (float3)Alpha * (float3)(128.0f / 255.0f);
|
As_rgba.rgb = (float3)Alpha * (float3)(128.0f / 255.0f);
|
||||||
Color.rgb = (float3)127.5f;
|
Color.rgb = (float3)127.5f;
|
||||||
}
|
}
|
||||||
|
else if (PS_BLEND_HW == 5)
|
||||||
|
{
|
||||||
|
// Needed for Cs*Ad, Cs*Ad + Cd, Cd - Cs*Ad.
|
||||||
|
Color.rgb = max(Color.rgb - (Color.rgb / (float3)128.0f), (float3)0.0f);
|
||||||
|
}
|
||||||
|
else if (PS_BLEND_HW == 6)
|
||||||
|
{
|
||||||
|
// Needed for Cd*Ad - Cs*Ad, Cs*Ad - Cd*Ad.
|
||||||
|
Color.rgb = (float3)253.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -937,6 +937,12 @@ float As = As_rgba.a;
|
||||||
#endif
|
#endif
|
||||||
As_rgba.rgb = vec3(Alpha) * vec3(128.0f / 255.0f);
|
As_rgba.rgb = vec3(Alpha) * vec3(128.0f / 255.0f);
|
||||||
Color.rgb = vec3(127.5f);
|
Color.rgb = vec3(127.5f);
|
||||||
|
#elif PS_BLEND_HW == 5
|
||||||
|
// Needed for Cs*Ad, Cs*Ad + Cd, Cd - Cs*Ad.
|
||||||
|
Color.rgb = max(Color.rgb - (Color.rgb / vec3(128.0f)), vec3(0.0f));
|
||||||
|
#elif PS_BLEND_HW == 6
|
||||||
|
// Needed for Cd*Ad - Cs*Ad, Cs*Ad - Cd*Ad.
|
||||||
|
Color.rgb = vec3(253.0f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1205,6 +1205,12 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba)
|
||||||
|
|
||||||
As_rgba.rgb = vec3(Alpha) * vec3(128.0f / 255.0f);
|
As_rgba.rgb = vec3(Alpha) * vec3(128.0f / 255.0f);
|
||||||
Color.rgb = vec3(127.5f);
|
Color.rgb = vec3(127.5f);
|
||||||
|
#elif PS_BLEND_HW == 5
|
||||||
|
// Needed for Cs*Ad, Cs*Ad + Cd, Cd - Cs*Ad.
|
||||||
|
Color.rgb = max(Color.rgb - (Color.rgb / vec3(128.0f)), vec3(0.0f));
|
||||||
|
#elif PS_BLEND_HW == 6
|
||||||
|
// Needed for Cd*Ad - Cs*Ad, Cs*Ad - Cd*Ad.
|
||||||
|
Color.rgb = vec3(253.0f);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,10 +172,12 @@ enum ChannelFetch
|
||||||
|
|
||||||
enum class HWBlendType
|
enum class HWBlendType
|
||||||
{
|
{
|
||||||
SRC_ONE_DST_FACTOR = 1, // Use the dest color as blend factor, Cs is set to 1.
|
SRC_ONE_DST_FACTOR1 = 1, // Use the dest color as blend factor, Cs is set to 1.
|
||||||
SRC_ALPHA_DST_FACTOR = 2, // Use the dest color as blend factor, Cs is set to (Alpha - 1).
|
SRC_ALPHA_DST_FACTOR = 2, // Use the dest color as blend factor, Cs is set to (Alpha - 1).
|
||||||
SRC_DOUBLE = 3, // Double source color.
|
SRC_DOUBLE = 3, // Double source color.
|
||||||
SRC_HALF_ONE_DST_FACTOR = 4, // Use the dest color as blend factor, Cs is set to 0.5, additionally divide As or Af by 2.
|
SRC_HALF_ONE_DST_FACTOR = 4, // Use the dest color as blend factor, Cs is set to 0.5, additionally divide As or Af by 2.
|
||||||
|
SRC_FLOAT_PRECISION = 5, // Adjust Cs by a small amount to compensate for float precision loss.
|
||||||
|
SRC_ONE_DST_FACTOR2 = 6, // Use the dest color as blend factor, Cs is set to 0.9921875 instead of 1 for float precision loss.
|
||||||
|
|
||||||
BMIX1_ALPHA_HIGH_ONE = 1, // Blend formula is replaced when alpha is higher than 1.
|
BMIX1_ALPHA_HIGH_ONE = 1, // Blend formula is replaced when alpha is higher than 1.
|
||||||
BMIX1_SRC_HALF = 2, // Impossible blend will always be wrong on hw, divide Cs by 2.
|
BMIX1_SRC_HALF = 2, // Impossible blend will always be wrong on hw, divide Cs by 2.
|
||||||
|
|
|
@ -4643,7 +4643,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
blend.dst = (m_conf.ps.blend_c == 1) ? GSDevice::DST_ALPHA : GSDevice::SRC1_COLOR;
|
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.
|
// 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.enable = true;
|
||||||
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR);
|
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR1);
|
||||||
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};
|
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))
|
else if (alpha_c1_high_no_rta_correct && (blend_flag & BLEND_HW3))
|
||||||
|
@ -4653,6 +4653,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
// Render pass 1: Do Cs*Alpha, Cs*Alpha + Cd or Cd - Cs*Alpha on first pass.
|
// Render pass 1: Do Cs*Alpha, Cs*Alpha + Cd or Cd - Cs*Alpha on first pass.
|
||||||
// Render pass 2: Take result (Cd) from render pass 1 and either add or rev subtract Cs*Alpha based on the blend operation.
|
// Render pass 2: Take result (Cd) from render pass 1 and either add or rev subtract Cs*Alpha based on the blend operation.
|
||||||
m_conf.blend_second_pass.enable = true;
|
m_conf.blend_second_pass.enable = true;
|
||||||
|
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_FLOAT_PRECISION);
|
||||||
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};
|
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_c0_high_max_one || alpha_c2_high_one) && (blend_flag & BLEND_HW4))
|
else if ((alpha_c0_high_max_one || alpha_c2_high_one) && (blend_flag & BLEND_HW4))
|
||||||
|
@ -4679,7 +4680,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
// Render pass 1: Do (Cd - Cs)*Alpha, (Cs - Cd)*Alpha or Cd*Alpha on first pass.
|
// Render pass 1: Do (Cd - Cs)*Alpha, (Cs - Cd)*Alpha or Cd*Alpha on first pass.
|
||||||
// Render pass 2: Take result (Cd) from render pass 1 and double it.
|
// 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.enable = true;
|
||||||
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR);
|
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR2);
|
||||||
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, GSDevice::CONST_ONE, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, GSDevice::CONST_ONE, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
||||||
}
|
}
|
||||||
else if (alpha_c1_high_no_rta_correct && (blend_flag & BLEND_HW6))
|
else if (alpha_c1_high_no_rta_correct && (blend_flag & BLEND_HW6))
|
||||||
|
@ -4692,7 +4693,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
blend.src = GSDevice::CONST_COLOR;
|
blend.src = GSDevice::CONST_COLOR;
|
||||||
// Render pass 2: Take result (Cd) from render pass 1 and double it.
|
// 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.enable = true;
|
||||||
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR);
|
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR1);
|
||||||
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, GSDevice::CONST_ONE, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, GSDevice::CONST_ONE, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
||||||
}
|
}
|
||||||
else if (alpha_c1_high_no_rta_correct && (blend_flag & BLEND_HW7))
|
else if (alpha_c1_high_no_rta_correct && (blend_flag & BLEND_HW7))
|
||||||
|
@ -4706,7 +4707,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
blend.op = GSDevice::OP_SUBTRACT;
|
blend.op = GSDevice::OP_SUBTRACT;
|
||||||
// Render pass 2: Take result (Cd) from render pass 1 and double it.
|
// 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.enable = true;
|
||||||
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR);
|
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR1);
|
||||||
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, GSDevice::CONST_ONE, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
m_conf.blend_second_pass.blend = {true, GSDevice::DST_COLOR, GSDevice::CONST_ONE, GSDevice::OP_ADD, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
||||||
}
|
}
|
||||||
else if (blend_flag & BLEND_HW8)
|
else if (blend_flag & BLEND_HW8)
|
||||||
|
@ -4726,13 +4727,14 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
// Render pass 1: Do Cs*(1 - Alpha).
|
// Render pass 1: Do Cs*(1 - Alpha).
|
||||||
// Render pass 2: Take result (Cd) from render pass 1 and subtract Cs*Alpha from it.
|
// Render pass 2: Take result (Cd) from render pass 1 and subtract Cs*Alpha from it.
|
||||||
m_conf.blend_second_pass.enable = true;
|
m_conf.blend_second_pass.enable = true;
|
||||||
|
m_conf.blend_second_pass.blend_hw = static_cast<u8>(HWBlendType::SRC_FLOAT_PRECISION);
|
||||||
m_conf.blend_second_pass.blend = {true, GSDevice::DST_ALPHA, GSDevice::CONST_ONE, GSDevice::OP_REV_SUBTRACT, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
m_conf.blend_second_pass.blend = {true, GSDevice::DST_ALPHA, GSDevice::CONST_ONE, GSDevice::OP_REV_SUBTRACT, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_conf.blend_second_pass.enable && blend_flag & BLEND_HW1)
|
if (!m_conf.blend_second_pass.enable && blend_flag & BLEND_HW1)
|
||||||
{
|
{
|
||||||
m_conf.ps.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR);
|
m_conf.ps.blend_hw = static_cast<u8>(HWBlendType::SRC_ONE_DST_FACTOR1);
|
||||||
}
|
}
|
||||||
else if (blend_flag & BLEND_HW2)
|
else if (blend_flag & BLEND_HW2)
|
||||||
{
|
{
|
||||||
|
@ -4743,7 +4745,9 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||||
m_conf.ps.blend_hw = static_cast<u8>(HWBlendType::SRC_DOUBLE);
|
m_conf.ps.blend_hw = static_cast<u8>(HWBlendType::SRC_DOUBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
if (m_conf.ps.blend_c == 2 && (m_conf.ps.blend_hw == static_cast<u8>(HWBlendType::SRC_ALPHA_DST_FACTOR) ||
|
||||||
|
m_conf.ps.blend_hw == static_cast<u8>(HWBlendType::SRC_HALF_ONE_DST_FACTOR) ||
|
||||||
|
m_conf.blend_second_pass.blend_hw == static_cast<u8>(HWBlendType::SRC_ALPHA_DST_FACTOR)))
|
||||||
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(AFIX) / 128.0f;
|
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;
|
const GSDevice::BlendFactor src_factor_alpha = m_conf.blend_second_pass.enable ? GSDevice::CONST_ZERO : GSDevice::CONST_ONE;
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
|
|
||||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||||
/// shaders change, to invalidate the cache.
|
/// shaders change, to invalidate the cache.
|
||||||
static constexpr u32 SHADER_CACHE_VERSION = 53;
|
static constexpr u32 SHADER_CACHE_VERSION = 54;
|
||||||
|
|
Loading…
Reference in New Issue