GS/TC: Break LookupTarget() into 3 functions.

Separate draw lookup from frame lookup. Put common code in another processing function.
This commit is contained in:
TJnotJT
2026-04-17 20:17:46 +02:00
committed by lightningterror
parent fa9c99a948
commit 09fcc4d60e
4 changed files with 800 additions and 725 deletions
+19 -19
View File
@@ -50,8 +50,8 @@ bool GSHwHack::GSC_IRem(GSRendererHW& r, int& skip)
GIFRegTEX0 RTLookup = GIFRegTEX0::Create(RTBP0, RFBW, RFPSM);
GSTextureCache::Source* src = g_texture_cache->LookupSource(true, RTLookup, r.m_cached_ctx.TEXA, r.m_cached_ctx.CLAMP, GSVector4i(0, 0, 1, 1), nullptr, true, false, r.m_cached_ctx.FRAME, true, true);
GSTextureCache::Target* rt = g_texture_cache->LookupTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget, true, 0, false, false, true, true, GSVector4i(0, 0, 1, 1), true, false, true, src);
GSTextureCache::Target* rt = g_texture_cache->LookupDrawTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget, true, 0, false, true, true, GSVector4i(0, 0, 1, 1), true, false, true, src);
if (!rt)
return false;
@@ -138,8 +138,8 @@ bool GSHwHack::GSC_IRem(GSRendererHW& r, int& skip)
GIFRegTEX0 RTLookup = GIFRegTEX0::Create(RTBP0, RFBW, RFPSM);
GSTextureCache::Source* src = g_texture_cache->LookupSource(true, RTLookup, r.m_cached_ctx.TEXA, r.m_cached_ctx.CLAMP, GSVector4i(0,0,1,1), nullptr, true, false, r.m_cached_ctx.FRAME, true, true);
GSTextureCache::Target* rt = g_texture_cache->LookupTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget, true, 0, false, false, true, true, GSVector4i(0,0,1,1), true, false, true, src);
GSTextureCache::Target* rt = g_texture_cache->LookupDrawTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget, true, 0, false, true, true, GSVector4i(0,0,1,1), true, false, true, src);
if (!rt)
return false;
@@ -283,7 +283,7 @@ bool GSHwHack::GSC_DTGames(GSRendererHW& r, int& skip)
// The further problem to this is the limitation of alpha we can save on an RT as they copy in 255, so I can cheese it here pretending it's RTA'd
if (RTME && RFPSM == PSMCT32 && RTBP0 == RFBP && RTPSM == PSMCT16 && RTEST.ATE && RTEST.ATST == ATST_NEVER && RTEST.AFAIL == AFAIL_FB_ONLY && RFBMSK == 0xFFFFFF)
{
GSTextureCache::Target* rt = g_texture_cache->LookupTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSTextureCache::Target* rt = g_texture_cache->LookupDrawTarget(GIFRegTEX0::Create(RTBP0, RFBW, RFPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget);
if (!rt)
@@ -373,13 +373,13 @@ bool GSHwHack::GSC_SandGrainGames(GSRendererHW& r, int& skip)
if (r.PRIM->PRIM == GS_SPRITE && RTME && RFPSM == PSMCT16S && RTPSM == PSMZ16S && next_ctx.TEX0.TBP0 == RFBP && next_ctx.TEX0.PSM == PSMT8H)
{
GSTextureCache::Target* texsrc = g_texture_cache->LookupTarget(GIFRegTEX0::Create(RTBP0, RTBW, RTPSM),
GSTextureCache::Target* texsrc = g_texture_cache->LookupDrawTarget(GIFRegTEX0::Create(RTBP0, RTBW, RTPSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::DepthStencil);
if (!texsrc)
return false;
GSTextureCache::Target* rt = g_texture_cache->LookupTarget(GIFRegTEX0::Create(next_ctx.FRAME.Block(), next_ctx.FRAME.FBW, next_ctx.FRAME.PSM),
GSTextureCache::Target* rt = g_texture_cache->LookupDrawTarget(GIFRegTEX0::Create(next_ctx.FRAME.Block(), next_ctx.FRAME.FBW, next_ctx.FRAME.PSM),
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget);
if (!rt)
@@ -468,7 +468,7 @@ bool GSHwHack::GSC_BurnoutGames(GSRendererHW& r, int& skip)
break;
// Next draw should contain our source.
GSTextureCache::Target* tgt = g_texture_cache->LookupTarget(r.m_env.CTXT[r.m_backed_up_ctx].TEX0,
GSTextureCache::Target* tgt = g_texture_cache->LookupDrawTarget(r.m_env.CTXT[r.m_backed_up_ctx].TEX0,
GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget);
if (!tgt)
break;
@@ -718,8 +718,8 @@ bool GSHwHack::GSC_PolyphonyDigitalGames(GSRendererHW& r, int& skip)
return false;
}
GSTextureCache::Target* src = g_texture_cache->LookupTarget(RTEX0, GSVector2i(1, 1), r.GetTextureScaleFactor(),
GSTextureCache::RenderTarget, true, 0, false, false, true, true, GSVector4i::zero(), true);
GSTextureCache::Target* src = g_texture_cache->LookupDrawTarget(RTEX0, GSVector2i(1, 1), r.GetTextureScaleFactor(),
GSTextureCache::RenderTarget, true, 0, false, true, true, GSVector4i::zero(), true);
if (!src)
return false;
@@ -777,7 +777,7 @@ bool GSHwHack::GSC_PolyphonyDigitalGames(GSRendererHW& r, int& skip)
for (u32 channel = 0; channel < 3; channel++)
{
const GIFRegTEX0 TEX0 = GIFRegTEX0::Create(base + channel * page_offset, 10, PSMCT32);
GSTextureCache::Target* dst = g_texture_cache->LookupTarget(TEX0, src->GetUnscaledSize(), src->GetScale(), GSTextureCache::RenderTarget, true, fbmsk);
GSTextureCache::Target* dst = g_texture_cache->LookupDrawTarget(TEX0, src->GetUnscaledSize(), src->GetScale(), GSTextureCache::RenderTarget, true, fbmsk);
if (!dst)
{
dst = g_texture_cache->CreateTarget(TEX0, size, size, src->GetScale(), GSTextureCache::RenderTarget, true, fbmsk);
@@ -822,7 +822,7 @@ bool GSHwHack::GSC_Battlefield2(GSRendererHW& r, int& skip)
GIFRegTEX0 TEX0 = {};
TEX0.TBP0 = RFBP;
TEX0.TBW = 8;
GSTextureCache::Target* dst = g_texture_cache->LookupTarget(TEX0, r.GetTargetSize(), r.GetTextureScaleFactor(), GSTextureCache::DepthStencil);
GSTextureCache::Target* dst = g_texture_cache->LookupDrawTarget(TEX0, r.GetTargetSize(), r.GetTextureScaleFactor(), GSTextureCache::DepthStencil);
if (!dst)
dst = g_texture_cache->CreateTarget(TEX0, r.GetTargetSize(), r.GetValidSize(nullptr), r.GetTextureScaleFactor(), GSTextureCache::DepthStencil,
@@ -1067,7 +1067,7 @@ bool GSHwHack::OI_RozenMaidenGebetGarden(GSRendererHW& r, GSTexture* rt, GSTextu
TEX0.TBW = RFRAME.FBW;
TEX0.PSM = RFRAME.PSM;
if (GSTextureCache::Target* tmp_rt = g_texture_cache->LookupTarget(TEX0, r.GetTargetSize(), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget))
if (GSTextureCache::Target* tmp_rt = g_texture_cache->LookupDrawTarget(TEX0, r.GetTargetSize(), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget))
{
GL_INS("OI_RozenMaidenGebetGarden FB clear");
g_gs_device->ClearRenderTarget(tmp_rt->m_texture, 0);
@@ -1089,7 +1089,7 @@ bool GSHwHack::OI_RozenMaidenGebetGarden(GSRendererHW& r, GSTexture* rt, GSTextu
TEX0.TBW = RFRAME.FBW;
TEX0.PSM = RZBUF.PSM;
if (GSTextureCache::Target* tmp_ds = g_texture_cache->LookupTarget(TEX0, r.GetTargetSize(), r.GetTextureScaleFactor(), GSTextureCache::DepthStencil))
if (GSTextureCache::Target* tmp_ds = g_texture_cache->LookupDrawTarget(TEX0, r.GetTargetSize(), r.GetTextureScaleFactor(), GSTextureCache::DepthStencil))
{
GL_INS("OI_RozenMaidenGebetGarden ZB clear");
g_gs_device->ClearDepth(tmp_ds->m_texture, 0.0f);
@@ -1122,14 +1122,14 @@ bool GSHwHack::OI_SonicUnleashed(GSRendererHW& r, GSTexture* rt, GSTexture* ds,
GL_INS("OI_SonicUnleashed replace draw by a copy draw %lld", r.s_n);
GSTextureCache::Target* src = g_texture_cache->LookupTarget(Texture, GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget, true, 0, false, false, true, true, GSVector4i::zero(), true);
GSTextureCache::Target* src = g_texture_cache->LookupDrawTarget(Texture, GSVector2i(1, 1), r.GetTextureScaleFactor(), GSTextureCache::RenderTarget, true, 0, false, true, true, GSVector4i::zero(), true);
if (!src)
return true;
const GSVector2i src_size(src->m_texture->GetSize());
GSTextureCache::Target* rt_again = g_texture_cache->LookupTarget(Frame, src_size, src->m_scale, GSTextureCache::RenderTarget);
GSTextureCache::Target* rt_again = g_texture_cache->LookupDrawTarget(Frame, src_size, src->m_scale, GSTextureCache::RenderTarget);
if ((rt_again->m_TEX0.PSM & 0x3) == PSMCT16)
{
GSVector4 dRect;
@@ -1284,15 +1284,15 @@ static bool GetMoveTargetPair(GSRendererHW& r, GSTextureCache::Target** src, GIF
const int src_type =
GSLocalMemory::m_psm[src_desc.PSM].depth ? GSTextureCache::DepthStencil : GSTextureCache::RenderTarget;
GSTextureCache::Target* tsrc =
g_texture_cache->LookupTarget(src_desc, GSVector2i(1, 1), r.GetTextureScaleFactor(), src_type);
g_texture_cache->LookupDrawTarget(src_desc, GSVector2i(1, 1), r.GetTextureScaleFactor(), src_type);
if (!tsrc)
return false;
// The target might not.
const int dst_type =
GSLocalMemory::m_psm[dst_desc.PSM].depth ? GSTextureCache::DepthStencil : GSTextureCache::RenderTarget;
GSTextureCache::Target* tdst = g_texture_cache->LookupTarget(dst_desc, tsrc->GetUnscaledSize(), tsrc->GetScale(),
dst_type, true, 0, false, false, preserve_target, preserve_target, tsrc->GetUnscaledRect());
GSTextureCache::Target* tdst = g_texture_cache->LookupDrawTarget(dst_desc, tsrc->GetUnscaledSize(), tsrc->GetScale(),
dst_type, true, 0, false, preserve_target, preserve_target, tsrc->GetUnscaledRect());
if (!tdst)
{
if (req_target)
+8 -8
View File
@@ -3000,8 +3000,8 @@ void GSRendererHW::Draw()
FRAME.TBW = m_conf.colclip_frame.FBW;
FRAME.PSM = m_conf.colclip_frame.PSM;
GSTextureCache::Target* old_rt = g_texture_cache->LookupTarget(FRAME, GSVector2i(1, 1), GetTextureScaleFactor(), GSTextureCache::RenderTarget, true,
fm, false, false, true, true, GSVector4i(0, 0, 1, 1), true, false, false);
GSTextureCache::Target* old_rt = g_texture_cache->LookupDrawTarget(FRAME, GSVector2i(1, 1), GetTextureScaleFactor(), GSTextureCache::RenderTarget, true,
fm, false, true, true, GSVector4i(0, 0, 1, 1), true, false, false);
if (old_rt)
{
@@ -3686,8 +3686,8 @@ void GSRendererHW::Draw()
ZBUF_TEX0.TBW = m_cached_ctx.FRAME.FBW;
ZBUF_TEX0.PSM = m_cached_ctx.ZBUF.PSM;
ds = g_texture_cache->LookupTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
m_cached_ctx.DepthWrite(), 0, false, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block(), !no_rt,
ds = g_texture_cache->LookupDrawTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
m_cached_ctx.DepthWrite(), 0, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block(), !no_rt,
src, nullptr, -1);
ZBUF_TEX0.TBW = m_channel_shuffle ? src->m_from_target_TEX0.TBW : m_cached_ctx.FRAME.FBW;
@@ -3946,8 +3946,8 @@ void GSRendererHW::Draw()
// Of course if this size is different (in width) or this is a shuffle happening, this will be bypassed.
const bool preserve_downscale_draw = (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && ((std::abs(scale_draw) == 1 && !scaled_copy) || (scale_draw == 0 && src && src->m_from_target && src->m_from_target->m_downscaled))) || is_possible_mem_clear == ClearType::ClearWithDraw;
rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, ((src && src->m_scale != 1) && (GSConfig.UserHacks_NativeScaling == GSNativeScaling::Normal || GSConfig.UserHacks_NativeScaling == GSNativeScaling::NormalUpscaled) && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, lookup_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(),
rt = g_texture_cache->LookupDrawTarget(FRAME_TEX0, t_size, ((src && src->m_scale != 1) && (GSConfig.UserHacks_NativeScaling == GSNativeScaling::Normal || GSConfig.UserHacks_NativeScaling == GSNativeScaling::NormalUpscaled) && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
fm, force_preload, preserve_rt_rgb, preserve_rt_alpha, lookup_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(),
GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && preserve_downscale_draw && is_possible_mem_clear != ClearType::NormalClear, src, ds, (no_ds || !ds) ? -1 : (m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0));
// Draw skipped because it was a clear and there was no target.
@@ -4328,8 +4328,8 @@ void GSRendererHW::Draw()
ZBUF_TEX0.TBW = m_cached_ctx.FRAME.FBW;
ZBUF_TEX0.PSM = m_cached_ctx.ZBUF.PSM;
ds = g_texture_cache->LookupTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
m_cached_ctx.DepthWrite(), 0, false, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block(), false,
ds = g_texture_cache->LookupDrawTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
m_cached_ctx.DepthWrite(), 0, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block(), false,
src, nullptr, -1);
ZBUF_TEX0.TBW = m_channel_shuffle ? src->m_from_target_TEX0.TBW : m_cached_ctx.FRAME.FBW;
File diff suppressed because it is too large Load Diff
+31 -5
View File
@@ -30,6 +30,8 @@ public:
constexpr static u32 MAX_BP = 0x3fff;
constexpr static GSVector4 FullSrcRect = GSVector4::cxpr(0.0f, 0.0f, 1.0f, 1.0f);
constexpr static bool CheckOverlap(const u32 a_bp, const u32 a_bp_end, const u32 b_bp, const u32 b_bp_end) noexcept
{
u32 b_bp_start_synced = b_bp;
@@ -485,6 +487,20 @@ protected:
Source* CreateMergedSource(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, SourceRegion region, float scale);
// Used in target lookup functions to determine new sizes of targets.
struct RescaleHelper
{
RescaleHelper(const GSVector2i& size, float scale);
void CalcRescale(const Target* tgt);
void SetNewSize(const GSVector2i& new_size, float scale);
const GSVector2i m_size;
float m_scale;
GSVector2i m_new_size{};
GSVector2i m_new_scaled_size{};
GSVector4 m_dRect{};
bool m_clear = true;
};
public:
GSTextureCache();
~GSTextureCache();
@@ -516,14 +532,24 @@ public:
Target* FindTargetOverlap(Target* target, int type, int psm);
void CombineAlignedInsideTargets(Target* target, GSTextureCache::Source* src = nullptr);
Target* LookupTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type, bool used = true, u32 fbmask = 0,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false, bool possible_clear = false, bool preserve_scale = false, GSTextureCache::Source* src = nullptr, GSTextureCache::Target* ds = nullptr, int offset = -1);
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, float scale, int type, bool used = true, u32 fbmask = 0,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_target = true,
private:
Target* ProcessTargetAfterLookup(RescaleHelper& rescaler, Target* dst, GIFRegTEX0 TEX0, const GSVector2i& size, int type,
bool used, u32 fbmask, bool is_frame, bool preload, bool preserve_rgb = true, bool preserve_alpha = true,
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false, bool possible_clear = false,
bool preserve_scale = false, GSTextureCache::Source* src = nullptr, GSTextureCache::Target* ds = nullptr, int offset = -1);
public:
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, float scale, int type, bool used = true,
u32 fbmask = 0, bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_target = true,
const GSVector4i draw_rc = GSVector4i::zero(), GSTextureCache::Source* src = nullptr);
Target* LookupDisplayTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, bool is_feedback);
Target* LookupDrawTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type, bool used = true, u32 fbmask = 0,
bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false, bool possible_clear = false, bool preserve_scale = false, GSTextureCache::Source* src = nullptr, GSTextureCache::Target* ds = nullptr, int offset = -1);
/// Looks up a target in the cache, and only returns it if the BP/BW match exactly.
Target* GetExactTarget(u32 BP, u32 BW, int type, u32 end_bp);
Target* GetTargetWithSharedBits(u32 BP, u32 PSM) const;