mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Skip DATE/draw if not required
This commit is contained in:
parent
98eb3cb7f0
commit
d49323c7c4
|
@ -4718,7 +4718,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
#endif
|
||||
|
||||
const GSDrawingEnvironment& env = *m_draw_env;
|
||||
const bool DATE = m_cached_ctx.TEST.DATE && m_cached_ctx.FRAME.PSM != PSMCT24;
|
||||
bool DATE = m_cached_ctx.TEST.DATE && m_cached_ctx.FRAME.PSM != PSMCT24;
|
||||
bool DATE_PRIMID = false;
|
||||
bool DATE_BARRIER = false;
|
||||
bool DATE_one = false;
|
||||
|
@ -4755,7 +4755,115 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
|
||||
const GSDevice::FeatureSupport features = g_gs_device->Features();
|
||||
|
||||
// Blend
|
||||
int blend_alpha_min = 0, blend_alpha_max = 255;
|
||||
if (rt)
|
||||
{
|
||||
blend_alpha_min = rt->m_alpha_min;
|
||||
blend_alpha_max = rt->m_alpha_max;
|
||||
|
||||
const bool is_24_bit = (GSLocalMemory::m_psm[rt->m_TEX0.PSM].trbpp == 24);
|
||||
if (is_24_bit)
|
||||
{
|
||||
// C24/Z24 - alpha is 1.
|
||||
blend_alpha_min = 128;
|
||||
blend_alpha_max = 128;
|
||||
}
|
||||
|
||||
if (!m_channel_shuffle && !m_texture_shuffle)
|
||||
{
|
||||
const int fba_value = m_prev_env.CTXT[m_prev_env.PRIM.CTXT].FBA.FBA * 128;
|
||||
if ((m_cached_ctx.FRAME.FBMSK & 0xff000000) == 0)
|
||||
{
|
||||
if (rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(m_cached_ctx.TEST.DATE || m_cached_ctx.TEST.ATE || m_cached_ctx.TEST.ZTST != ZTST_ALWAYS))
|
||||
{
|
||||
rt->m_alpha_max = GetAlphaMinMax().max | fba_value;
|
||||
rt->m_alpha_min = GetAlphaMinMax().min | fba_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
rt->m_alpha_max = std::max(GetAlphaMinMax().max | fba_value, rt->m_alpha_max);
|
||||
rt->m_alpha_min = std::min(GetAlphaMinMax().min | fba_value, rt->m_alpha_min);
|
||||
}
|
||||
}
|
||||
else if ((m_cached_ctx.FRAME.FBMSK & 0xff000000) != 0xff000000) // We can't be sure of the alpha if it's partially masked.
|
||||
{
|
||||
rt->m_alpha_max |= std::max(GetAlphaMinMax().max | fba_value, rt->m_alpha_max);
|
||||
rt->m_alpha_min = std::min(GetAlphaMinMax().min | fba_value, rt->m_alpha_min);
|
||||
}
|
||||
else if (!is_24_bit)
|
||||
{
|
||||
// If both are zero then we probably don't know what the alpha is.
|
||||
if (rt->m_alpha_max == 0 && rt->m_alpha_min == 0)
|
||||
{
|
||||
rt->m_alpha_max = 255;
|
||||
rt->m_alpha_min = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((m_texture_shuffle && m_conf.ps.write_rg == false) || m_channel_shuffle)
|
||||
{
|
||||
rt->m_alpha_max = 255;
|
||||
rt->m_alpha_min = 0;
|
||||
}
|
||||
|
||||
GL_INS("RT Alpha Range: %d-%d => %d-%d", blend_alpha_min, blend_alpha_max, rt->m_alpha_min, rt->m_alpha_max);
|
||||
|
||||
// If there's no overlap, the values in the RT before FB write will be the old values.
|
||||
if (m_prim_overlap != PRIM_OVERLAP_NO)
|
||||
{
|
||||
// Otherwise, it may be a mix of the old/new values.
|
||||
blend_alpha_min = std::min(blend_alpha_min, rt->m_alpha_min);
|
||||
blend_alpha_max = std::max(blend_alpha_max, rt->m_alpha_max);
|
||||
}
|
||||
|
||||
if (!rt->m_32_bits_fmt)
|
||||
{
|
||||
rt->m_alpha_max &= 128;
|
||||
rt->m_alpha_min &= 128;
|
||||
}
|
||||
}
|
||||
|
||||
// DATE: selection of the algorithm. Must be done before blending because GL42 is not compatible with blending
|
||||
if (DATE)
|
||||
{
|
||||
if (m_cached_ctx.TEST.DATM)
|
||||
{
|
||||
if (rt)
|
||||
{
|
||||
// Destination and incoming pixels are all 1 or higher, no need for DATE.
|
||||
if ((rt->m_alpha_min >= 128 || (m_cached_ctx.FRAME.FBMSK & 0x80000000)) && blend_alpha_min >= 128)
|
||||
{
|
||||
DATE = false;
|
||||
m_cached_ctx.TEST.DATE = false;
|
||||
}
|
||||
else if (blend_alpha_max < 128) // All dest pixels are less than 1, everything fails.
|
||||
{
|
||||
rt->m_alpha_max = blend_alpha_max;
|
||||
rt->m_alpha_min = blend_alpha_min;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rt)
|
||||
{
|
||||
// Destination and incoming pixels are all less than 1, no need for DATE.
|
||||
if ((rt->m_alpha_max < 128 || (m_cached_ctx.FRAME.FBMSK & 0x80000000)) && blend_alpha_max < 128)
|
||||
{
|
||||
DATE = false;
|
||||
m_cached_ctx.TEST.DATE = false;
|
||||
}
|
||||
else if (blend_alpha_min >= 128) // All dest pixels are 1 or higher, everything fails.
|
||||
{
|
||||
rt->m_alpha_max = blend_alpha_max;
|
||||
rt->m_alpha_min = blend_alpha_min;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DATE)
|
||||
{
|
||||
// It is way too complex to emulate texture shuffle with DATE, so use accurate path.
|
||||
|
@ -4840,6 +4948,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
ASSERT(!(DATE_PRIMID && DATE_one));
|
||||
ASSERT(!(DATE_PRIMID && DATE_BARRIER));
|
||||
}
|
||||
}
|
||||
|
||||
// Before emulateblending, dither will be used
|
||||
m_conf.ps.dither = GSConfig.Dithering > 0 && m_conf.ps.dfmt == 2 && env.DTHE.DTHE;
|
||||
|
@ -4850,74 +4959,6 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.colormask.wa = 0;
|
||||
}
|
||||
|
||||
// Blend
|
||||
int blend_alpha_min = 0, blend_alpha_max = 255;
|
||||
if (rt)
|
||||
{
|
||||
blend_alpha_min = rt->m_alpha_min;
|
||||
blend_alpha_max = rt->m_alpha_max;
|
||||
|
||||
const bool is_24_bit = (GSLocalMemory::m_psm[rt->m_TEX0.PSM].trbpp == 24);
|
||||
if (is_24_bit)
|
||||
{
|
||||
// C24/Z24 - alpha is 1.
|
||||
blend_alpha_min = 128;
|
||||
blend_alpha_max = 128;
|
||||
}
|
||||
|
||||
if (!m_channel_shuffle && !m_texture_shuffle)
|
||||
{
|
||||
const int fba_value = m_prev_env.CTXT[m_prev_env.PRIM.CTXT].FBA.FBA * 128;
|
||||
if ((m_cached_ctx.FRAME.FBMSK & 0xff000000) == 0)
|
||||
{
|
||||
if (rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(m_cached_ctx.TEST.DATE || m_cached_ctx.TEST.ATE || m_cached_ctx.TEST.ZTST != ZTST_ALWAYS))
|
||||
{
|
||||
rt->m_alpha_max = GetAlphaMinMax().max | fba_value;
|
||||
rt->m_alpha_min = GetAlphaMinMax().min | fba_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
rt->m_alpha_max = std::max(GetAlphaMinMax().max | fba_value, rt->m_alpha_max);
|
||||
rt->m_alpha_min = std::min(GetAlphaMinMax().min | fba_value, rt->m_alpha_min);
|
||||
}
|
||||
}
|
||||
else if ((m_cached_ctx.FRAME.FBMSK & 0xff000000) != 0xff000000) // We can't be sure of the alpha if it's partially masked.
|
||||
{
|
||||
rt->m_alpha_max |= std::max(GetAlphaMinMax().max | fba_value, rt->m_alpha_max);
|
||||
rt->m_alpha_min = std::min(GetAlphaMinMax().min | fba_value, rt->m_alpha_min);
|
||||
}
|
||||
else if (!is_24_bit)
|
||||
{
|
||||
// If both are zero then we probably don't know what the alpha is.
|
||||
if (rt->m_alpha_max == 0 && rt->m_alpha_min == 0)
|
||||
{
|
||||
rt->m_alpha_max = 255;
|
||||
rt->m_alpha_min = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((m_texture_shuffle && m_conf.ps.write_rg == false) || m_channel_shuffle)
|
||||
{
|
||||
rt->m_alpha_max = 255;
|
||||
rt->m_alpha_min = 0;
|
||||
}
|
||||
|
||||
GL_INS("RT Alpha Range: %d-%d => %d-%d", blend_alpha_min, blend_alpha_max, rt->m_alpha_min, rt->m_alpha_max);
|
||||
|
||||
// If there's no overlap, the values in the RT before FB write will be the old values.
|
||||
if (m_prim_overlap != PRIM_OVERLAP_NO)
|
||||
{
|
||||
// Otherwise, it may be a mix of the old/new values.
|
||||
blend_alpha_min = std::min(blend_alpha_min, rt->m_alpha_min);
|
||||
blend_alpha_max = std::max(blend_alpha_max, rt->m_alpha_max);
|
||||
}
|
||||
|
||||
if (!rt->m_32_bits_fmt)
|
||||
{
|
||||
rt->m_alpha_max &= 128;
|
||||
rt->m_alpha_min &= 128;
|
||||
}
|
||||
}
|
||||
|
||||
// Not gonna spend too much time with this, it's not likely to be used much, can't be less accurate than it was.
|
||||
if (ds)
|
||||
|
|
Loading…
Reference in New Issue