From b6923f49b159303bd3a2281021d22cdb6b8ea308 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 17 Jun 2023 01:46:11 +1000 Subject: [PATCH] GS/HW: Add render fix for MGS3 DoF effect --- bin/resources/GameIndex.yaml | 36 +++++++++++++++++++++++++++ pcsx2/GS/Renderers/HW/GSHwHack.cpp | 40 ++++++++++++++++++++++++++++++ pcsx2/GS/Renderers/HW/GSHwHack.h | 1 + 3 files changed, 77 insertions(+) diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml index c90db12b68..32c5c081a5 100644 --- a/bin/resources/GameIndex.yaml +++ b/bin/resources/GameIndex.yaml @@ -24014,6 +24014,7 @@ SLES-82013: gsHWFixes: halfPixelOffset: 2 # Fixes blurry characters. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82018: name: "Cy Girls [Ice Disc]" region: "PAL-E-F-S" @@ -24038,6 +24039,7 @@ SLES-82024: gsHWFixes: halfPixelOffset: 2 # Fixes blurry characters. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82026: name: "Metal Gear Solid 3 - Snake Eater" region: "PAL-S" @@ -24046,6 +24048,7 @@ SLES-82026: gsHWFixes: halfPixelOffset: 2 # Fixes blurry characters. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82028: name: "Star Ocean 3 - Till the End of Time [Disc 1 of 2]" region: "PAL-E" @@ -24094,6 +24097,7 @@ SLES-82032: gsHWFixes: halfPixelOffset: 2 # Fixes blurry characters. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82034: name: "Xenosaga Episode II [Disc 1 of 2]" region: "PAL-M3" @@ -24157,6 +24161,7 @@ SLES-82042: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82043: name: "Metal Gear Solid 3 - Subsistence [Disc 2 of 3]" region: "PAL-E-F" @@ -24166,6 +24171,7 @@ SLES-82043: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82042" SLES-82044: @@ -24177,6 +24183,7 @@ SLES-82044: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82045: name: "Metal Gear Solid 3 - Subsistence [Disc 2 of 3]" region: "PAL-I" @@ -24186,6 +24193,7 @@ SLES-82045: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82044" SLES-82046: @@ -24197,6 +24205,7 @@ SLES-82046: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82047: name: "Metal Gear Solid 3 - Subsistence [Disc 2 of 3]" region: "PAL-G" @@ -24206,6 +24215,7 @@ SLES-82047: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82046" SLES-82048: @@ -24217,6 +24227,7 @@ SLES-82048: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLES-82049: name: "Metal Gear Solid 3 - Subsistence [Disc 2 of 3]" region: "PAL-S" @@ -24226,6 +24237,7 @@ SLES-82049: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82048" SLES-82050: @@ -24237,6 +24249,7 @@ SLES-82050: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82042" SLES-82051: @@ -24248,6 +24261,7 @@ SLES-82051: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82044" SLES-82052: @@ -24259,6 +24273,7 @@ SLES-82052: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82046" SLES-82053: @@ -24270,6 +24285,7 @@ SLES-82053: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLES-82048" SLKA-15002: @@ -25116,6 +25132,7 @@ SLKA-25251: gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLKA-25252: name: "Forgotten Realms - Demon Stone" region: "NTSC-K" @@ -25433,6 +25450,7 @@ SLKA-25353: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLKA-25354: name: "Metal Gear Solid 3 - Subsistence [Limited Edition] [Disc 2 of 3]" region: "NTSC-K" @@ -25443,6 +25461,7 @@ SLKA-25354: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLKA-25353" SLKA-25355: @@ -25455,6 +25474,7 @@ SLKA-25355: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLKA-25353" SLKA-25359: @@ -31610,6 +31630,7 @@ SLPM-65789: gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-65790: name: "Metal Gear Solid 3 - Snake Eater" region: "NTSC-J" @@ -31618,6 +31639,7 @@ SLPM-65790: gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-65791: name: "S.L.A.I. - Steel Lancer Arena International" region: "NTSC-J" @@ -32827,6 +32849,7 @@ SLPM-66117: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-66118: name: "Metal Gear Solid 3 - Subsistence [with Headset] [Disc 2 of 3]" region: "NTSC-J" @@ -32836,6 +32859,7 @@ SLPM-66118: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-66119: name: "Metal Gear Solid 3 - Subsistence [with Headset] [Disc 3 of 3]" region: "NTSC-J" @@ -32845,6 +32869,7 @@ SLPM-66119: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-66121: name: "Spider-Man 2 [Taito Best]" region: "NTSC-J" @@ -33240,6 +33265,7 @@ SLPM-66220: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLPM-66117" SLPM-66221: @@ -33251,6 +33277,7 @@ SLPM-66221: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLPM-66117" SLPM-66222: @@ -33262,6 +33289,7 @@ SLPM-66222: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLPM-66117" SLPM-66223: @@ -33273,6 +33301,7 @@ SLPM-66223: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLPM-66117" SLPM-66224: @@ -33284,6 +33313,7 @@ SLPM-66224: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLPM-66117" SLPM-66225: @@ -35560,6 +35590,7 @@ SLPM-66794: gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-66796: name: "Metal Gear Solid - 20th Anniversary Collection" region: "NTSC-J" @@ -36488,6 +36519,7 @@ SLPM-68516: gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLPM-68520: name: "Armored Core - Last Raven [Monthly Champion magazine Special Edition]" region: "NTSC-J" @@ -46721,6 +46753,7 @@ SLUS-20915: gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. autoFlush: 2 # Fixes lens flare. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLUS-20916: name: "Dance Dance Revolution EXTREME" region: "NTSC-U" @@ -48540,6 +48573,7 @@ SLUS-21243: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLUS-21359" SLUS-21244: @@ -49263,6 +49297,7 @@ SLUS-21359: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. SLUS-21360: name: "Metal Gear Solid 3 - Subsistence [Disc 3 of 3]" region: "NTSC-U" @@ -49272,6 +49307,7 @@ SLUS-21360: gsHWFixes: autoFlush: 2 # Fixes lens flare. halfPixelOffset: 2 # Fixes blurriness. + getSkipCount: "GSC_MetalGearSolid3" # Fixes depth of field blur. memcardFilters: - "SLUS-21359" SLUS-21361: diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index eb4a66835c..5488aaf21a 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -668,6 +668,45 @@ bool GSHwHack::GSC_BlueTongueGames(GSRendererHW& r, int& skip) return false; } +bool GSHwHack::GSC_MetalGearSolid3(GSRendererHW& r, int& skip) +{ + // MGS3 copies 256x224 in Z24 from 0x2000 to 0x2080 (with a BW of 8, so half the screen), and then uses this as a + // Z buffer. So, we effectively have two buffers within one, overlapping, at the 256 pixel point, colour on left, + // depth on right. Our texture cache can't handle that, and it thinks it's one big target, so when it does look up + // Z at 0x2080, it misses and loads from local memory instead, which of course, is junk. This is for the depth of + // field effect (MGS3-DOF.gs). + + // We could fix this up at the time the Z data actually gets used, but that doubles the amount of copies we need to + // do, since OI fixes can't access the dirty area. So, instead, we'll just fudge the FBP when it copies 0x2000 to + // 0x2080, which normally happens with a 256 pixel offset, so we have to subtract that from the sprite verts too. + + // Drawing with FPSM of Z24 is pretty unlikely, so hopefully this doesn't hit any false positives. + if (RFPSM != PSMZ24 || RTPSM != PSMZ24 || !RTME) + return false; + + // For some reason, instead of being sensible and masking Z, they set up AFAIL instead. + if (!RZMSK) + { + u32 fm = 0, fm_mask = 0, zm = 0; + if (!r.m_cached_ctx.TEST.ATE || !r.TryAlphaTest(fm, fm_mask, zm) || zm == 0) + return false; + } + + const int w_sub = (RFBW / 2) * 64; + const u32 w_sub_fp = w_sub << 4; + r.m_cached_ctx.FRAME.FBP += RFBW / 2; + + GL_INS("OI_MetalGearSolid3(): %x -> %x, %dx%d, subtract %d", RFBP, RFBP + (RFBW / 2), r.m_r.width(), r.m_r.height(), + w_sub); + + for (u32 i = 0; i < r.m_vertex.next; i++) + r.m_vertex.buff[i].XYZ.X -= w_sub_fp; + + // No point adjusting the scissor, it just ends up expanding out anyway.. but we do have to fix up the draw rect. + r.m_r -= GSVector4i(w_sub); + return true; +} + bool GSHwHack::OI_PointListPalette(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { const u32 n_vertices = r.m_vertex.next; @@ -1084,6 +1123,7 @@ const GSHwHack::Entry GSHwHack::s_get_skip_count_function CRC_F(GSC_Battlefield2), CRC_F(GSC_NFSUndercover), CRC_F(GSC_PolyphonyDigitalGames), + CRC_F(GSC_MetalGearSolid3), // Channel Effect CRC_F(GSC_GiTS), diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.h b/pcsx2/GS/Renderers/HW/GSHwHack.h index 1afafd8de8..0d62d9b34f 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.h +++ b/pcsx2/GS/Renderers/HW/GSHwHack.h @@ -44,6 +44,7 @@ public: static bool GSC_Battlefield2(GSRendererHW& r, int& skip); static bool GSC_NFSUndercover(GSRendererHW& r, int& skip); static bool GSC_PolyphonyDigitalGames(GSRendererHW& r, int& skip); + static bool GSC_MetalGearSolid3(GSRendererHW& r, int& skip); static bool OI_PointListPalette(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); static bool OI_BigMuthaTruckers(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);