Skip to content

Commit

Permalink
GS/HW: Further fix up RTA handling
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Apr 2, 2024
1 parent effdfd5 commit 8e00828
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
40 changes: 27 additions & 13 deletions pcsx2/GS/Renderers/HW/GSRendererHW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
{
Expand All @@ -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))
{
Expand Down Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions pcsx2/GS/Renderers/HW/GSRendererHW.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class GSRendererHW : public GSRenderer
void FinishSplitClear();

bool IsRTWritten();
bool IsDepthAlwaysPassing();
bool IsUsingCsInBlend();
bool IsUsingAsInBlend();

Expand Down

0 comments on commit 8e00828

Please sign in to comment.