From 66872a20e69afb42c430e8657aa9fe4ab11e206b Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 4 Jan 2024 15:28:49 +1000 Subject: [PATCH 1/2] GS/HW: Handle offset RTs when offset texture is detected Catwoman draws to the target at 2E60 via 2D00, one page back horizontally, and one vertically. The Destroy All Humans fix also works here, but it only applied to the texture, not the RT. So do a very conservative form of RT-in-RT to handle Catwoman. Unfortunately nothing else benefits from it. --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 18 ++++++++++++++++++ pcsx2/GS/Renderers/HW/GSRendererHW.h | 3 +++ pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 12 ++++++++++++ 3 files changed, 33 insertions(+) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 08549831cc0fc..21b0dfb994f79 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -6592,6 +6592,24 @@ void GSRendererHW::ReplaceVerticesWithSprite(const GSVector4i& unscaled_rect, co ReplaceVerticesWithSprite(unscaled_rect, unscaled_rect, unscaled_size, unscaled_rect); } +void GSRendererHW::OffsetDraw(s32 fbp_offset, s32 zbp_offset, s32 xoffset, s32 yoffset) +{ + GL_INS("Offseting render target by %d pages [%x -> %x], Z by %d pages [%x -> %x]", + fbp_offset, m_cached_ctx.FRAME.FBP << 5, zbp_offset, (m_cached_ctx.FRAME.FBP + fbp_offset) << 5); + GL_INS("Offseting vertices by [%d, %d]", xoffset, yoffset); + + m_cached_ctx.FRAME.FBP += fbp_offset; + m_cached_ctx.ZBUF.ZBP += zbp_offset; + + const s32 fp_xoffset = xoffset << 4; + const s32 fp_yoffset = yoffset << 4; + for (u32 i = 0; i < m_vertex.next; i++) + { + m_vertex.buff[i].XYZ.X += fp_xoffset; + m_vertex.buff[i].XYZ.Y += fp_yoffset; + } +} + GSHWDrawConfig& GSRendererHW::BeginHLEHardwareDraw( GSTexture* rt, GSTexture* ds, float rt_scale, GSTexture* tex, float tex_scale, const GSVector4i& unscaled_rect) { diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index 58ddeb3967c3f..f55cf38936f4b 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -217,6 +217,9 @@ class GSRendererHW : public GSRenderer /// Returns true if the specified texture address matches the frame or Z buffer. bool IsTBPFrameOrZ(u32 tbp) const; + /// Offsets the current draw, used for RT-in-RT. Offsets are relative to the *current* FBP, not the new FBP. + void OffsetDraw(s32 fbp_offset, s32 zbp_offset, s32 xoffset, s32 yoffset); + /// Replaces vertices with the specified fullscreen quad. void ReplaceVerticesWithSprite(const GSVector4i& unscaled_rect, const GSVector4i& unscaled_uv_rect, const GSVector2i& unscaled_size, const GSVector4i& scissor); diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 315d4dc542561..b61f8a15a97f8 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -1541,6 +1541,18 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const dst = t; tex_merge_rt = false; found_t = true; + + // Catwoman offsets the RT as well as the texture. + if (GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.Block() == TEX0.TBP0) + { + // Should be page aligned. + pxAssert(((t->m_TEX0.TBP0 - TEX0.TBP0) % 32) == 0); + const s32 page_offset = (t->m_TEX0.TBP0 - TEX0.TBP0) >> 5; + GL_CACHE("TC: RT also in front of TBP, offsetting draw by %d pages and [%d,%d].", page_offset, x_offset, y_offset); + GSRendererHW::GetInstance()->OffsetDraw(page_offset, page_offset, x_offset, y_offset); + break; + } + if (dst->m_TEX0.TBP0 == frame_fbp && possible_shuffle) break; else From 499895ac3906c5513c4991fc99732aa6e791e7a0 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 4 Jan 2024 15:32:33 +1000 Subject: [PATCH 2/2] GameDB: Add fullblend/autoflush/tex-in-RT for Catwoman --- bin/resources/GameIndex.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml index 8929aaa5c95da..340d074fb78d5 100644 --- a/bin/resources/GameIndex.yaml +++ b/bin/resources/GameIndex.yaml @@ -18328,6 +18328,11 @@ SLES-52563: SLES-52567: name: "Catwoman" region: "PAL-M7" + gsHWFixes: + recommendedBlendingLevel: 4 # Fixes bloom. + autoFlush: 1 # Fixes ghosting. + textureInsideRT: 1 # Required for offset RTs/textures for post-processing. + roundSprite: 2 # Fixes misaligned post-processing. SLES-52568: name: "Crash Twinsanity" region: "PAL-M5" @@ -60461,6 +60466,11 @@ SLUS-20992: name: "Catwoman" region: "NTSC-U" compat: 5 + gsHWFixes: + recommendedBlendingLevel: 4 # Fixes bloom. + autoFlush: 1 # Fixes ghosting. + textureInsideRT: 1 # Required for offset RTs/textures for post-processing. + roundSprite: 2 # Fixes misaligned post-processing. SLUS-20993: name: "Ghosthunter" region: "NTSC-U"