mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
GS/TC: Update depth lookup when looking up targets.
This commit is contained in:
@@ -2404,13 +2404,20 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
};
|
||||
|
||||
Target* dst = nullptr;
|
||||
auto& list = m_dst[type];
|
||||
Target* dst_match = nullptr;
|
||||
auto* list = &m_dst[type];
|
||||
|
||||
const GSVector4i min_rect = draw_rect.max_u32(GSVector4i(0, 0, draw_rect.x, draw_rect.y));
|
||||
// TODO: Move all frame stuff to its own routine too.
|
||||
if (!is_frame)
|
||||
{
|
||||
for (auto i = list.begin(); i != list.end();)
|
||||
for (int iteration = 0; iteration < 2; iteration++)
|
||||
{
|
||||
if (dst != nullptr)
|
||||
break;
|
||||
|
||||
list = &m_dst[iteration == 0 ? type : (1 - type)];
|
||||
for (auto i = list->begin(); i != list->end();)
|
||||
{
|
||||
Target* t = *i;
|
||||
if (bp == t->m_TEX0.TBP0)
|
||||
@@ -2492,17 +2499,26 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
if (can_use)
|
||||
{
|
||||
if (used)
|
||||
list.MoveFront(i.Index());
|
||||
dst = t;
|
||||
list->MoveFront(i.Index());
|
||||
|
||||
if (iteration == 1)
|
||||
{
|
||||
dst_match = t;
|
||||
dst_match->m_32_bits_fmt |= (psm_s.bpp != 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = t;
|
||||
dst->m_32_bits_fmt |= (psm_s.bpp != 16);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (!(src && src->m_from_target == t))
|
||||
{
|
||||
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s due to change in target", t->m_TEX0.TBP0, t->m_TEX0.TBW, GSUtil::GetPSMName(t->m_TEX0.PSM));
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
|
||||
continue;
|
||||
@@ -2551,7 +2567,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
{
|
||||
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s offset overwrite shuffle", t->m_TEX0.TBP0, t->m_TEX0.TBW, GSUtil::GetPSMName(t->m_TEX0.PSM));
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
|
||||
continue;
|
||||
@@ -2580,7 +2596,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
{
|
||||
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s due to change in target", t->m_TEX0.TBP0, t->m_TEX0.TBW, GSUtil::GetPSMName(t->m_TEX0.PSM));
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
}
|
||||
|
||||
@@ -2601,7 +2617,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
{
|
||||
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s due to dirty areas not preserved (Likely change in target)", t->m_TEX0.TBP0, t->m_TEX0.TBW, GSUtil::GetPSMName(t->m_TEX0.PSM));
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
|
||||
continue;
|
||||
@@ -2626,12 +2642,21 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
}
|
||||
|
||||
//DevCon.Warning("Here draw %d wanted %x PSM %x got %x PSM %x offset of %d pages width %d pages draw width %d", GSState::s_n, bp, TEX0.PSM, t->m_TEX0.TBP0, t->m_TEX0.PSM, (bp - t->m_TEX0.TBP0) >> 5, t->m_TEX0.TBW, draw_rect.width());
|
||||
dst = t;
|
||||
if (iteration == 1)
|
||||
{
|
||||
dst_match = t;
|
||||
dst_match->m_32_bits_fmt |= (psm_s.bpp != 16);
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = t;
|
||||
dst->m_32_bits_fmt |= (psm_s.bpp != 16);
|
||||
}
|
||||
//Continue just in case there's a newer target
|
||||
if (used)
|
||||
list.MoveFront(i.Index());
|
||||
list->MoveFront(i.Index());
|
||||
if (t->m_TEX0.TBP0 <= bp || GSLocalMemory::GetStartBlockAddress(TEX0.TBP0, TEX0.TBW, TEX0.PSM, min_rect) >= bp)
|
||||
break;
|
||||
else
|
||||
@@ -2643,11 +2668,12 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxAssert(type == RenderTarget);
|
||||
// Let's try to find a perfect frame that contains valid data
|
||||
for (auto i = list.begin(); i != list.end(); ++i)
|
||||
for (auto i = list->begin(); i != list->end(); ++i)
|
||||
{
|
||||
Target* t = *i;
|
||||
|
||||
@@ -2673,7 +2699,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
{
|
||||
DevCon.Warning("Wanted %x psm %x bw %x, got %x psm %x bw %x, deleting", TEX0.TBP0, TEX0.PSM, TEX0.TBW, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW);
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
@@ -2691,7 +2717,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
// 2nd try ! Try to find a frame at the requested bp -> bp + size is inside of (or equal to)
|
||||
if (!dst)
|
||||
{
|
||||
for (auto i = list.begin(); i != list.end(); ++i)
|
||||
for (auto i = list->begin(); i != list->end(); ++i)
|
||||
{
|
||||
Target* t = *i;
|
||||
const u32 end_block = GSLocalMemory::GetEndBlockAddress(bp, TEX0.TBW, TEX0.PSM, GSVector4i(0, size.y, size.x, size.y + 1));
|
||||
@@ -2711,7 +2737,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
{
|
||||
DevCon.Warning("2 Wanted %x psm %x bw %x, got %x psm %x bw %x, deleting", TEX0.TBP0, TEX0.PSM, TEX0.TBW, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW);
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
@@ -2731,7 +2757,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
// 3rd try ! Try to find a frame that doesn't contain valid data (honestly I'm not sure we need to do it)
|
||||
if (!dst)
|
||||
{
|
||||
for (auto i = list.begin(); i != list.end(); ++i)
|
||||
for (auto i = list->begin(); i != list->end(); ++i)
|
||||
{
|
||||
Target* t = *i;
|
||||
if (bp == t->m_TEX0.TBP0 && TEX0.TBW == t->m_TEX0.TBW)
|
||||
@@ -2743,7 +2769,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
{
|
||||
DevCon.Warning("3 Wanted %x psm %x bw %x, got %x psm %x bw %x, deleting", TEX0.TBP0, TEX0.PSM, TEX0.TBW, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW);
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = list.erase(i);
|
||||
i = list->erase(i);
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
@@ -2969,21 +2995,21 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
if (!is_frame)
|
||||
{
|
||||
GL_CACHE("TC: Attempt to repopulate RGB for %s[%x]", to_string(type), dst->m_TEX0.TBP0);
|
||||
for (Target* dst_match : m_dst[1 - type])
|
||||
for (Target* dst_match_repopulate : m_dst[1 - type])
|
||||
{
|
||||
if (dst_match->m_TEX0.TBP0 != dst->m_TEX0.TBP0 || !dst_match->m_valid_rgb)
|
||||
if (dst_match_repopulate->m_TEX0.TBP0 != dst->m_TEX0.TBP0 || !dst_match_repopulate->m_valid_rgb)
|
||||
continue;
|
||||
|
||||
dst->m_TEX0.TBW = dst_match->m_TEX0.TBW;
|
||||
dst->m_TEX0.TBW = dst_match_repopulate->m_TEX0.TBW;
|
||||
// Force the valid rect to the new size in case of shrinkage.
|
||||
dst->m_valid = dst_match->m_valid;
|
||||
dst->UpdateValidity(dst_match->m_valid);
|
||||
dst->m_valid = dst_match_repopulate->m_valid;
|
||||
dst->UpdateValidity(dst_match_repopulate->m_valid);
|
||||
|
||||
if (type == RenderTarget)
|
||||
{
|
||||
dst_match->m_valid_rgb = (fbmask & mask) == (mask & 0x00FFFFFFu);
|
||||
dst_match_repopulate->m_valid_rgb = (fbmask & mask) == (mask & 0x00FFFFFFu);
|
||||
dst->m_was_dst_matched = true;
|
||||
if (!CopyRGBFromDepthToColor(dst, dst_match))
|
||||
if (!CopyRGBFromDepthToColor(dst, dst_match_repopulate))
|
||||
{
|
||||
// Needed new texture and memory allocation failed.
|
||||
return nullptr;
|
||||
@@ -2991,10 +3017,10 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_match->m_valid_rgb &= (fbmask & mask) == (mask & 0x00FFFFFFu);
|
||||
dst_match_repopulate->m_valid_rgb &= (fbmask & mask) == (mask & 0x00FFFFFFu);
|
||||
dst->Update();
|
||||
|
||||
if (!dst->ResizeTexture(dst_match->m_unscaled_size.x, dst_match->m_unscaled_size.y))
|
||||
if (!dst->ResizeTexture(dst_match_repopulate->m_unscaled_size.x, dst_match_repopulate->m_unscaled_size.y))
|
||||
{
|
||||
// Needed new texture and memory allocation failed.
|
||||
return nullptr;
|
||||
@@ -3004,14 +3030,14 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 :
|
||||
ShaderConvert::RGBA8_TO_FLOAT24;
|
||||
|
||||
g_gs_device->StretchRect(dst_match->m_texture, GSVector4(0, 0, 1, 1),
|
||||
g_gs_device->StretchRect(dst_match_repopulate->m_texture, GSVector4(0, 0, 1, 1),
|
||||
dst->m_texture, GSVector4(dst->GetUnscaledRect()) * GSVector4(dst->GetScale()), shader, false);
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
dst_match->m_valid_rgb = !used;
|
||||
dst_match->m_was_dst_matched = true;
|
||||
dst_match_repopulate->m_valid_rgb = !used;
|
||||
dst_match_repopulate->m_was_dst_matched = true;
|
||||
dst->m_valid_rgb = true;
|
||||
dst->m_32_bits_fmt = dst_match->m_32_bits_fmt;
|
||||
dst->m_32_bits_fmt = dst_match_repopulate->m_32_bits_fmt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3087,13 +3113,13 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
}
|
||||
}
|
||||
else if (!is_frame && !GSConfig.UserHacks_DisableDepthSupport)
|
||||
{
|
||||
if (!dst_match)
|
||||
{
|
||||
const int rev_type = (type == DepthStencil) ? RenderTarget : DepthStencil;
|
||||
|
||||
// Depth stencil/RT can be an older RT/DS but only check recent RT/DS to avoid to pick
|
||||
// some bad data.
|
||||
auto& rev_list = m_dst[rev_type];
|
||||
Target* dst_match = nullptr;
|
||||
for (auto i = rev_list.begin(); i != rev_list.end(); ++i)
|
||||
{
|
||||
Target* t = *i;
|
||||
@@ -3173,9 +3199,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
dst_match = t;
|
||||
}
|
||||
}
|
||||
// We only want to use a matched target if it's actually being used.
|
||||
if (dst_match)
|
||||
}
|
||||
else
|
||||
{
|
||||
// dst_match, we only want to use a matched target if it's actually being used.
|
||||
|
||||
calcRescale(dst_match);
|
||||
|
||||
// If we don't need A, and the existing target doesn't have valid alpha, don't bother converting it.
|
||||
@@ -3192,7 +3220,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
// Clear instead of invalidating if there is anything which isn't touched.
|
||||
clear |= (!preserve_target && fbmask != 0);
|
||||
GIFRegTEX0 new_TEX0;
|
||||
new_TEX0.TBP0 = TEX0.TBP0;
|
||||
new_TEX0.TBP0 = GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets ? dst_match->m_TEX0.TBP0 : TEX0.TBP0;
|
||||
new_TEX0.TBW = (!half_width) ? dst_match->m_TEX0.TBW : TEX0.TBW;
|
||||
new_TEX0.PSM = is_shuffle ? dst_match->m_TEX0.PSM : TEX0.PSM;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user