From 645fad366c876d33e9b58dfa6543e31e3d06043e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 23 Apr 2024 17:31:47 +1000 Subject: [PATCH 1/2] GS/HW: Stretch double buffered targets when scale changes Otherwise the coordinates are out of range => GPU crash. --- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 8a879975fd953..904a4b0deab37 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -2586,7 +2586,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons // Clear the dirty first dst->Update(); // Invalidate has been moved to after DrawPrims(), because we might kill the current sources' backing. - if (!t->m_valid_rgb || !(t->m_valid_alpha_high || t->m_valid_alpha_low)) + if (!t->m_valid_rgb || !(t->m_valid_alpha_high || t->m_valid_alpha_low) || t->m_scale != dst->m_scale) { const GSVector4 src_rect = GSVector4(0, 0, copy_width, copy_height) / (GSVector4(t->m_texture->GetSize()).xyxy()); const GSVector4 dst_rect = GSVector4(0, dst_offset, copy_width, copy_height); From 1e573f26df66480c2d77b08709d85b61e9c67570 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 23 Apr 2024 17:32:34 +1000 Subject: [PATCH 2/2] GS/HW: Check for format combinations that make sense for CSBW True Crime: New York City strikes again... --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 5e3316ddc639d..87f0b6cc2ee39 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -6219,6 +6219,14 @@ bool GSRendererHW::CanUseSwPrimRender(bool no_rt, bool no_ds, bool draw_sprite_t if (!rc.GetDirtyRect(m_cached_ctx.TEX0, false).rintersect(tr).rempty()) return true; } + + // Make sure it actually makes sense to use this target as a source, given the formats, and it wouldn't just sample as garbage. + // We can't rely exclusively on the dirty rect check above, because sometimes the targets are from older frames and too large. + if (!GSUtil::HasSameSwizzleBits(m_cached_ctx.TEX0.PSM, src_target->m_TEX0.PSM) && + (!src_target->m_32_bits_fmt || GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp != 16)) + { + return true; + } } return false;