From 7b512ce296ea0d5de002a2a91019582496de7da2 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 5 Apr 2023 01:36:57 +1000 Subject: [PATCH] GS/HW: Fix Final Fantasy XII CRC hack --- pcsx2/GS/Renderers/HW/GSHwHack.cpp | 10 ++++---- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 31 +++++++++++++++++++++++- pcsx2/GS/Renderers/HW/GSTextureCache.h | 4 +++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index b02a0855d0..ab5b77c2cb 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -920,6 +920,7 @@ bool GSHwHack::OI_FFXII(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTexture if (r.m_vertex.next >= 16 * 512) { // incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454 + GL_INS("OI_FFXII() Buffering pixels"); if (!video) video = new u32[512 * 512]; @@ -952,12 +953,11 @@ bool GSHwHack::OI_FFXII(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTexture { // normally, this step would copy the video onto screen with 512 texture mapped horizontal lines, // but we use the stored video data to create a new texture, and replace the lines with two triangles + GL_INS("OI_FFXII() replace lines with a quad"); - g_gs_device->Recycle(t->m_texture); - - t->m_texture = g_gs_device->CreateTexture(512, 512, 1, GSTexture::Format::Color); - - t->m_texture->Update(GSVector4i(0, 0, 448, lines), video, 448 * 4); + GSTexture* tex = g_gs_device->CreateTexture(512, 512, 1, GSTexture::Format::Color); + tex->Update(GSVector4i(0, 0, 448, lines), video, 448 * 4); + g_texture_cache->ReplaceSourceTexture(t, tex, 1.0f, tex->GetSize(), nullptr, false); r.m_vertex.buff[2] = r.m_vertex.buff[r.m_vertex.next - 2]; r.m_vertex.buff[3] = r.m_vertex.buff[r.m_vertex.next - 1]; diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 62ec790510..026b105979 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -2694,6 +2694,35 @@ void GSTextureCache::InvalidateSourcesFromTarget(const Target* t) } } +void GSTextureCache::ReplaceSourceTexture(Source* s, GSTexture* new_texture, float new_scale, + const GSVector2i& new_unscaled_size, HashCacheEntry* hc_entry, bool new_texture_is_shared) +{ + pxAssert(!hc_entry || !new_texture_is_shared); + + if (s->m_from_hash_cache) + { + pxAssert(s->m_from_hash_cache->refcount > 0); + if ((--s->m_from_hash_cache->refcount) == 0) + s->m_from_hash_cache->age = 0; + } + else if (!s->m_shared_texture) + { + m_source_memory_usage -= s->m_texture->GetMemUsage(); + g_gs_device->Recycle(s->m_texture); + } + + s->m_texture = new_texture; + s->m_shared_texture = new_texture_is_shared; + s->m_from_hash_cache = hc_entry; + s->m_unscaled_size = new_unscaled_size; + s->m_scale = new_scale; + + if (s->m_from_hash_cache) + s->m_from_hash_cache->refcount++; + else if (!s->m_shared_texture) + m_source_memory_usage += s->m_texture->GetMemUsage(); +} + void GSTextureCache::IncAge() { static constexpr int max_age = 3; @@ -2877,7 +2906,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con } #ifdef ENABLE_OGL_DEBUG - if (TEX0.PSM == PSM_PSMT4) + if (TEX0.PSM == PSMT4) { GL_INS("ERROR: Reading RT as a packed-indexed 4 bits format is not supported"); } diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.h b/pcsx2/GS/Renderers/HW/GSTextureCache.h index 9e3487d41c..7d7df755f3 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.h +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.h @@ -458,6 +458,10 @@ public: /// Removes any sources which point to the specified target. void InvalidateSourcesFromTarget(const Target* t); + /// Replaces a source's texture externally. Required for some CRC hacks. + void ReplaceSourceTexture(Source* s, GSTexture* new_texture, float new_scale, const GSVector2i& new_unscaled_size, + HashCacheEntry* hc_entry, bool new_texture_is_shared); + bool Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u32 DBW, u32 DPSM, int dx, int dy, int w, int h); bool ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx, int dy, int w, int h);