mirror of https://github.com/PCSX2/pcsx2.git
GS-hw, TC: search tex in rt in dirty targets.
Also move any target BW update from InvalidateVideoMem to LookupTarget. Fixes Indiana Jones map rendering in cutscenes.
This commit is contained in:
parent
44d0966892
commit
c1e5e45431
|
@ -288,7 +288,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
bool found_t = false;
|
||||
for (auto t : m_dst[RenderTarget])
|
||||
{
|
||||
if (t->m_used && t->m_dirty.empty())
|
||||
const bool t_clean = t->m_dirty.empty();
|
||||
if (t->m_used)
|
||||
{
|
||||
// Typical bug (MGS3 blue cloud):
|
||||
// 1/ RT used as 32 bits => alpha channel written
|
||||
|
@ -299,7 +300,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
// Solution: consider the RT as 32 bits if the alpha was used in the past
|
||||
u32 t_psm = (t->m_dirty_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM;
|
||||
|
||||
if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t_psm))
|
||||
if (t_clean && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t_psm))
|
||||
{
|
||||
// It is a complex to convert the code in shader. As a reference, let's do it on the CPU, it will be slow but
|
||||
// 1/ it just works :)
|
||||
|
@ -316,7 +317,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
found_t = true;
|
||||
break;
|
||||
}
|
||||
else if ((t->m_TEX0.TBW >= 16) && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0 + t->m_TEX0.TBW * 0x10, t->m_TEX0.PSM))
|
||||
else if (t_clean && (t->m_TEX0.TBW >= 16) && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0 + t->m_TEX0.TBW * 0x10, t->m_TEX0.PSM))
|
||||
{
|
||||
// Detect half of the render target (fix snow engine game)
|
||||
// Target Page (8KB) have always a width of 64 pixels
|
||||
|
@ -678,6 +679,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
|
|||
}
|
||||
else
|
||||
{
|
||||
dst->m_TEX0.TBW = TEX0.TBW;
|
||||
dst->Update();
|
||||
}
|
||||
|
||||
|
@ -877,7 +879,6 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
|
|||
GL_CACHE("TC: Dirty Target(%s) %d (0x%x) r(%d,%d,%d,%d)", to_string(type),
|
||||
t->m_texture ? t->m_texture->GetID() : 0,
|
||||
t->m_TEX0.TBP0, r.x, r.y, r.z, r.w);
|
||||
t->m_TEX0.TBW = bw;
|
||||
t->m_dirty.push_back(GSDirtyRect(r, psm, bw));
|
||||
}
|
||||
else
|
||||
|
@ -917,7 +918,6 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
|
|||
t->m_texture ? t->m_texture->GetID() : 0,
|
||||
t->m_TEX0.TBP0);
|
||||
// TODO: do not add this rect above too
|
||||
t->m_TEX0.TBW = bw;
|
||||
t->m_dirty.push_back(GSDirtyRect(GSVector4i(r.left, r.top - y, r.right, r.bottom - y), psm, bw));
|
||||
continue;
|
||||
}
|
||||
|
@ -945,7 +945,6 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
|
|||
t->m_TEX0.TBP0, t->m_end_block,
|
||||
r.left, r.top + y, r.right, r.bottom + y, bw);
|
||||
|
||||
t->m_TEX0.TBW = bw;
|
||||
t->m_dirty.push_back(GSDirtyRect(GSVector4i(r.left, r.top + y, r.right, r.bottom + y), psm, bw));
|
||||
continue;
|
||||
}
|
||||
|
@ -2422,6 +2421,26 @@ GSTextureCache::SurfaceOffset GSTextureCache::ComputeSurfaceOffset(const uint32_
|
|||
sok.elems[1].psm = t->m_TEX0.PSM;
|
||||
sok.elems[1].rect = t->m_valid;
|
||||
const SurfaceOffset so = ComputeSurfaceOffset(sok);
|
||||
// Check if any dirty rect in the target overlaps with the offset.
|
||||
if (so.is_valid && !t->m_dirty.empty())
|
||||
{
|
||||
const SurfaceOffsetKeyElem& t_sok = sok.elems[1];
|
||||
const GSLocalMemory::psm_t& t_psm_s = GSLocalMemory::m_psm[t_sok.psm];
|
||||
const u32 so_bp = t_psm_s.info.bn(so.b2a_offset.x, so.b2a_offset.y, t_sok.bp, t_sok.bw);
|
||||
const u32 so_bp_end = t_psm_s.info.bn(so.b2a_offset.z - 1, so.b2a_offset.w - 1, t_sok.bp, t_sok.bw);
|
||||
for (const auto& dr : t->m_dirty)
|
||||
{
|
||||
const GSLocalMemory::psm_t& dr_psm_s = GSLocalMemory::m_psm[dr.psm];
|
||||
const u32 dr_bp = dr_psm_s.info.bn(dr.r.x, dr.r.y, t_sok.bp, dr.bw);
|
||||
const u32 dr_bp_end = dr_psm_s.info.bn(dr.r.z - 1, dr.r.w - 1, t_sok.bp, dr.bw);
|
||||
const bool overlap = GSTextureCache::CheckOverlap(dr_bp, dr_bp_end, so_bp, so_bp_end);
|
||||
if (overlap)
|
||||
{
|
||||
// Dirty rectangle in target overlaps with the found offset.
|
||||
return { false };
|
||||
}
|
||||
}
|
||||
}
|
||||
return so;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue