mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
GS/HW/TC: Force a temporary source creation in edges cases.
Case: When looking up a source, we find a perfect BP hit for a target. However, the requested area is outside the target's valid area. Don't use the target direct and instead load from memory in a temporary source. Co-authored-by: refraction
This commit is contained in:
parent
b5a2d04b2e
commit
44f47f11b8
@ -1347,6 +1347,11 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||||||
int x_offset = 0;
|
int x_offset = 0;
|
||||||
int y_offset = 0;
|
int y_offset = 0;
|
||||||
|
|
||||||
|
// Indicates that in looking for targets that match the source BP, we found a perfect BP match
|
||||||
|
// but the target's valid area was outside the required area for the source. In such cases
|
||||||
|
// we want to create a temporary source and load the data from memory.
|
||||||
|
bool target_bp_hit_outside_valid_area = false;
|
||||||
|
|
||||||
#ifdef DISABLE_HW_TEXTURE_CACHE
|
#ifdef DISABLE_HW_TEXTURE_CACHE
|
||||||
if (0)
|
if (0)
|
||||||
#else
|
#else
|
||||||
@ -1725,6 +1730,15 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||||||
|
|
||||||
if (!possible_shuffle && outside_target)
|
if (!possible_shuffle && outside_target)
|
||||||
{
|
{
|
||||||
|
// Hit a target but source required area outside the target's valid area.
|
||||||
|
target_bp_hit_outside_valid_area = true;
|
||||||
|
GL_CACHE(
|
||||||
|
"TC: LookupSource: Target BP match but outside valid area;"
|
||||||
|
" Source=(BP=%04x, BW=%d, PSM=%s, req=(%x,%x - %x,%x));"
|
||||||
|
" Target=(BP=%04x, BW=%d, PSM=%s, valid_area=(%x,%x - %x,%x))",
|
||||||
|
bp, bw, GSUtil::GetPSMName(psm), r.x, r.y, r.z, r.w,
|
||||||
|
t->m_TEX0.TBP0, t->m_TEX0.TBW, GSUtil::GetPSMName(t->m_TEX0.PSM),
|
||||||
|
t->m_valid.x, t->m_valid.y, t->m_valid.z, t->m_valid.w);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2034,7 +2048,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||||||
//
|
//
|
||||||
// Sigh... They don't help us.
|
// Sigh... They don't help us.
|
||||||
|
|
||||||
if (!found_t && !dst && !GSConfig.UserHacks_DisableDepthSupport)
|
if (!found_t && !dst && !GSConfig.UserHacks_DisableDepthSupport && !target_bp_hit_outside_valid_area)
|
||||||
{
|
{
|
||||||
// Let's try a trick to avoid to use wrongly a depth buffer
|
// Let's try a trick to avoid to use wrongly a depth buffer
|
||||||
// Unfortunately, I don't have any Arc the Lad testcase
|
// Unfortunately, I don't have any Arc the Lad testcase
|
||||||
@ -2172,7 +2186,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src = CreateSource(src_TEX0, TEXA, dst, x_offset, y_offset, lod, &rect, gpu_clut, region);
|
src = CreateSource(src_TEX0, TEXA, dst, x_offset, y_offset, lod, &rect, gpu_clut, region, target_bp_hit_outside_valid_area);
|
||||||
if (!src) [[unlikely]]
|
if (!src) [[unlikely]]
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -5773,7 +5787,7 @@ void GSTextureCache::IncAge()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work.
|
//Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work.
|
||||||
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region)
|
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region, bool target_bp_hit)
|
||||||
{
|
{
|
||||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
||||||
Source* src = new Source(TEX0, TEXA);
|
Source* src = new Source(TEX0, TEXA);
|
||||||
@ -6239,7 +6253,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GSUtil::GetChannelMask(TEX0.PSM) == 0xf && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.Block() && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->ZBUF.Block())
|
if (GSUtil::GetChannelMask(TEX0.PSM) == 0xf && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.Block() && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->ZBUF.Block() && !target_bp_hit)
|
||||||
{
|
{
|
||||||
// Kill any possible targets we missed, they might be wrong now.
|
// Kill any possible targets we missed, they might be wrong now.
|
||||||
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, TEX0.TBP0, TEX0.PSM, GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.FBMSK, true);
|
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, TEX0.TBP0, TEX0.PSM, GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.FBMSK, true);
|
||||||
@ -6247,7 +6261,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
// kill source immediately after the draw if it's the RT, because that'll get invalidated immediately.
|
// kill source immediately after the draw if it's the RT, because that'll get invalidated immediately.
|
||||||
if (GSRendererHW::GetInstance()->IsTBPFrameOrZ(TEX0.TBP0, true) && GSRendererHW::GetInstance()->ChannelsSharedTEX0FRAME())
|
if (target_bp_hit || (GSRendererHW::GetInstance()->IsTBPFrameOrZ(TEX0.TBP0, true) && GSRendererHW::GetInstance()->ChannelsSharedTEX0FRAME()))
|
||||||
{
|
{
|
||||||
GL_CACHE("TC: Source == RT before RT creation, invalidating after draw.");
|
GL_CACHE("TC: Source == RT before RT creation, invalidating after draw.");
|
||||||
m_temporary_source = src;
|
m_temporary_source = src;
|
||||||
|
|||||||
@ -445,7 +445,7 @@ protected:
|
|||||||
std::unique_ptr<GSDownloadTexture> m_uint16_download_texture;
|
std::unique_ptr<GSDownloadTexture> m_uint16_download_texture;
|
||||||
std::unique_ptr<GSDownloadTexture> m_uint32_download_texture;
|
std::unique_ptr<GSDownloadTexture> m_uint32_download_texture;
|
||||||
|
|
||||||
Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region);
|
Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t, int x_offset, int y_offset, const GSVector2i* lod, const GSVector4i* src_range, GSTexture* gpu_clut, SourceRegion region, bool force_temporary = false);
|
||||||
|
|
||||||
bool PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, bool is_frame,
|
bool PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, bool is_frame,
|
||||||
bool preload, bool preserve_target, const GSVector4i draw_rect, Target* dst, GSTextureCache::Source* src = nullptr);
|
bool preload, bool preserve_target, const GSVector4i draw_rect, Target* dst, GSTextureCache::Source* src = nullptr);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user