mirror of https://github.com/PCSX2/pcsx2.git
GS: Correct depth trace for sprites + optimize HW depth selection
This commit is contained in:
parent
6aa57b7e87
commit
8917c5dbc9
|
@ -132,13 +132,15 @@ void GSVertexTrace::CorrectDepthTrace(const void* vertex, int count)
|
|||
|
||||
|
||||
const GSVertex* RESTRICT v = (GSVertex*)vertex;
|
||||
u32 z = v[0].XYZ.Z;
|
||||
|
||||
// ought to check only 1/2 for sprite
|
||||
const int sprite_step = (m_primclass == GS_SPRITE_CLASS) ? 1 : 0;
|
||||
|
||||
u32 z = v[sprite_step].XYZ.Z;
|
||||
|
||||
if (z & 1)
|
||||
{
|
||||
// Check that first bit is always 1
|
||||
for (int i = 0; i < count; i++)
|
||||
for (int i = sprite_step; i < count; i += (sprite_step + 1))
|
||||
{
|
||||
z &= v[i].XYZ.Z;
|
||||
}
|
||||
|
@ -146,13 +148,13 @@ void GSVertexTrace::CorrectDepthTrace(const void* vertex, int count)
|
|||
else
|
||||
{
|
||||
// Check that first bit is always 0
|
||||
for (int i = 0; i < count; i++)
|
||||
for (int i = sprite_step; i < count; i += (sprite_step + 1))
|
||||
{
|
||||
z |= v[i].XYZ.Z;
|
||||
}
|
||||
}
|
||||
|
||||
if (z == v[0].XYZ.Z)
|
||||
if (z == v[sprite_step].XYZ.Z)
|
||||
{
|
||||
m_eq.z = 1;
|
||||
}
|
||||
|
|
|
@ -1397,10 +1397,11 @@ bool GSRendererHW::IsRTWritten()
|
|||
bool GSRendererHW::IsDepthAlwaysPassing()
|
||||
{
|
||||
const u32 max_z = (0xFFFFFFFF >> (GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].fmt * 8));
|
||||
const int check_index = m_vt.m_primclass == GS_SPRITE_CLASS ? 1 : 0;
|
||||
// Depth is always pass/fail (no read) and write are discarded.
|
||||
return (!m_cached_ctx.TEST.ZTE || m_cached_ctx.TEST.ZTST <= ZTST_ALWAYS) ||
|
||||
// Depth test will always pass
|
||||
(m_cached_ctx.TEST.ZTST == ZTST_GEQUAL && m_vt.m_eq.z && std::min(m_vertex.buff[0].XYZ.Z, max_z) == max_z);
|
||||
(m_cached_ctx.TEST.ZTST == ZTST_GEQUAL && m_vt.m_eq.z && std::min(m_vertex.buff[check_index].XYZ.Z, max_z) == max_z);
|
||||
}
|
||||
|
||||
bool GSRendererHW::IsUsingCsInBlend()
|
||||
|
@ -2708,15 +2709,58 @@ void GSRendererHW::Draw()
|
|||
|
||||
ds = g_texture_cache->LookupTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
|
||||
m_cached_ctx.DepthWrite(), 0, false, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block());
|
||||
|
||||
if (!ds)
|
||||
{
|
||||
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src), target_scale, GSTextureCache::DepthStencil,
|
||||
true, 0, false, force_preload, preserve_depth, m_r, src);
|
||||
if (!ds) [[unlikely]]
|
||||
|
||||
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src), target_scale, GSTextureCache::DepthStencil,
|
||||
true, 0, false, force_preload, preserve_depth, m_r, src);
|
||||
if (!ds) [[unlikely]]
|
||||
{
|
||||
GL_INS("ERROR: Failed to create ZBUF target, skipping.");
|
||||
CleanupDraw(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it failed to check depth test earlier, we can now check the top bits from the alpha to get a bit more accurate picture.
|
||||
if (((zm && m_cached_ctx.TEST.ZTST > ZTST_ALWAYS) || (m_vt.m_eq.z && m_cached_ctx.TEST.ZTST == ZTST_GEQUAL)) && GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].trbpp == 32)
|
||||
{
|
||||
GL_INS("ERROR: Failed to create ZBUF target, skipping.");
|
||||
CleanupDraw(true);
|
||||
return;
|
||||
if (ds->m_alpha_max != 0)
|
||||
{
|
||||
const u32 max_z = (static_cast<u64>(ds->m_alpha_max + 1) << 24) - 1;
|
||||
|
||||
switch (m_cached_ctx.TEST.ZTST)
|
||||
{
|
||||
case ZTST_GEQUAL:
|
||||
// Every Z value will pass
|
||||
if (max_z <= m_vt.m_min.p.z)
|
||||
{
|
||||
m_cached_ctx.TEST.ZTST = ZTST_ALWAYS;
|
||||
if (zm)
|
||||
{
|
||||
ds = nullptr;
|
||||
no_ds = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZTST_GREATER:
|
||||
// Every Z value will pass
|
||||
if (max_z < m_vt.m_min.p.z)
|
||||
{
|
||||
m_cached_ctx.TEST.ZTST = ZTST_ALWAYS;
|
||||
if (zm)
|
||||
{
|
||||
ds = nullptr;
|
||||
no_ds = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5608,8 +5652,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
// 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)
|
||||
{
|
||||
ds->m_alpha_max = std::max(ds->m_alpha_max, static_cast<int>(m_vt.m_max.p.z) >> 24);
|
||||
ds->m_alpha_min = std::min(ds->m_alpha_min, static_cast<int>(m_vt.m_min.p.z) >> 24);
|
||||
ds->m_alpha_max = std::max(static_cast<u32>(ds->m_alpha_max), static_cast<u32>(m_vt.m_max.p.z) >> 24);
|
||||
ds->m_alpha_min = std::min(static_cast<u32>(ds->m_alpha_min), static_cast<u32>(m_vt.m_min.p.z) >> 24);
|
||||
GL_INS("New DS Alpha Range: %d-%d", ds->m_alpha_min, ds->m_alpha_max);
|
||||
|
||||
if (GSLocalMemory::m_psm[ds->m_TEX0.PSM].bpp == 16)
|
||||
|
|
Loading…
Reference in New Issue