mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Allow creation of known targets via move with offset
Fixes upscaling with subtitles in Devil May Cry.
This commit is contained in:
parent
070068366f
commit
83bf215ead
|
@ -2310,6 +2310,24 @@ void GSRendererHW::Draw()
|
|||
GL_INS("Skipping (%d,%d=>%d,%d) draw at FBP %x/ZBP %x due to invalid height or zero clear.", m_r.x, m_r.y,
|
||||
m_r.z, m_r.w, m_cached_ctx.FRAME.Block(), m_cached_ctx.ZBUF.Block());
|
||||
|
||||
// Since we're not creating a target here, if this is the first draw to the target, it's not going
|
||||
// to be in the height cache, and we might create a smaller size target. We also need to record
|
||||
// it for HW moves (e.g. Devil May Cry subtitles).
|
||||
if (!height_invalid)
|
||||
{
|
||||
const GSVector2i target_size = GetValidSize(nullptr);
|
||||
if (!no_rt && is_zero_color_clear)
|
||||
{
|
||||
g_texture_cache->GetTargetSize(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM,
|
||||
target_size.x, target_size.y);
|
||||
}
|
||||
if (!no_ds && is_zero_depth_clear)
|
||||
{
|
||||
g_texture_cache->GetTargetSize(m_cached_ctx.ZBUF.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.ZBUF.PSM,
|
||||
target_size.x, target_size.y);
|
||||
}
|
||||
}
|
||||
|
||||
CleanupDraw(false);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3648,8 +3648,9 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
|
|||
|
||||
// Beware of the case where a game might create a larger texture by moving a bunch of chunks around.
|
||||
// We use dx/dy == 0 and the TBW check as a safeguard to make sure these go through to local memory.
|
||||
// We can also recreate the target if it's previously been created in the height cache with a valid size.
|
||||
// Good test case for this is the Xenosaga I cutscene transitions, or Gradius V.
|
||||
if (src && !dst && dx == 0 && dy == 0 && ((static_cast<u32>(w) + 63) / 64) <= DBW)
|
||||
if (src && !dst && ((dx == 0 && dy == 0 && ((static_cast<u32>(w) + 63) / 64) <= DBW) || HasTargetInHeightCache(DBP, DBW, DPSM, 10)))
|
||||
{
|
||||
GIFRegTEX0 new_TEX0 = {};
|
||||
new_TEX0.TBP0 = DBP;
|
||||
|
@ -4107,6 +4108,31 @@ GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width
|
|||
return GSVector2i(min_width, min_height);
|
||||
}
|
||||
|
||||
bool GSTextureCache::HasTargetInHeightCache(u32 bp, u32 fbw, u32 psm, u32 max_age, bool move_front)
|
||||
{
|
||||
TargetHeightElem search = {};
|
||||
search.bp = bp;
|
||||
search.fbw = fbw;
|
||||
search.psm = psm;
|
||||
|
||||
for (auto it = m_target_heights.begin(); it != m_target_heights.end(); ++it)
|
||||
{
|
||||
TargetHeightElem& elem = const_cast<TargetHeightElem&>(*it);
|
||||
if (elem.bits == search.bits)
|
||||
{
|
||||
if (elem.age > max_age)
|
||||
return false;
|
||||
|
||||
if (move_front)
|
||||
m_target_heights.MoveFront(it.Index());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GSTextureCache::Has32BitTarget(u32 bp)
|
||||
{
|
||||
// Look for 32-bit targets at the matching block.
|
||||
|
|
|
@ -502,6 +502,7 @@ public:
|
|||
Target* FindOverlappingTarget(u32 BP, u32 BW, u32 PSM, GSVector4i rc) const;
|
||||
|
||||
GSVector2i GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width, s32 min_height);
|
||||
bool HasTargetInHeightCache(u32 bp, u32 fbw, u32 psm, u32 max_age = std::numeric_limits<u32>::max(), bool move_front = true);
|
||||
bool Has32BitTarget(u32 bp);
|
||||
|
||||
void InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 write_psm = PSMCT32);
|
||||
|
|
Loading…
Reference in New Issue