From 25338fb4f29631ee60608757023a0fc3a4636336 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Sat, 25 Jan 2025 20:35:32 +0000 Subject: [PATCH] GS/HW: Predict valid sizes based on repeated draws and scissor - this should be okay/limited to certain situations like Battlefield 2. Scissor isn't 100% guaranteed to be right, but it's probably better than nothing. --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index fbddb612aa..953d26ca38 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -950,6 +950,12 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex) // e.g. Burnout 3, God of War II, etc. int height = std::min(m_context->scissor.in.w, m_r.w); + // We can check if the next draw is doing the same from the next page, and assume it's a per line clear. + // Battlefield 2 does this. + int pages = ((GSLocalMemory::GetEndBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r) + 1) - m_cached_ctx.FRAME.Block()) >> 5; + if (m_cached_ctx.FRAME.FBW > 1 && m_r.height() <= 64 && (pages % m_cached_ctx.FRAME.FBW) == 0 && m_env.CTXT[m_backed_up_ctx].FRAME.FBP == (m_cached_ctx.FRAME.FBP + pages) && NextDrawMatchesShuffle()) + height = std::max(m_context->scissor.in.w, height); + // If the draw is less than a page high, FBW=0 is the same as FBW=1. const GSLocalMemory::psm_t& frame_psm = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM]; int width = std::min(std::max(m_cached_ctx.FRAME.FBW, 1) * 64, m_context->scissor.in.z);