diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index e1080d0527..1784764bf8 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -2518,7 +2518,7 @@ void GSRendererHW::Draw() rt->m_TEX0 = FRAME_TEX0; } - if (ds && (!is_possible_mem_clear || ds->m_TEX0.PSM != ZBUF_TEX0.PSM)) + if (ds && (!is_possible_mem_clear || ds->m_TEX0.PSM != ZBUF_TEX0.PSM || (rt && ds->m_TEX0.TBW != rt->m_TEX0.TBW))) ds->m_TEX0 = ZBUF_TEX0; } else if (!m_texture_shuffle) @@ -2782,12 +2782,6 @@ void GSRendererHW::Draw() // Temporary source *must* be invalidated before normal, because otherwise it'll be double freed. g_texture_cache->InvalidateTemporarySource(); - // Set the RT format back to 32bits after the shuffle. - if (rt && m_texture_shuffle && rt->m_32_bits_fmt) - { - rt->m_TEX0.PSM = PSMCT32; - } - // Invalidation of old targets when changing to double-buffering. if (old_rt) g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, old_rt->m_TEX0.TBP0); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index be8af1e811..1e25abf7e7 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -123,7 +123,7 @@ private: // We modify some of the context registers to optimize away unnecessary operations. // Instead of messing with the real context, we copy them and use those instead. - struct + struct HWCachedCtx { GIFRegTEX0 TEX0; GIFRegCLAMP CLAMP; @@ -143,7 +143,7 @@ private: return ZBUF.ZMSK == 0 && TEST.ZTE != 0; // ZTE == 0 is bug on the real hardware, write is blocked then } - } m_cached_ctx; + }; // CRC Hacks bool IsBadFrame(); @@ -174,6 +174,7 @@ private: GSVector2i m_lod = {}; // Min & Max level of detail GSHWDrawConfig m_conf = {}; + HWCachedCtx m_cached_ctx; // software sprite renderer state std::vector m_sw_vertex_buffer; @@ -185,7 +186,7 @@ public: virtual ~GSRendererHW() override; __fi static GSRendererHW* GetInstance() { return static_cast(g_gs_renderer.get()); } - + __fi HWCachedCtx* GetCachedCtx() { return &m_cached_ctx; } void Destroy() override; void UpdateRenderFixes() override; diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 6522ad3830..12ea14dc9d 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -4008,6 +4008,13 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con } else { + if (GSUtil::GetChannelMask(TEX0.PSM) == 0xf && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.Block() && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->ZBUF.Block()) + { + // Kill any possible targets we missed, they might be wrong now. + g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, TEX0.TBP0, TEX0.PSM, GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.FBMSK, true); + g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, TEX0.TBP0, TEX0.PSM, GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.FBMSK, true); + } + // maintain the clut even when paltex is on for the dump/replacement texture lookup bool paltex = (GSConfig.GPUPaletteConversion && psm.pal > 0) || gpu_clut; const u32* clut = (psm.pal > 0) ? static_cast(g_gs_renderer->m_mem.m_clut) : nullptr; diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.h b/pcsx2/GS/Renderers/HW/GSTextureCache.h index 496e6da471..c0d5786871 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.h +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.h @@ -495,7 +495,7 @@ public: bool Has32BitTarget(u32 bp); void InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 write_psm = PSMCT32); - void InvalidateVideoMemType(int type, u32 bp, u32 write_psm = PSMCT32, u32 write_fbmsk = 0); + void InvalidateVideoMemType(int type, u32 bp, u32 write_psm = PSMCT32, u32 write_fbmsk = 0, bool dirty_only = false); void InvalidateVideoMemSubTarget(GSTextureCache::Target* rt); void InvalidateVideoMem(const GSOffset& off, const GSVector4i& r, bool target = true); void InvalidateLocalMem(const GSOffset& off, const GSVector4i& r, bool full_flush = false);