GS-HW: Try to make Preload Frame Data slightly less gross.

These changes make sure there's a matching EE transfer to texture allocation in that frame, if not, then don't allocate anything. This should reduce bad data being loaded in to the Rt.

Preload replaced for Simple 2000 Series Vol. 114 - The Onna Okappichi Torimonochou, preload worked by chance (but no more), disable depth works.
This commit is contained in:
refractionpcsx2 2023-01-29 10:24:58 +00:00
parent ee0042c768
commit 5697759d9e
5 changed files with 68 additions and 46 deletions

View File

@ -36452,7 +36452,7 @@ SLPS-20489:
name: "Simple 2000 Series Vol. 114 - The Onna Okappichi Torimonochou - Oharu-chan GoGoGo!"
region: "NTSC-J"
gsHWFixes:
preloadFrameData: 1 # Fixes black screen in-game.
disableDepthSupport: 1 # Fixes black screen in-game.
getSkipCount: "GSC_Simple2000Vol114"
SLPS-20490:
name: "Pachi-Slot Club Collection - IM Juggler EX - Juggler Selection"

View File

@ -147,6 +147,8 @@ void GSState::Reset(bool hardware_reset)
m_env.Reset();
m_draw_transfers.clear();
PRIM = &m_env.PRIM;
UpdateContext();
@ -1984,7 +1986,11 @@ void GSState::Write(const u8* mem, int len)
if (!m_tr.Update(w, h, psm.trbpp, len))
return;
if (GSConfig.PreloadFrameWithGSData)
{
// Store the transfer for preloading new RT's.
m_draw_transfers.push_front(blit);
}
GIFRegTEX0& prev_tex0 = m_prev_env.CTXT[m_prev_env.PRIM.CTXT].TEX0;

View File

@ -222,6 +222,7 @@ public:
bool m_mipmap;
u32 m_dirty_gs_regs;
int m_backed_up_ctx;
std::list<GIFRegBITBLTBUF> m_draw_transfers;
static int s_n;

View File

@ -1704,7 +1704,7 @@ void GSRendererHW::Draw()
GSTextureCache::Target* rt = nullptr;
if (!no_rt)
rt = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::RenderTarget, true, fm, false, 0, 0, preload);
rt = m_tc->LookupTarget(TEX0, t_size, GSTextureCache::RenderTarget, true, fm, false, unscaled_size.x, unscaled_size.y, preload);
TEX0.TBP0 = context->ZBUF.Block();
TEX0.TBW = context->FRAME.FBW;

View File

@ -17,6 +17,7 @@
#include "GSTextureCache.h"
#include "GSTextureReplacements.h"
#include "GSRendererHW.h"
#include "GS/GSState.h"
#include "GS/GSGL.h"
#include "GS/GSIntrin.h"
#include "GS/GSUtil.h"
@ -702,19 +703,34 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
bool supported_fmt = !GSConfig.UserHacks_DisableDepthSupport || psm_s.depth == 0;
if ((is_frame || preload) && TEX0.TBW > 0 && supported_fmt)
{
GL_INS("Preloading the RT DATA");
// RT doesn't have height but if we use a too big value, we will read outside of the GS memory.
int page0 = TEX0.TBP0 >> 5;
int max_page = (MAX_PAGES - page0);
int max_h = 32 * max_page / TEX0.TBW;
// h is likely smaller than w (true most of the time). Reduce the upload size (speed)
max_h = std::min<int>(max_h, TEX0.TBW * 64);
if (!is_frame)
{
// Check for an EE transfer that matches our RT.
while (static_cast<GSRendererHW*>(g_gs_renderer.get())->m_draw_transfers.size() > 0)
{
const GIFRegBITBLTBUF* transfer = &static_cast<GSRendererHW*>(g_gs_renderer.get())->m_draw_transfers.front();
const GSVector4i newrect = GSVector4i(0, 0, TEX0.TBW * 64, is_frame ? real_h : max_h);
if (transfer->DBP == TEX0.TBP0 && GSUtil::HasSharedBits(transfer->DPSM, TEX0.PSM))
{
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;
}
static_cast<GSRendererHW*>(g_gs_renderer.get())->m_draw_transfers.pop_front();
}
}
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);
}
}
static_cast<GSRendererHW*>(g_gs_renderer.get())->m_draw_transfers.clear();
}
if (used)
{
dst->m_used = true;
@ -1116,8 +1132,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
r.x,
r.y,
r.z,
r.w
);
r.w);
}
if (!ComputeSurfaceOffset(off, r, t).is_valid)
{