mirror of https://github.com/PCSX2/pcsx2.git
GS-hw: Improve how we handle blending on 24bit with Ad factor in renderer.
This commit is contained in:
parent
e89612e5b9
commit
edc82d77a5
|
@ -66,6 +66,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
|
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
|
||||||
|
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
|
||||||
|
|
||||||
struct VS_INPUT
|
struct VS_INPUT
|
||||||
{
|
{
|
||||||
|
@ -762,9 +763,9 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 RT = trunc(RtTexture.Load(int3(pos_xy, 0)) * 255.0f + 0.1f);
|
float4 RT = SW_BLEND_NEEDS_RT ? trunc(RtTexture.Load(int3(pos_xy, 0)) * 255.0f + 0.1f) : (float4)0.0f;
|
||||||
|
|
||||||
float Ad = (PS_DFMT == FMT_24) ? 1.0f : RT.a / 128.0f;
|
float Ad = RT.a / 128.0f;
|
||||||
|
|
||||||
float3 Cd = RT.rgb;
|
float3 Cd = RT.rgb;
|
||||||
float3 Cs = Color.rgb;
|
float3 Cs = Color.rgb;
|
||||||
|
|
|
@ -709,13 +709,9 @@ void ps_blend(inout vec4 Color, inout float As)
|
||||||
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
|
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PS_DFMT == FMT_24
|
|
||||||
float Ad = 1.0f;
|
|
||||||
#else
|
|
||||||
// FIXME FMT_16 case
|
// FIXME FMT_16 case
|
||||||
// FIXME Ad or Ad * 2?
|
// FIXME Ad or Ad * 2?
|
||||||
float Ad = RT.a / 128.0f;
|
float Ad = RT.a / 128.0f;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Let the compiler do its jobs !
|
// Let the compiler do its jobs !
|
||||||
vec3 Cd = RT.rgb;
|
vec3 Cd = RT.rgb;
|
||||||
|
|
|
@ -1008,13 +1008,9 @@ void ps_blend(inout vec4 Color, inout float As)
|
||||||
vec4 RT = vec4(0.0f);
|
vec4 RT = vec4(0.0f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PS_DFMT == FMT_24
|
|
||||||
float Ad = 1.0f;
|
|
||||||
#else
|
|
||||||
// FIXME FMT_16 case
|
// FIXME FMT_16 case
|
||||||
// FIXME Ad or Ad * 2?
|
// FIXME Ad or Ad * 2?
|
||||||
float Ad = RT.a / 128.0f;
|
float Ad = RT.a / 128.0f;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Let the compiler do its jobs !
|
// Let the compiler do its jobs !
|
||||||
vec3 Cd = RT.rgb;
|
vec3 Cd = RT.rgb;
|
||||||
|
|
|
@ -2481,6 +2481,8 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
||||||
// Compute the blending equation to detect special case
|
// Compute the blending equation to detect special case
|
||||||
const GSDevice::FeatureSupport features(g_gs_device->Features());
|
const GSDevice::FeatureSupport features(g_gs_device->Features());
|
||||||
const GIFRegALPHA& ALPHA = m_context->ALPHA;
|
const GIFRegALPHA& ALPHA = m_context->ALPHA;
|
||||||
|
// AFIX: Afix factor.
|
||||||
|
u8 AFIX = ALPHA.FIX;
|
||||||
|
|
||||||
// Set blending to shader bits
|
// Set blending to shader bits
|
||||||
m_conf.ps.blend_a = ALPHA.A;
|
m_conf.ps.blend_a = ALPHA.A;
|
||||||
|
@ -2495,15 +2497,21 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
||||||
m_conf.ps.fixed_one_a = 1;
|
m_conf.ps.fixed_one_a = 1;
|
||||||
m_conf.ps.blend_c = 0;
|
m_conf.ps.blend_c = 0;
|
||||||
}
|
}
|
||||||
|
// 24 bits doesn't have an alpha channel so use 128 (1.0f) fix factor as equivalent.
|
||||||
|
else if (m_conf.ps.dfmt == 1 && m_conf.ps.blend_c == 1)
|
||||||
|
{
|
||||||
|
AFIX = 128;
|
||||||
|
m_conf.ps.blend_c = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Get alpha value
|
// Get alpha value
|
||||||
const bool alpha_c0_zero = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().max == 0) && !IsCoverageAlpha();
|
const bool alpha_c0_zero = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().max == 0) && !IsCoverageAlpha();
|
||||||
const bool alpha_c0_one = (m_conf.ps.blend_c == 0 && (GetAlphaMinMax().min == 128) && (GetAlphaMinMax().max == 128)) || IsCoverageAlpha();
|
const bool alpha_c0_one = (m_conf.ps.blend_c == 0 && (GetAlphaMinMax().min == 128) && (GetAlphaMinMax().max == 128)) || IsCoverageAlpha();
|
||||||
const bool alpha_c0_high_min_one = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().min > 128) && !IsCoverageAlpha();
|
const bool alpha_c0_high_min_one = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().min > 128) && !IsCoverageAlpha();
|
||||||
const bool alpha_c0_high_max_one = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().max > 128) && !IsCoverageAlpha();
|
const bool alpha_c0_high_max_one = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().max > 128) && !IsCoverageAlpha();
|
||||||
const bool alpha_c2_zero = (m_conf.ps.blend_c == 2 && ALPHA.FIX == 0u);
|
const bool alpha_c2_zero = (m_conf.ps.blend_c == 2 && AFIX == 0u);
|
||||||
const bool alpha_c2_one = (m_conf.ps.blend_c == 2 && ALPHA.FIX == 128u);
|
const bool alpha_c2_one = (m_conf.ps.blend_c == 2 && AFIX == 128u);
|
||||||
const bool alpha_c2_high_one = (m_conf.ps.blend_c == 2 && ALPHA.FIX > 128u);
|
const bool alpha_c2_high_one = (m_conf.ps.blend_c == 2 && AFIX > 128u);
|
||||||
const bool alpha_one = alpha_c0_one || alpha_c2_one;
|
const bool alpha_one = alpha_c0_one || alpha_c2_one;
|
||||||
|
|
||||||
// Optimize blending equations, must be done before index calculation
|
// Optimize blending equations, must be done before index calculation
|
||||||
|
@ -2832,7 +2840,7 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
||||||
{
|
{
|
||||||
// Require the fix alpha vlaue
|
// Require the fix alpha vlaue
|
||||||
if (m_conf.ps.blend_c == 2)
|
if (m_conf.ps.blend_c == 2)
|
||||||
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(ALPHA.FIX) / 128.0f;
|
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(AFIX) / 128.0f;
|
||||||
|
|
||||||
const HWBlend blend = GSDevice::GetBlend(blend_index, replace_dual_src);
|
const HWBlend blend = GSDevice::GetBlend(blend_index, replace_dual_src);
|
||||||
if (accumulation_blend)
|
if (accumulation_blend)
|
||||||
|
@ -2874,7 +2882,7 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
||||||
else if (blend_mix)
|
else if (blend_mix)
|
||||||
{
|
{
|
||||||
// For mixed blend, the source blend is done in the shader (so we use CONST_ONE as a factor).
|
// For mixed blend, the source blend is done in the shader (so we use CONST_ONE as a factor).
|
||||||
m_conf.blend = {true, GSDevice::CONST_ONE, blend.dst, blend.op, m_conf.ps.blend_c == 2, ALPHA.FIX};
|
m_conf.blend = {true, GSDevice::CONST_ONE, blend.dst, blend.op, m_conf.ps.blend_c == 2, AFIX};
|
||||||
m_conf.ps.blend_mix = (blend.op == GSDevice::OP_REV_SUBTRACT) ? 2 : 1;
|
m_conf.ps.blend_mix = (blend.op == GSDevice::OP_REV_SUBTRACT) ? 2 : 1;
|
||||||
|
|
||||||
// Elide DSB colour output if not used by dest.
|
// Elide DSB colour output if not used by dest.
|
||||||
|
@ -2970,7 +2978,7 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
||||||
else if (m_conf.ps.blend_c == 2)
|
else if (m_conf.ps.blend_c == 2)
|
||||||
{
|
{
|
||||||
m_conf.ps.blend_c = 2;
|
m_conf.ps.blend_c = 2;
|
||||||
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(ALPHA.FIX) / 128.0f;
|
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(AFIX) / 128.0f;
|
||||||
m_conf.ps.clr_hw = 2;
|
m_conf.ps.clr_hw = 2;
|
||||||
}
|
}
|
||||||
else // m_conf.ps.blend_c == 0
|
else // m_conf.ps.blend_c == 0
|
||||||
|
@ -2989,18 +2997,8 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
|
||||||
m_conf.ps.clr_hw = 6;
|
m_conf.ps.clr_hw = 6;
|
||||||
m_conf.require_one_barrier |= true;
|
m_conf.require_one_barrier |= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_conf.ps.dfmt == 1 && m_conf.ps.blend_c == 1)
|
|
||||||
{
|
|
||||||
// 24 bits doesn't have an alpha channel so use 1.0f fix factor as equivalent
|
|
||||||
const HWBlend blend(GSDevice::GetBlend(blend_index + 3, replace_dual_src)); // +3 <=> +1 on C
|
|
||||||
m_conf.blend = {true, blend.src, blend.dst, blend.op, true, 128};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const HWBlend blend(GSDevice::GetBlend(blend_index, replace_dual_src));
|
const HWBlend blend(GSDevice::GetBlend(blend_index, replace_dual_src));
|
||||||
m_conf.blend = {true, blend.src, blend.dst, blend.op, m_conf.ps.blend_c == 2, ALPHA.FIX};
|
m_conf.blend = {true, blend.src, blend.dst, blend.op, m_conf.ps.blend_c == 2, AFIX};
|
||||||
}
|
|
||||||
|
|
||||||
// Remove second color output when unused. Works around bugs in some drivers (e.g. Intel).
|
// Remove second color output when unused. Works around bugs in some drivers (e.g. Intel).
|
||||||
m_conf.ps.no_color1 |= !GSDevice::IsDualSourceBlendFactor(m_conf.blend.src_factor) &&
|
m_conf.ps.no_color1 |= !GSDevice::IsDualSourceBlendFactor(m_conf.blend.src_factor) &&
|
||||||
|
|
|
@ -823,7 +823,7 @@ struct PSMain
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Ad = PS_DFMT == FMT_24 ? 1.f : trunc(current_color.a * 255.5f) / 128.f;
|
float Ad = trunc(current_color.a * 255.5f) / 128.f;
|
||||||
|
|
||||||
float3 Cd = trunc(current_color.rgb * 255.5f);
|
float3 Cd = trunc(current_color.rgb * 255.5f);
|
||||||
float3 Cs = Color.rgb;
|
float3 Cs = Color.rgb;
|
||||||
|
|
Loading…
Reference in New Issue