GS/HW: RTA checks for moves and DST matches and ICO CRC.

This commit is contained in:
refractionpcsx2 2024-02-27 04:41:20 +00:00 committed by lightningterror
parent 6a5ac4fe54
commit 7a547e64c4
3 changed files with 35 additions and 1 deletions

View File

@ -1435,6 +1435,11 @@ bool GSHwHack::MV_Ico(GSRendererHW& r)
dst->UpdateValidChannels(PSMCT32, 0); dst->UpdateValidChannels(PSMCT32, 0);
dst->UpdateValidity(draw_rc); dst->UpdateValidity(draw_rc);
if (dst->m_rt_alpha_scale)
{
dst->RTADecorrect(dst);
}
GSHWDrawConfig& config = GSRendererHW::GetInstance()->BeginHLEHardwareDraw( GSHWDrawConfig& config = GSRendererHW::GetInstance()->BeginHLEHardwareDraw(
dst->GetTexture(), nullptr, dst->GetScale(), src->GetTexture(), src->GetScale(), draw_rc); dst->GetTexture(), nullptr, dst->GetScale(), src->GetTexture(), src->GetScale(), draw_rc);
config.pal = palette->GetPaletteGSTexture(); config.pal = palette->GetPaletteGSTexture();

View File

@ -4304,7 +4304,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
m_conf.ps.blend_b = 0; m_conf.ps.blend_b = 0;
m_conf.ps.blend_d = 0; m_conf.ps.blend_d = 0;
const bool rta_decorrection = m_channel_shuffle || m_texture_shuffle || rt_alpha_max > 128 || m_conf.ps.fbmask || m_conf.ps.tex_is_fb; const bool rta_decorrection = m_channel_shuffle || m_texture_shuffle || (std::max(rt_alpha_max, rt->m_alpha_max) > 128) || m_conf.ps.fbmask || m_conf.ps.tex_is_fb;
const bool rta_correction = !rta_decorrection && !blend_ad_alpha_masked && m_conf.ps.blend_c == 1 && !(blend_flag & BLEND_A_MAX); const bool rta_correction = !rta_decorrection && !blend_ad_alpha_masked && m_conf.ps.blend_c == 1 && !(blend_flag & BLEND_A_MAX);
if (rta_correction) if (rta_correction)
{ {

View File

@ -1995,6 +1995,9 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
dst->m_was_dst_matched = true; dst->m_was_dst_matched = true;
dst->m_TEX0.TBW = dst_match->m_TEX0.TBW; dst->m_TEX0.TBW = dst_match->m_TEX0.TBW;
dst->UpdateValidity(dst->m_valid); dst->UpdateValidity(dst->m_valid);
dst->m_rt_alpha_scale = false;
if (!CopyRGBFromDepthToColor(dst, dst_match)) if (!CopyRGBFromDepthToColor(dst, dst_match))
{ {
// Needed new texture and memory allocation failed. // Needed new texture and memory allocation failed.
@ -2232,6 +2235,9 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
} }
else if (dst_match->m_texture->GetState() == GSTexture::State::Dirty) else if (dst_match->m_texture->GetState() == GSTexture::State::Dirty)
{ {
if (dst_match->m_type == RenderTarget && dst_match->m_rt_alpha_scale)
dst_match->RTADecorrect(dst_match);
g_gs_device->StretchRect(dst_match->m_texture, sRect, dst->m_texture, dRect, shader, false); g_gs_device->StretchRect(dst_match->m_texture, sRect, dst->m_texture, dRect, shader, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1); g_perfmon.Put(GSPerfMon::TextureCopies, 1);
} }
@ -3686,6 +3692,19 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
GL_CACHE("HW Move 0x%x[BW:%u PSM:%s] to 0x%x[BW:%u PSM:%s] <%d,%d->%d,%d> -> <%d,%d->%d,%d>", SBP, SBW, GL_CACHE("HW Move 0x%x[BW:%u PSM:%s] to 0x%x[BW:%u PSM:%s] <%d,%d->%d,%d> -> <%d,%d->%d,%d>", SBP, SBW,
psm_str(SPSM), DBP, DBW, psm_str(DPSM), sx, sy, sx + w, sy + h, dx, dy, dx + w, dy + h); psm_str(SPSM), DBP, DBW, psm_str(DPSM), sx, sy, sx + w, sy + h, dx, dy, dx + w, dy + h);
const bool cover_whole_target = dst->m_type == RenderTarget && GSVector4i(dx, dy, dx + w, dy + h).rintersect(dst->m_valid).eq(dst->m_valid);
if (!cover_whole_target)
{
if (src->m_type == RenderTarget && src->m_rt_alpha_scale)
{
src->RTADecorrect(src);
}
if (dst->m_type == RenderTarget && dst->m_rt_alpha_scale)
{
dst->RTADecorrect(dst);
}
}
// If the copies overlap, this is a validation error, so we need to copy to a temporary texture first. // If the copies overlap, this is a validation error, so we need to copy to a temporary texture first.
if ((SBP == DBP) && !(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h))).rempty()) if ((SBP == DBP) && !(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h))).rempty())
{ {
@ -3794,6 +3813,10 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
} }
dst->UpdateValidity(GSVector4i(dx, dy, dx + w, dy + h)); dst->UpdateValidity(GSVector4i(dx, dy, dx + w, dy + h));
dst->UpdateDrawn(GSVector4i(dx, dy, dx + w, dy + h)); dst->UpdateDrawn(GSVector4i(dx, dy, dx + w, dy + h));
if (cover_whole_target)
dst->m_rt_alpha_scale = src->m_rt_alpha_scale;
// Invalidate any sources that overlap with the target (since they're now stale). // Invalidate any sources that overlap with the target (since they're now stale).
InvalidateVideoMem(g_gs_renderer->m_mem.GetOffset(DBP, DBW, DPSM), GSVector4i(dx, dy, dx + w, dy + h), false); InvalidateVideoMem(g_gs_renderer->m_mem.GetOffset(DBP, DBW, DPSM), GSVector4i(dx, dy, dx + w, dy + h), false);
return true; return true;
@ -3848,6 +3871,12 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
const GSVector4i bbox = write_rg ? GSVector4i(dx, dy, dx + w, dy + h) : GSVector4i(sx, sy, sx + w, sy + h); const GSVector4i bbox = write_rg ? GSVector4i(dx, dy, dx + w, dy + h) : GSVector4i(sx, sy, sx + w, sy + h);
if (tgt->m_rt_alpha_scale)
{
if (read_ba || !write_rg)
tgt->RTADecorrect(tgt);
}
GSHWDrawConfig& config = GSRendererHW::GetInstance()->BeginHLEHardwareDraw(tgt->m_texture, nullptr, tgt->m_scale, tgt->m_texture, tgt->m_scale, bbox); GSHWDrawConfig& config = GSRendererHW::GetInstance()->BeginHLEHardwareDraw(tgt->m_texture, nullptr, tgt->m_scale, tgt->m_texture, tgt->m_scale, bbox);
config.colormask.wrgba = (write_rg ? (1 | 2) : (4 | 8)); config.colormask.wrgba = (write_rg ? (1 | 2) : (4 | 8));
config.ps.read_ba = read_ba; config.ps.read_ba = read_ba;