diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml index 0f38798a06..bcb8e57b9a 100644 --- a/bin/resources/GameIndex.yaml +++ b/bin/resources/GameIndex.yaml @@ -5302,7 +5302,10 @@ SCKA-20096: name: "Barnyard" region: "NTSC-K" gsHWFixes: - mipmap: 1 # Better characters and environment but has a texture cache issue that makes it worse. + halfPixelOffset: 2 # Fix text and post blur. + mipmap: 2 # Base mip level isn't always used. + autoFlush: 1 # Needed for recursive mipmap rendering. + getSkipCount: "GSC_Barnyard" # Render mipmaps on the CPU. SCKA-20098: name: "Nickelodeon SpongeBob SquarePants - Creature from the Krusty Krab" region: "NTSC-K" @@ -19573,17 +19576,26 @@ SLES-54376: name: "Barnyard" region: "PAL-E" gsHWFixes: - mipmap: 1 # Better characters and environment but has a texture cache issue that makes it worse. + halfPixelOffset: 2 # Fix text and post blur. + mipmap: 2 # Base mip level isn't always used. + autoFlush: 1 # Needed for recursive mipmap rendering. + getSkipCount: "GSC_Barnyard" # Render mipmaps on the CPU. SLES-54377: name: "Barnyard" region: "PAL-G" gsHWFixes: - mipmap: 1 # Better characters and environment but has a texture cache issue that makes it worse. + halfPixelOffset: 2 # Fix text and post blur. + mipmap: 2 # Base mip level isn't always used. + autoFlush: 1 # Needed for recursive mipmap rendering. + getSkipCount: "GSC_Barnyard" # Render mipmaps on the CPU. SLES-54378: name: "Barnyard" region: "PAL-M4" gsHWFixes: - mipmap: 1 # Better characters and environment but has a texture cache issue that makes it worse. + halfPixelOffset: 2 # Fix text and post blur. + mipmap: 2 # Base mip level isn't always used. + autoFlush: 1 # Needed for recursive mipmap rendering. + getSkipCount: "GSC_Barnyard" # Render mipmaps on the CPU. SLES-54379: name: "NFL Street 3" region: "PAL-E" @@ -46400,7 +46412,10 @@ SLUS-21277: region: "NTSC-U" compat: 5 gsHWFixes: - mipmap: 1 # Better characters and environment but has a texture cache issue that makes it worse. + halfPixelOffset: 2 # Fix text and post blur. + mipmap: 2 # Base mip level isn't always used. + autoFlush: 1 # Needed for recursive mipmap rendering. + getSkipCount: "GSC_Barnyard" # Render mipmaps on the CPU. SLUS-21278: name: "SSX on Tour" region: "NTSC-U" diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index 17899459e5..f8c39f6a04 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -802,6 +802,40 @@ bool GSHwHack::GSC_XenosagaE3(GSRendererHW& r, const GSFrameInfo& fi, int& skip) return true; } +bool GSHwHack::GSC_Barnyard(GSRendererHW& r, const GSFrameInfo& fi, int& skip) +{ + GSDrawingContext* context = r.m_context; + + // Whoever wrote this was kinda nuts. They draw a stipple/dither pattern to a framebuffer, then reuse that as + // the depth buffer. Textures are then drawn repeatedly on top of one another, each with a slight offset. + // Depth testing is enabled, and that determines which pixels make it into the final texture. Kinda like an + // attempt at anti-aliasing or adding more detail to the textures? + + // The size of these textures varies quite a bit. 16-bit, 24-bit and 32-bit formats are all used. + // The ones we need to take care of here, are the textures which use mipmaps. Those get drawn recursively, mip + // levels are then drawn to the right of the base texture. And we can't handle that in the texture cache. So + // we'll limit to 16/32-bit, going up to 320 wide. Some font textures are 1024x1024, we don't really want to + // be rasterizing that on the CPU. + + // Catch the mipmap draws. + if ((context->FRAME.PSM == PSM_PSMCT16S || context->FRAME.PSM == PSM_PSMCT32) && context->FRAME.FBW <= 5) + { + r.SwPrimRender(r, true); + skip = 1; + return true; + } + + // This is the giant dither-like depth buffer. We need this on the CPU *and* the GPU for textures which are + // rendered on both. + if (context->FRAME.FBW == 8 && r.m_index.tail == 32 && r.PRIM->TME && context->TEX0.TBW == 1) + { + r.SwPrimRender(r, false); + return false; + } + + return false; +} + bool GSHwHack::OI_PointListPalette(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { const size_t n_vertices = r.m_vertex.next; @@ -1205,6 +1239,7 @@ const GSHwHack::Entry GSHwHack::s_get_skip_count_function CRC_F(GSC_UrbanReign, CRCHackLevel::Partial), CRC_F(GSC_ZettaiZetsumeiToshi2, CRCHackLevel::Partial), CRC_F(GSC_BlackAndBurnoutSky, CRCHackLevel::Partial), + CRC_F(GSC_Barnyard, CRCHackLevel::Partial), // Channel Effect CRC_F(GSC_CrashBandicootWoC, CRCHackLevel::Partial), diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.h b/pcsx2/GS/Renderers/HW/GSHwHack.h index 6ee26233a1..d337bdd0cf 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.h +++ b/pcsx2/GS/Renderers/HW/GSHwHack.h @@ -55,6 +55,7 @@ public: static bool GSC_RedDeadRevolver(GSRendererHW& r, const GSFrameInfo& fi, int& skip); static bool GSC_ShinOnimusha(GSRendererHW& r, const GSFrameInfo& fi, int& skip); static bool GSC_XenosagaE3(GSRendererHW& r, const GSFrameInfo& fi, int& skip); + static bool GSC_Barnyard(GSRendererHW& r, const GSFrameInfo& fi, 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);