From 982fd42683fbab1eca3d32d49a020bd57f1b90fd Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Mon, 13 Feb 2023 15:45:15 +0000 Subject: [PATCH] GS: Preload whenever it matches an upload. GUI option forces preloads. --- pcsx2/GS/GSState.cpp | 43 +++++++++++++----------- pcsx2/GS/GSState.h | 1 + pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 13 ++++--- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 14 ++++---- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index a776d83599..e34d4aea11 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -1758,14 +1758,18 @@ void GSState::Write(const u8* mem, int len) // Invalid the CLUT if it crosses paths. m_mem.m_clut.InvalidateRange(write_start_bp, write_end_bp); - if (GSConfig.PreloadFrameWithGSData) + GSVector4i r; + + r.left = m_env.TRXPOS.DSAX; + r.top = m_env.TRXPOS.DSAY; + r.right = r.left + m_env.TRXREG.RRW; + r.bottom = r.top + m_env.TRXREG.RRH; + + // Store the transfer for preloading new RT's. + if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && blit.DBP != m_draw_transfers.back().blit.DBP)) { - // Store the transfer for preloading new RT's. - if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && blit.DBP != m_draw_transfers.back().blit.DBP)) - { - GSUploadQueue new_transfer = { blit, s_n }; - m_draw_transfers.push_back(new_transfer); - } + GSUploadQueue new_transfer = { blit, r, s_n }; + m_draw_transfers.push_back(new_transfer); } GL_CACHE("Write! ... => 0x%x W:%d F:%s (DIR %d%d), dPos(%d %d) size(%d %d)", @@ -1776,12 +1780,6 @@ void GSState::Write(const u8* mem, int len) if (m_tr.end == 0 && len >= m_tr.total) { // received all data in one piece, no need to buffer it - GSVector4i r; - - r.left = m_env.TRXPOS.DSAX; - r.top = m_env.TRXPOS.DSAY; - r.right = r.left + m_env.TRXREG.RRW; - r.bottom = r.top + m_env.TRXREG.RRH; ExpandTarget(m_env.BITBLTBUF, r); InvalidateVideoMem(blit, r, true); @@ -1917,15 +1915,20 @@ void GSState::Move() Flush(GSFlushReason::LOCALTOLOCALMOVE); } - if (GSConfig.PreloadFrameWithGSData) + // Store the transfer for preloading new RT's. + if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && dbp != m_draw_transfers.back().blit.DBP)) { - // Store the transfer for preloading new RT's. - if (m_draw_transfers.size() == 0 || (m_draw_transfers.size() > 0 && dbp != m_draw_transfers.back().blit.DBP)) - { - GSUploadQueue new_transfer = { m_env.BITBLTBUF, s_n }; - m_draw_transfers.push_back(new_transfer); - } + GSVector4i r; + + r.left = m_env.TRXPOS.DSAX; + r.top = m_env.TRXPOS.DSAY; + r.right = r.left + m_env.TRXREG.RRW; + r.bottom = r.top + m_env.TRXREG.RRH; + + GSUploadQueue new_transfer = { m_env.BITBLTBUF, r, s_n }; + m_draw_transfers.push_back(new_transfer); } + // Invalid the CLUT if it crosses paths. m_mem.m_clut.InvalidateRange(write_start_bp, write_end_bp); diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index e16401c807..92062114d9 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -209,6 +209,7 @@ public: struct GSUploadQueue { GIFRegBITBLTBUF blit; + GSVector4i rect; int draw; }; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 8092669e42..adc6b56713 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -166,10 +166,15 @@ void GSRendererHW::VSync(u32 field, bool registers_written) if ((s_n - iter->draw) > 5) iter = m_draw_transfers.erase(iter); else + { iter++; + } + } } } + else + m_draw_transfers.clear(); if (GSConfig.LoadTextureReplacements) GSTextureReplacements::ProcessAsyncLoadedTextures(); @@ -1328,7 +1333,7 @@ void GSRendererHW::Draw() } // SW CLUT Render enable. - bool preload = GSConfig.PreloadFrameWithGSData | (m_force_preload > 0); + bool force_preload = GSConfig.PreloadFrameWithGSData; if (GSConfig.UserHacks_CPUCLUTRender > 0 || GSConfig.UserHacks_GPUTargetCLUTMode != GSGPUTargetCLUTMode::Disabled) { const CLUTDrawTestResult result = (GSConfig.UserHacks_CPUCLUTRender == 2) ? PossibleCLUTDrawAggressive() : PossibleCLUTDraw(); @@ -1349,7 +1354,7 @@ void GSRendererHW::Draw() !IsOpaque()) // Blending enabled { GL_INS("Forcing preload due to partial/blended CLUT draw"); - preload = m_force_preload = true; + force_preload = true; } } } @@ -1556,7 +1561,7 @@ void GSRendererHW::Draw() GSTextureCache::Target* rt = nullptr; if (!no_rt) - rt = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::RenderTarget, true, fm, false, unscaled_target_size.x, unscaled_target_size.y, preload); + rt = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::RenderTarget, true, fm, false, unscaled_target_size.x, unscaled_target_size.y, force_preload); TEX0.TBP0 = context->ZBUF.Block(); TEX0.TBW = context->FRAME.FBW; @@ -1564,7 +1569,7 @@ void GSRendererHW::Draw() GSTextureCache::Target* ds = nullptr; if (!no_ds) - ds = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::DepthStencil, context->DepthWrite(), 0, false, 0, 0, preload); + ds = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::DepthStencil, context->DepthWrite(), 0, false, unscaled_target_size.x, unscaled_target_size.y, force_preload); if (process_texture) { diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 3679f3db82..685d22ab10 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -775,19 +775,22 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con // From a performance point of view, it might cost a little on big upscaling // but normally few RT are miss so it must remain reasonable. const bool supported_fmt = !GSConfig.UserHacks_DisableDepthSupport || psm_s.depth == 0; - const bool forced_preload = GSRendererHW::GetInstance()->m_force_preload > 0; - if ((is_frame || preload || forced_preload) && TEX0.TBW > 0 && supported_fmt) + + if (TEX0.TBW > 0 && supported_fmt) { - if (!is_frame && !forced_preload) + const bool forced_preload = GSRendererHW::GetInstance()->m_force_preload > 0; + const GSVector4i newrect = GSVector4i(0, 0, real_w, real_h); + + if (!is_frame && !forced_preload && !preload) { std::vector::iterator iter; for (iter = GSRendererHW::GetInstance()->m_draw_transfers.begin(); iter != GSRendererHW::GetInstance()->m_draw_transfers.end(); ) { - if (iter->blit.DBP == TEX0.TBP0 && GSUtil::HasSharedBits(iter->blit.DPSM, TEX0.PSM)) + // If the format, and location doesn't match, but also the upload is at least the size of the target, don't preload. + if (iter->blit.DBP == TEX0.TBP0 && GSUtil::HasCompatibleBits(iter->blit.DPSM, TEX0.PSM) && iter->rect.rintersect(newrect).eq(newrect)) { GSRendererHW::GetInstance()->m_draw_transfers.erase(iter); GL_INS("Preloading the RT DATA"); - const GSVector4i newrect = GSVector4i(0, 0, real_w, real_h); AddDirtyRectTarget(dst, newrect, TEX0.PSM, TEX0.TBW); dst->Update(true); break; @@ -798,7 +801,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con else { GL_INS("Preloading the RT DATA"); - const GSVector4i newrect = GSVector4i(0, 0, real_w, real_h); AddDirtyRectTarget(dst, newrect, TEX0.PSM, TEX0.TBW); dst->Update(true); }