From d35db63d73da87e5f272c5dfc28da2ce39d4cf44 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Thu, 3 Mar 2022 21:32:32 +1000 Subject: [PATCH] GS: Reference GSConfig instead of using theApp Removes multiple sources of truth, enables overrides. --- pcsx2/Config.h | 3 ++ pcsx2/GS/GS.cpp | 2 + pcsx2/GS/GSState.cpp | 27 +++++------- pcsx2/GS/GSState.h | 4 +- pcsx2/GS/Renderers/HW/GSHwHack.cpp | 6 +-- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 42 ++++-------------- pcsx2/GS/Renderers/HW/GSRendererHW.h | 9 ---- pcsx2/GS/Renderers/HW/GSRendererNew.cpp | 4 +- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 53 +++++++---------------- pcsx2/GS/Renderers/HW/GSTextureCache.h | 7 --- pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp | 2 +- pcsx2/GS/Renderers/SW/GSRendererSW.cpp | 8 ---- pcsx2/Pcsx2Config.cpp | 14 ++++++ 13 files changed, 60 insertions(+), 121 deletions(-) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index d190bad43c..0cb52ac849 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -544,6 +544,9 @@ struct Pcsx2Config /// Sets user hack values to defaults when user hacks are not enabled. void MaskUserHacks(); + /// Sets user hack values to defaults when upscaling is not enabled. + void MaskUpscalingHacks(); + /// Returns true if any of the hardware renderers are selected. bool UseHardwareRenderer() const; diff --git a/pcsx2/GS/GS.cpp b/pcsx2/GS/GS.cpp index d5e4665dbc..0978412c68 100644 --- a/pcsx2/GS/GS.cpp +++ b/pcsx2/GS/GS.cpp @@ -311,6 +311,7 @@ bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* b GSConfig = config; GSConfig.Renderer = renderer; GSConfig.MaskUserHacks(); + GSConfig.MaskUpscalingHacks(); if (!Host::AcquireHostDisplay(GetAPIForRenderer(renderer))) { @@ -724,6 +725,7 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config) GSConfig = new_config; GSConfig.Renderer = (GSConfig.Renderer == GSRendererType::Auto) ? GSUtil::GetPreferredRenderer() : GSConfig.Renderer; GSConfig.MaskUserHacks(); + GSConfig.MaskUpscalingHacks(); if (!s_gs) return; diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index ead16fed9c..eb23226a66 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -23,6 +23,11 @@ int GSState::s_n = 0; +static __fi bool IsAutoFlushEnabled() +{ + return (GSConfig.Renderer == GSRendererType::SW) ? GSConfig.AutoFlushSW : GSConfig.UserHacks_AutoFlush; +} + GSState::GSState() : m_version(7) , m_gsc(NULL) @@ -30,6 +35,7 @@ GSState::GSState() , m_skip_offset(0) , m_q(1.0f) , m_scanmask_used(false) + , tex_flushed(true) , m_vt(this) , m_regs(NULL) , m_crc(0) @@ -39,18 +45,8 @@ GSState::GSState() // m_nativeres seems to be a hack. Unfortunately it impacts draw call number which make debug painful in the replayer. // Let's keep it disabled to ease debug. m_nativeres = GSConfig.UpscaleMultiplier == 1; - m_mipmap = theApp.GetConfigB("mipmap"); + m_mipmap = GSConfig.Mipmap; m_NTSC_Saturation = theApp.GetConfigB("NTSC_Saturation"); - if (theApp.GetConfigB("UserHacks")) - { - m_userhacks_auto_flush = theApp.GetConfigB("UserHacks_AutoFlush"); - m_userhacks_wildhack = theApp.GetConfigB("UserHacks_WildHack"); - } - else - { - m_userhacks_auto_flush = false; - m_userhacks_wildhack = false; - } s_n = 0; s_dump = theApp.GetConfigB("dump"); @@ -132,7 +128,6 @@ GSState::GSState() PRIM = &m_env.PRIM; //CSR->rREV = 0x20; m_env.PRMODECONT.AC = 1; - tex_flushed = true; Reset(); @@ -246,7 +241,7 @@ void GSState::ResetHandlers() m_fpGIFPackedRegHandlers[GIF_REG_PRIM] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerPRIM; m_fpGIFPackedRegHandlers[GIF_REG_RGBA] = &GSState::GIFPackedRegHandlerRGBA; m_fpGIFPackedRegHandlers[GIF_REG_STQ] = &GSState::GIFPackedRegHandlerSTQ; - m_fpGIFPackedRegHandlers[GIF_REG_UV] = m_userhacks_wildhack ? &GSState::GIFPackedRegHandlerUV_Hack : &GSState::GIFPackedRegHandlerUV; + m_fpGIFPackedRegHandlers[GIF_REG_UV] = GSConfig.UserHacks_WildHack ? &GSState::GIFPackedRegHandlerUV_Hack : &GSState::GIFPackedRegHandlerUV; m_fpGIFPackedRegHandlers[GIF_REG_TEX0_1] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerTEX0<0>; m_fpGIFPackedRegHandlers[GIF_REG_TEX0_2] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerTEX0<1>; m_fpGIFPackedRegHandlers[GIF_REG_CLAMP_1] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerCLAMP<0>; @@ -257,7 +252,7 @@ void GSState::ResetHandlers() // swap first/last indices when the provoking vertex is the first (D3D/Vulkan) const bool index_swap = GSConfig.UseHardwareRenderer() && !g_gs_device->Features().provoking_vertex_last; - if (m_userhacks_auto_flush) + if (IsAutoFlushEnabled()) index_swap ? SetPrimHandlers() : SetPrimHandlers(); else index_swap ? SetPrimHandlers() : SetPrimHandlers(); @@ -268,7 +263,7 @@ void GSState::ResetHandlers() m_fpGIFRegHandlers[GIF_A_D_REG_RGBAQ] = &GSState::GIFRegHandlerRGBAQ; m_fpGIFRegHandlers[GIF_A_D_REG_RGBAQ + 0x10] = &GSState::GIFRegHandlerRGBAQ; m_fpGIFRegHandlers[GIF_A_D_REG_ST] = &GSState::GIFRegHandlerST; - m_fpGIFRegHandlers[GIF_A_D_REG_UV] = m_userhacks_wildhack ? &GSState::GIFRegHandlerUV_Hack : &GSState::GIFRegHandlerUV; + m_fpGIFRegHandlers[GIF_A_D_REG_UV] = GSConfig.UserHacks_WildHack ? &GSState::GIFRegHandlerUV_Hack : &GSState::GIFRegHandlerUV; m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_1] = &GSState::GIFRegHandlerTEX0<0>; m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_2] = &GSState::GIFRegHandlerTEX0<1>; m_fpGIFRegHandlers[GIF_A_D_REG_CLAMP_1] = &GSState::GIFRegHandlerCLAMP<0>; @@ -1136,7 +1131,7 @@ void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r) // Some games do a single sprite draw to itself, then flush the texture cache, then use that texture again. // This won't get picked up by the new autoflush logic (which checks for page crossings for the PS2 Texture Cache flush) // so we need to do it here. - if(m_userhacks_auto_flush) + if (IsAutoFlushEnabled()) Flush(); } diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index 7fd1bdc629..1c8e174a81 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -149,14 +149,11 @@ protected: bool IsBadFrame(); void SetupCrcHack(); - bool m_userhacks_wildhack; bool m_isPackedUV_HackFlag; CRCHackLevel m_crc_hack_level; GetSkipCount m_gsc; int m_skip; int m_skip_offset; - bool m_userhacks_auto_flush; - bool tex_flushed; GSVertex m_v; float m_q; @@ -164,6 +161,7 @@ protected: GSVector4i m_ofxy; bool m_scanmask_used; + bool tex_flushed; struct { diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index 67157fb321..3eedce61bc 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -18,7 +18,6 @@ bool s_nativeres; static CRCHackLevel s_crc_hack_level = CRCHackLevel::Full; -bool s_autoflush; // hacks #define CRC_Partial (s_crc_hack_level >= CRCHackLevel::Partial) #define CRC_Full (s_crc_hack_level >= CRCHackLevel::Full) @@ -419,7 +418,7 @@ bool GSC_BurnoutGames(const GSFrameInfo& fi, int& skip) // 0x01dc0 01c00(MP) ntsc, 0x01f00 0x01d40(MP) ntsc progressive, 0x02200(MP) pal. // Yellow stripes. // Multiplayer tested only on Takedown. - skip = s_autoflush ? 2 : 4; + skip = GSConfig.UserHacks_AutoFlush ? 2 : 4; } } @@ -950,7 +949,6 @@ void GSState::SetupCrcHack() s_nativeres = m_nativeres; s_crc_hack_level = m_crc_hack_level; - s_autoflush = m_userhacks_auto_flush; memset(lut, 0, sizeof(lut)); @@ -1055,7 +1053,7 @@ bool GSState::IsBadFrame() return false; } - if (m_skip == 0 && GSConfig.UserHacks && (GSConfig.SkipDraw > 0)) + if (m_skip == 0 && GSConfig.SkipDraw > 0) { if (fi.TME) { diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index bbcb2d2e77..917b2e9092 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -25,7 +25,6 @@ GSRendererHW::GSRendererHW() , m_height(default_rt_size.y) , m_custom_width(1024) , m_custom_height(1024) - , m_userhacks_ts_half_bottom(-1) , m_tc(new GSTextureCache(this)) , m_src(nullptr) , m_hw_mipmap(GSConfig.HWMipmap) @@ -37,29 +36,13 @@ GSRendererHW::GSRendererHW() , m_lod(GSVector2i(0, 0)) { m_mipmap = (m_hw_mipmap >= HWMipmapLevel::Basic); - m_conservative_framebuffer = theApp.GetConfigB("conservative_framebuffer"); - if (theApp.GetConfigB("UserHacks")) + if (GSConfig.UserHacks) { - m_userhacks_enabled_gs_mem_clear = !theApp.GetConfigB("UserHacks_Disable_Safe_Features"); - m_userHacks_enabled_unscale_ptln = !theApp.GetConfigB("UserHacks_Disable_Safe_Features"); - m_userhacks_align_sprite_X = theApp.GetConfigB("UserHacks_align_sprite_X"); - m_userHacks_merge_sprite = theApp.GetConfigB("UserHacks_merge_pp_sprite"); - m_userhacks_ts_half_bottom = theApp.GetConfigI("UserHacks_Half_Bottom_Override"); - m_userhacks_round_sprite_offset = theApp.GetConfigI("UserHacks_round_sprite_offset"); - m_userhacks_tcoffset_x = theApp.GetConfigI("UserHacks_TCOffsetX") / -1000.0f; - m_userhacks_tcoffset_y = theApp.GetConfigI("UserHacks_TCOffsetY") / -1000.0f; + m_userhacks_tcoffset_x = GSConfig.UserHacks_TCOffsetX / -1000.0f; + m_userhacks_tcoffset_y = GSConfig.UserHacks_TCOffsetY / -1000.0f; m_userhacks_tcoffset = m_userhacks_tcoffset_x < 0.0f || m_userhacks_tcoffset_y < 0.0f; } - else - { - m_userhacks_enabled_gs_mem_clear = true; - m_userHacks_enabled_unscale_ptln = true; - m_userhacks_align_sprite_X = false; - m_userHacks_merge_sprite = false; - m_userhacks_ts_half_bottom = -1; - m_userhacks_round_sprite_offset = 0; - } if (!GSConfig.UpscaleMultiplier) // Custom Resolution { @@ -67,13 +50,6 @@ GSRendererHW::GSRendererHW() m_custom_height = m_height = theApp.GetConfigI("resy"); } - if (GSConfig.UpscaleMultiplier == 1) // hacks are only needed for upscaling issues. - { - m_userhacks_round_sprite_offset = 0; - m_userhacks_align_sprite_X = false; - m_userHacks_merge_sprite = false; - } - m_dump_root = root_hw; GSTextureReplacements::Initialize(m_tc); } @@ -127,7 +103,7 @@ void GSRendererHW::SetScaling() // // m_large_framebuffer has been inverted to m_conservative_framebuffer, it isn't an option that benefits being enabled all the time for everyone. int fb_height = 1280; - if (m_conservative_framebuffer) + if (GSConfig.ConservativeFramebuffer) { fb_height = fb_width < 1024 ? std::max(512, crtc_size.y) : 1024; } @@ -544,7 +520,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba) read_ba = (tex_pos > 112 && tex_pos < 144); bool half_bottom = false; - switch (m_userhacks_ts_half_bottom) + switch (GSConfig.UserHacks_HalfBottomOverride) { case 0: // Force Disabled. @@ -774,7 +750,7 @@ GSVector4i GSRendererHW::ComputeBoundingBox(const GSVector2& rtscale, const GSVe void GSRendererHW::MergeSprite(GSTextureCache::Source* tex) { // Upscaling hack to avoid various line/grid issues - if (m_userHacks_merge_sprite && tex && tex->m_target && (m_vt.m_primclass == GS_SPRITE_CLASS)) + if (GSConfig.UserHacks_MergePPSprite && tex && tex->m_target && (m_vt.m_primclass == GS_SPRITE_CLASS)) { if (PRIM->FST && GSLocalMemory::m_psm[tex->m_TEX0.PSM].fmt < 2 && ((m_vt.m_eq.value & 0xCFFFF) == 0xCFFFF)) { @@ -1732,7 +1708,7 @@ void GSRendererHW::Draw() return; } - if (m_userhacks_enabled_gs_mem_clear) + if (!GSConfig.UserHacks_DisableSafeFeatures) { // Constant Direct Write without texture/test/blending (aka a GS mem clear) if ((m_vt.m_primclass == GS_SPRITE_CLASS) && !PRIM->TME // Direct write @@ -1758,7 +1734,7 @@ void GSRendererHW::Draw() GSVertex* v = &m_vertex.buff[0]; // Hack to avoid vertical black line in various games (ace combat/tekken) - if (m_userhacks_align_sprite_X) + if (GSConfig.UserHacks_AlignSpriteX) { // Note for performance reason I do the check only once on the first // primitive @@ -1784,7 +1760,7 @@ void GSRendererHW::Draw() // Noting to do if no texture is sampled if (PRIM->FST && draw_sprite_tex) { - if ((m_userhacks_round_sprite_offset > 1) || (m_userhacks_round_sprite_offset == 1 && !m_vt.IsLinear())) + if ((GSConfig.UserHacks_RoundSprite > 1) || (GSConfig.UserHacks_RoundSprite == 1 && !m_vt.IsLinear())) { if (m_vt.IsLinear()) RoundSpriteOffset(); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index afe38d7818..18ae61793f 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -27,12 +27,6 @@ private: int m_height; int m_custom_width; int m_custom_height; - int m_userhacks_ts_half_bottom; - - bool m_conservative_framebuffer; - bool m_userhacks_align_sprite_X; - bool m_userhacks_enabled_gs_mem_clear; - bool m_userHacks_merge_sprite; static constexpr float SSR_UV_TOLERANCE = 1.0f; @@ -148,9 +142,6 @@ protected: virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; - int m_userhacks_round_sprite_offset; - bool m_userHacks_enabled_unscale_ptln; - bool m_userhacks_tcoffset; float m_userhacks_tcoffset_x; float m_userhacks_tcoffset_y; diff --git a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp index d56f1bfcd7..77a4c7bd2a 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp @@ -33,12 +33,12 @@ void GSRendererNew::SetupIA(const float& sx, const float& sy) { GL_PUSH("IA"); - if (m_userhacks_wildhack && !m_isPackedUV_HackFlag && PRIM->TME && PRIM->FST) + if (GSConfig.UserHacks_WildHack && !m_isPackedUV_HackFlag && PRIM->TME && PRIM->FST) { for (unsigned int i = 0; i < m_vertex.next; i++) m_vertex.buff[i].UV &= 0x3FEF3FEF; } - const bool unscale_pt_ln = m_userHacks_enabled_unscale_ptln && (GetUpscaleMultiplier() != 1); + const bool unscale_pt_ln = !GSConfig.UserHacks_DisableSafeFeatures && (GetUpscaleMultiplier() != 1); const GSDevice::FeatureSupport features = g_gs_device->Features(); switch (m_vt.m_primclass) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 7d25e5acd0..cb487e89ef 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -27,35 +27,12 @@ #define XXH_INLINE_ALL 1 #include "xxhash.h" -bool GSTextureCache::m_disable_partial_invalidation = false; -bool GSTextureCache::m_wrap_gs_mem = false; u8* GSTextureCache::m_temp; GSTextureCache::GSTextureCache(GSRenderer* r) : m_renderer(r) , m_palette_map(r) { - if (theApp.GetConfigB("UserHacks")) - { - UserHacks_HalfPixelOffset = theApp.GetConfigI("UserHacks_HalfPixelOffset") == 1; - m_preload_frame = theApp.GetConfigB("preload_frame_with_gs_data"); - m_disable_partial_invalidation = theApp.GetConfigB("UserHacks_DisablePartialInvalidation"); - m_can_convert_depth = !theApp.GetConfigB("UserHacks_DisableDepthSupport"); - m_cpu_fb_conversion = theApp.GetConfigB("UserHacks_CPU_FB_Conversion"); - m_texture_inside_rt = theApp.GetConfigB("UserHacks_TextureInsideRt"); - m_wrap_gs_mem = theApp.GetConfigB("wrap_gs_mem"); - } - else - { - UserHacks_HalfPixelOffset = false; - m_preload_frame = false; - m_disable_partial_invalidation = false; - m_can_convert_depth = true; - m_cpu_fb_conversion = false; - m_texture_inside_rt = false; - m_wrap_gs_mem = false; - } - // In theory 4MB is enough but 9MB is safer for overflow (8MB // isn't enough in custom resolution) // Test: onimusha 3 PAL 60Hz @@ -110,7 +87,7 @@ void GSTextureCache::RemoveAll() GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette) { - if (!m_can_convert_depth) + if (GSConfig.UserHacks_DisableDepthSupport) { GL_CACHE("LookupDepthSource not supported (0x%x, F:0x%x)", TEX0.TBP0, TEX0.PSM); throw GSRecoverableError(); @@ -305,7 +282,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con // 1/ it just works :) // 2/ even with upscaling // 3/ for both Direct3D and OpenGL - if (m_cpu_fb_conversion && (psm == PSM_PSMT4 || psm == PSM_PSMT8)) + if (GSConfig.UserHacks_CPUFBConversion && (psm == PSM_PSMT4 || psm == PSM_PSMT8)) // Forces 4-bit and 8-bit frame buffer conversion to be done on the CPU instead of the GPU, but performance will be slower. // There is no dedicated shader to handle 4-bit conversion (Stuntman has been confirmed to use 4-bit). // Direct3D10/11 and OpenGL support 8-bit fb conversion but don't render some corner cases properly (Harry Potter games). @@ -366,7 +343,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con // // Sigh... They don't help us. - if (!found_t && m_can_convert_depth) + if (!found_t && !GSConfig.UserHacks_DisableDepthSupport) { // Let's try a trick to avoid to use wrongly a depth buffer // Unfortunately, I don't have any Arc the Lad testcase @@ -441,7 +418,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con bool GSTextureCache::ShallSearchTextureInsideRt() { - return m_texture_inside_rt || (m_renderer->m_game.flags & CRC::Flags::TextureInsideRt); + return GSConfig.UserHacks_TextureInsideRt || (m_renderer->m_game.flags & CRC::Flags::TextureInsideRt); } GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, int type, bool used, u32 fbmask, const bool is_frame, const int real_h) @@ -545,7 +522,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con if (!is_frame) dst->m_dirty_alpha |= (psm_s.trbpp == 32 && (fbmask & 0xFF000000) != 0xFF000000) || (psm_s.trbpp == 16); } - else if (!is_frame && m_can_convert_depth) + else if (!is_frame && !GSConfig.UserHacks_DisableDepthSupport) { int rev_type = (type == DepthStencil) ? RenderTarget : DepthStencil; @@ -608,8 +585,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con // // From a performance point of view, it might cost a little on big upscaling // but normally few RT are miss so it must remain reasonable. - bool supported_fmt = m_can_convert_depth || psm_s.depth == 0; - if (m_preload_frame && TEX0.TBW > 0 && supported_fmt) + bool supported_fmt = !GSConfig.UserHacks_DisableDepthSupport || psm_s.depth == 0; + if (GSConfig.PreloadFrameWithGSData && TEX0.TBW > 0 && supported_fmt) { GL_INS("Preloading the RT DATA"); // RT doesn't have height but if we use a too big value, we will read outside of the GS memory. @@ -644,7 +621,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con // must invalidate the Target/Depth respectively void GSTextureCache::InvalidateVideoMemType(int type, u32 bp) { - if (!m_can_convert_depth) + if (GSConfig.UserHacks_DisableDepthSupport) return; auto& list = m_dst[type]; @@ -761,7 +738,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r // No point keeping invalidated sources around when the hash cache is active, // we can just re-hash and create a new source from the cached texture. - if (s->m_from_hash_cache || (m_disable_partial_invalidation && s->m_repeating)) + if (s->m_from_hash_cache || (GSConfig.UserHacks_DisablePartialInvalidation && s->m_repeating)) { m_src.RemoveAt(s); } @@ -937,7 +914,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r if (psm == PSM_PSMZ32 || psm == PSM_PSMZ24 || psm == PSM_PSMZ16 || psm == PSM_PSMZ16S) { GL_INS("ERROR: InvalidateLocalMem depth format isn't supported (%d,%d to %d,%d)", r.x, r.y, r.z, r.w); - if (m_can_convert_depth) + if (!GSConfig.UserHacks_DisableDepthSupport) { auto& dss = m_dst[DepthStencil]; for (auto it = dss.rbegin(); it != dss.rend(); ++it) // Iterate targets from LRU to MRU. @@ -986,7 +963,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r if (t->m_32_bits_fmt && t->m_TEX0.PSM > PSM_PSMCT24) t->m_TEX0.PSM = PSM_PSMCT32; - if (GSTextureCache::m_disable_partial_invalidation) + if (GSConfig.UserHacks_DisablePartialInvalidation) { Read(t, r.rintersect(t->m_valid)); } @@ -1430,7 +1407,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con float modx = 0.0f; float mody = 0.0f; - if (UserHacks_HalfPixelOffset && hack) + if (GSConfig.UserHacks_HalfPixelOffset == 1 && hack) { switch(m_renderer->GetUpscaleMultiplier()) { @@ -1607,7 +1584,7 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int { ASSERT(type == RenderTarget || type == DepthStencil); - Target* t = new Target(m_renderer, TEX0, m_can_convert_depth, type); + Target* t = new Target(m_renderer, TEX0, !GSConfig.UserHacks_DisableDepthSupport, type); // FIXME: initial data should be unswizzled from local mem in Update() if dirty @@ -1886,7 +1863,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect, int level) int i = (bn.blkY() << 7) + bn.blkX(); u32 block = bn.valueNoWrap(); - if (block < MAX_BLOCKS || m_wrap_gs_mem) + if (block < MAX_BLOCKS || GSConfig.WrapGSMem) { u32 addr = i % MAX_BLOCKS; @@ -1913,7 +1890,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect, int level) { u32 block = bn.valueNoWrap(); - if (block < MAX_BLOCKS || m_wrap_gs_mem) + if (block < MAX_BLOCKS || GSConfig.WrapGSMem) { block %= MAX_BLOCKS; diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.h b/pcsx2/GS/Renderers/HW/GSTextureCache.h index ad09159d5c..8e1bba8f91 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.h +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.h @@ -282,13 +282,7 @@ protected: std::unordered_map m_hash_cache; u64 m_hash_cache_memory_usage = 0; FastList m_dst[2]; - bool m_preload_frame; static u8* m_temp; - bool m_can_convert_depth; - bool m_cpu_fb_conversion; - static bool m_disable_partial_invalidation; - bool m_texture_inside_rt; - static bool m_wrap_gs_mem; constexpr static size_t S_SURFACE_OFFSET_CACHE_MAX_SIZE = std::numeric_limits::max(); std::unordered_map m_surface_offset_cache; @@ -326,7 +320,6 @@ public: void InvalidateLocalMem(const GSOffset& off, const GSVector4i& r); void IncAge(); - bool UserHacks_HalfPixelOffset; bool ShallSearchTextureInsideRt(); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index a6306b3085..9da804197e 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -881,7 +881,7 @@ GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel) glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - const int anisotropy = theApp.GetConfigI("MaxAnisotropy"); + const int anisotropy = GSConfig.MaxAnisotropy; if (anisotropy && sel.aniso) { if (GLExtension::Has("GL_ARB_texture_filter_anisotropic")) diff --git a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp index 4443e4562a..206bdb8ae3 100644 --- a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp +++ b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp @@ -58,14 +58,6 @@ GSRendererSW::GSRendererSW(int threads) InitCVB(GS_SPRITE_CLASS); m_dump_root = root_sw; - - // Reset handler with the auto flush hack enabled on the SW renderer. - // Some games run better without the hack so rely on ini/gui option. - if (theApp.GetConfigB("autoflush_sw")) - { - m_userhacks_auto_flush = true; - ResetHandlers(); - } } GSRendererSW::~GSRendererSW() diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 2fe769f108..e49a7d1557 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -598,12 +598,15 @@ void Pcsx2Config::GSOptions::MaskUserHacks() UserHacks_HalfPixelOffset = 0; UserHacks_RoundSprite = 0; PreloadFrameWithGSData = false; + WrapGSMem = false; UserHacks_DisablePartialInvalidation = false; UserHacks_DisableDepthSupport = false; UserHacks_CPUFBConversion = false; UserHacks_TextureInsideRt = false; UserHacks_TCOffsetX = 0; UserHacks_TCOffsetY = 0; + SkipDraw = 0; + SkipDrawOffset = 0; // in wx, we put trilinear filtering behind user hacks, but not in qt. #ifndef PCSX2_CORE @@ -611,6 +614,17 @@ void Pcsx2Config::GSOptions::MaskUserHacks() #endif } +void Pcsx2Config::GSOptions::MaskUpscalingHacks() +{ + if (UpscaleMultiplier == 1 || UserHacks) + return; + + UserHacks_AlignSpriteX = false; + UserHacks_MergePPSprite = false; + UserHacks_HalfPixelOffset = 0; + UserHacks_RoundSprite = 0; +} + bool Pcsx2Config::GSOptions::UseHardwareRenderer() const { return (Renderer == GSRendererType::DX11 || Renderer == GSRendererType::OGL || Renderer == GSRendererType::VK);