mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Further fix up RTA handling
This commit is contained in:
parent
effdfd5a22
commit
8e008288b6
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -119,6 +119,7 @@ private:
|
|||
void FinishSplitClear();
|
||||
|
||||
bool IsRTWritten();
|
||||
bool IsDepthAlwaysPassing();
|
||||
bool IsUsingCsInBlend();
|
||||
bool IsUsingAsInBlend();
|
||||
|
||||
|
|
Loading…
Reference in New Issue