GS/HW: Further fix up RTA handling

This commit is contained in:
refractionpcsx2 2024-03-31 07:19:00 +01:00
parent effdfd5a22
commit 8e008288b6
2 changed files with 28 additions and 13 deletions

View File

@ -471,7 +471,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
GSVector4::storeh(&v[1].ST.S, st);
}
}
m_r = fpr;
m_vertex.head = m_vertex.tail = m_vertex.next = 2;
m_index.tail = 2;
return;
@ -1363,6 +1363,15 @@ bool GSRendererHW::IsRTWritten()
(ALPHA.C == 0 && GetAlphaMinMax().max != 0)))));
}
bool GSRendererHW::IsDepthAlwaysPassing()
{
const u32 max_z = (0xFFFFFFFF >> (GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].fmt * 8));
// 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);
}
bool GSRendererHW::IsUsingCsInBlend()
{
const GIFRegALPHA ALPHA = m_context->ALPHA;
@ -2047,13 +2056,8 @@ void GSRendererHW::Draw()
// 2/ SuperMan really draws (0,0,0,0) color and a (0) 32-bits depth
// 3/ 50cents really draws (0,0,0,128) color and a (0) 24 bits depth
// Note: FF DoC has both buffer at same location but disable the depth test (write?) with ZTE = 0
const u32 max_z = (0xFFFFFFFF >> (GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].fmt * 8));
bool no_rt = (!IsRTWritten() && !m_cached_ctx.TEST.DATE);
const bool all_depth_tests_pass =
// Depth is always pass/fail (no read) and write are discarded.
(!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);
const bool all_depth_tests_pass = IsDepthAlwaysPassing();
bool no_ds = (zm != 0 && all_depth_tests_pass) ||
// No color or Z being written.
(no_rt && zm != 0);
@ -3588,6 +3592,8 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS
m_cached_ctx.CLAMP.WMS = m_cached_ctx.CLAMP.WMS == CLAMP_REGION_CLAMP ? CLAMP_CLAMP : CLAMP_REPEAT;
if (m_cached_ctx.CLAMP.WMT > CLAMP_CLAMP)
m_cached_ctx.CLAMP.WMT = m_cached_ctx.CLAMP.WMT == CLAMP_REGION_CLAMP ? CLAMP_CLAMP : CLAMP_REPEAT;
m_primitive_covers_without_gaps = rt->m_valid.rintersect(m_r).eq(rt->m_valid);
}
else
{
@ -3836,8 +3842,12 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
s[0].XYZ.Y = static_cast<u16>(m_context->XYOFFSET.OFY + 0);
s[1].XYZ.Y = static_cast<u16>(m_context->XYOFFSET.OFY + 16384);
m_r = GSVector4i(0, 0, 1024, 1024);
m_vertex.head = m_vertex.tail = m_vertex.next = 2;
m_index.tail = 2;
m_primitive_covers_without_gaps = true;
return true;
}
@ -5218,7 +5228,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
const bool afail_always_fb_alpha = m_cached_ctx.TEST.AFAIL == AFAIL_FB_ONLY || (m_cached_ctx.TEST.AFAIL == AFAIL_RGB_ONLY && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].trbpp != 32);
const bool always_passing_alpha = !m_cached_ctx.TEST.ATE || afail_always_fb_alpha || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ATST_ALWAYS);
const bool full_cover = (rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || !always_passing_alpha || (m_cached_ctx.TEST.ZTE && m_cached_ctx.TEST.ZTST != ZTST_ALWAYS)) || m_channel_shuffle);
const bool full_cover = rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || !always_passing_alpha || !IsDepthAlwaysPassing());
if ((fb_mask & alpha_mask) == 0)
{
@ -5245,10 +5255,14 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
rt_new_alpha_min = std::min(s_alpha_min, rt_new_alpha_min);
}
if (full_cover && (fb_mask & alpha_mask) == 0)
rt->m_alpha_range = s_alpha_max != s_alpha_min;
else
rt->m_alpha_range |= (s_alpha_max & ~fb_mask) != (s_alpha_min & ~fb_mask);
if ((fb_mask & alpha_mask) != alpha_mask)
{
if (full_cover && (fb_mask & alpha_mask) == 0)
rt->m_alpha_range = s_alpha_max != s_alpha_min;
else
rt->m_alpha_range |= (s_alpha_max & ~fb_mask) != (s_alpha_min & ~fb_mask);
}
}
else if ((m_texture_shuffle && m_conf.colormask.wa))
{
@ -5497,7 +5511,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
{
const bool afail_always_fb_alpha = m_cached_ctx.TEST.AFAIL == AFAIL_FB_ONLY || (m_cached_ctx.TEST.AFAIL == AFAIL_RGB_ONLY && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].trbpp != 32);
const bool always_passing_alpha = !m_cached_ctx.TEST.ATE || afail_always_fb_alpha || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ATST_ALWAYS);
const bool full_cover = rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || !always_passing_alpha || (m_cached_ctx.TEST.ZTE && m_cached_ctx.TEST.ZTST != ZTST_ALWAYS));
const bool full_cover = rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || !always_passing_alpha || !IsDepthAlwaysPassing());
if (!full_cover)
{

View File

@ -119,6 +119,7 @@ private:
void FinishSplitClear();
bool IsRTWritten();
bool IsDepthAlwaysPassing();
bool IsUsingCsInBlend();
bool IsUsingAsInBlend();