From 3692d7d090e8851b472d446cd81b63a559a7f2c1 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 26 Jul 2023 00:00:49 +1000 Subject: [PATCH] GS/HW: Extend bilinear dirty upscale fix to force nearest --- pcsx2-qt/Settings/GraphicsSettingsWidget.cpp | 2 +- pcsx2-qt/Settings/GraphicsSettingsWidget.ui | 53 +++++++++++++------- pcsx2/Config.h | 10 +++- pcsx2/Docs/gamedb-schema.json | 2 +- pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 4 +- pcsx2/GameDatabase.cpp | 7 ++- pcsx2/ImGui/FullscreenUI.cpp | 10 ++-- pcsx2/ImGui/ImGuiOverlays.cpp | 4 +- pcsx2/Pcsx2Config.cpp | 9 ++-- 9 files changed, 67 insertions(+), 34 deletions(-) diff --git a/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp b/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp index 183fa28a8d..1cc0023f82 100644 --- a/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp +++ b/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp @@ -218,12 +218,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget* ////////////////////////////////////////////////////////////////////////// SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_round_sprite_offset", 0); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", 0); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetX, "EmuCore/GS", "UserHacks_TCOffsetX", 0); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetY, "EmuCore/GS", "UserHacks_TCOffsetY", 0); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.alignSprite, "EmuCore/GS", "UserHacks_align_sprite_X", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.mergeSprite, "EmuCore/GS", "UserHacks_merge_pp_sprite", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.wildHack, "EmuCore/GS", "UserHacks_WildHack", false); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.nativePaletteDraw, "EmuCore/GS", "UserHacks_NativePaletteDraw", false); ////////////////////////////////////////////////////////////////////////// // Texture Replacements diff --git a/pcsx2-qt/Settings/GraphicsSettingsWidget.ui b/pcsx2-qt/Settings/GraphicsSettingsWidget.ui index 9e807996bb..dcddf2a6d7 100644 --- a/pcsx2-qt/Settings/GraphicsSettingsWidget.ui +++ b/pcsx2-qt/Settings/GraphicsSettingsWidget.ui @@ -1168,14 +1168,14 @@ - + Texture Offsets: - + @@ -1207,7 +1207,7 @@ - + @@ -1216,20 +1216,6 @@ - - - - Bilinear Dirty Upscale - - - - - - - Merge Sprite - - - @@ -1244,8 +1230,41 @@ + + + + Merge Sprite + + + + + + + Bilinear Dirty Upscale: + + + + + + + + Automatic (Default) + + + + + Force Bilinear + + + + + Force Nearest + + + + diff --git a/pcsx2/Config.h b/pcsx2/Config.h index d40804eb98..3c98b4b663 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -364,6 +364,14 @@ enum class GSTextureInRtMode : u8 MergeTargets, }; +enum class GSBilinearDirtyMode : u8 +{ + Automatic, + ForceBilinear, + ForceNearest, + MaxCount +}; + // Template function for casting enumerations to their underlying type template typename std::underlying_type::type enum_cast(Enumeration E) @@ -683,7 +691,6 @@ struct Pcsx2Config UserHacks_DisableRenderFixes : 1, UserHacks_MergePPSprite : 1, UserHacks_WildHack : 1, - UserHacks_BilinearHack : 1, UserHacks_NativePaletteDraw : 1, UserHacks_TargetPartialInvalidation : 1, UserHacks_EstimateTextureRegion : 1, @@ -763,6 +770,7 @@ struct Pcsx2Config u8 UserHacks_CPUCLUTRender = 0; GSGPUTargetCLUTMode UserHacks_GPUTargetCLUTMode = GSGPUTargetCLUTMode::Disabled; GSTextureInRtMode UserHacks_TextureInsideRt = GSTextureInRtMode::Disabled; + GSBilinearDirtyMode UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic; TriFiltering TriFilter = TriFiltering::Automatic; s8 OverrideTextureBarriers = -1; diff --git a/pcsx2/Docs/gamedb-schema.json b/pcsx2/Docs/gamedb-schema.json index 8859b8c062..198ebbb274 100644 --- a/pcsx2/Docs/gamedb-schema.json +++ b/pcsx2/Docs/gamedb-schema.json @@ -175,7 +175,7 @@ "bilinearUpscale": { "type": "integer", "minimum": 0, - "maximum": 1 + "maximum": 2 }, "nativePaletteDraw": { "type": "integer", diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 5c31ac0027..0d28ced8a7 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -5131,8 +5131,8 @@ void GSTextureCache::Target::Update() // Bilinear filtering this is probably not a good thing, at least in native, but upscaling Nearest can be gross and messy. // It's needed for depth, though.. filtering depth doesn't make much sense, but SMT3 needs it.. const bool upscaled = (m_scale != 1.0f); - const bool override_linear = upscaled && GSConfig.UserHacks_BilinearHack; - const bool linear = (m_type == RenderTarget && upscaled); + const bool override_linear = (upscaled && GSConfig.UserHacks_BilinearHack == GSBilinearDirtyMode::ForceBilinear); + const bool linear = (m_type == RenderTarget && upscaled && GSConfig.UserHacks_BilinearHack != GSBilinearDirtyMode::ForceNearest); GSDevice::MultiStretchRect* drects = static_cast( alloca(sizeof(GSDevice::MultiStretchRect) * static_cast(m_dirty.size()))); diff --git a/pcsx2/GameDatabase.cpp b/pcsx2/GameDatabase.cpp index ad6a69f32e..3d0d15ef26 100644 --- a/pcsx2/GameDatabase.cpp +++ b/pcsx2/GameDatabase.cpp @@ -728,8 +728,11 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions& break; case GSHWFixId::BilinearUpscale: - config.UserHacks_BilinearHack = (value > 0); - break; + { + if (value >= 0 && value < static_cast(GSBilinearDirtyMode::MaxCount)) + config.UserHacks_BilinearHack = static_cast(value); + } + break; case GSHWFixId::NativePaletteDraw: config.UserHacks_NativePaletteDraw = (value > 0); diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp index b5e42a8cc8..e7a5889089 100644 --- a/pcsx2/ImGui/FullscreenUI.cpp +++ b/pcsx2/ImGui/FullscreenUI.cpp @@ -3228,6 +3228,7 @@ void FullscreenUI::DrawGraphicsSettingsPage() static constexpr const char* s_half_pixel_offset_options[] = { "Off (Default)", "Normal (Vertex)", "Special (Texture)", "Special (Texture - Aggressive)"}; static constexpr const char* s_round_sprite_options[] = {"Off (Default)", "Half", "Full"}; + static constexpr const char* s_bilinear_dirty_options[] = {"Automatic (Default)", "Force Bilinear", "Force Nearest"}; static constexpr const char* s_auto_flush_options[] = { "Disabled (Default)", "Enabled (Sprites Only)", "Enabled (All Primitives)"}; @@ -3280,6 +3281,10 @@ void FullscreenUI::DrawGraphicsSettingsPage() "UserHacks_HalfPixelOffset", 0, s_half_pixel_offset_options, std::size(s_half_pixel_offset_options)); DrawIntListSetting(bsi, "Round Sprite", "Adjusts sprite coordinates.", "EmuCore/GS", "UserHacks_round_sprite_offset", 0, s_round_sprite_options, std::size(s_round_sprite_options)); + DrawIntListSetting(bsi, "Bilinear Upscale", + "Can smooth out textures due to be bilinear filtered when upscaling. E.g. Brave sun glare.", "EmuCore/GS", + "UserHacks_BilinearHack", static_cast(GSBilinearDirtyMode::Automatic), + s_bilinear_dirty_options, std::size(s_bilinear_dirty_options)); DrawIntSpinBoxSetting( bsi, "TC Offset X", "Adjusts target texture offsets.", "EmuCore/GS", "UserHacks_TCOffsetX", 0, -4096, 4096, 1); DrawIntSpinBoxSetting( @@ -3290,10 +3295,7 @@ void FullscreenUI::DrawGraphicsSettingsPage() "UserHacks_merge_pp_sprite", false, manual_hw_fixes); DrawToggleSetting(bsi, "Wild Arms Hack", "Lowers the GS precision to avoid gaps between pixels when upscaling. Fixes the text on Wild Arms games.", "EmuCore/GS", - "UserHacks_WildHack", false, manual_hw_fixes); - DrawToggleSetting(bsi, "Bilinear Upscale", - "Can smooth out textures due to be bilinear filtered when upscaling. E.g. Brave sun glare.", "EmuCore/GS", - "UserHacks_BilinearHack", false, manual_hw_fixes); + "UserHacks_WildHack", false, manual_hw_fixes); DrawToggleSetting(bsi, "Unscaled Palette Texture Draws", "Can fix some broken effects which rely on pixel perfect precision.", "EmuCore/GS", "UserHacks_NativePaletteDraw", false, manual_hw_fixes); } diff --git a/pcsx2/ImGui/ImGuiOverlays.cpp b/pcsx2/ImGui/ImGuiOverlays.cpp index 7f58def09d..092adf7a52 100644 --- a/pcsx2/ImGui/ImGuiOverlays.cpp +++ b/pcsx2/ImGui/ImGuiOverlays.cpp @@ -408,10 +408,10 @@ void ImGuiManager::DrawSettingsOverlay() APPEND("SD={}/{} ", GSConfig.SkipDrawStart, GSConfig.SkipDrawEnd); if (GSConfig.UserHacks_TextureInsideRt != GSTextureInRtMode::Disabled) APPEND("TexRT={} ", static_cast(GSConfig.UserHacks_TextureInsideRt)); + if (GSConfig.UserHacks_BilinearHack != GSBilinearDirtyMode::Automatic) + APPEND("BLU={}", static_cast(GSConfig.UserHacks_BilinearHack)); if (GSConfig.UserHacks_WildHack) APPEND("WA "); - if (GSConfig.UserHacks_BilinearHack) - APPEND("BLU "); if (GSConfig.UserHacks_NativePaletteDraw) APPEND("NPD "); if (GSConfig.UserHacks_MergePPSprite) diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 9237e5e9a8..0de1fe13ae 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -538,7 +538,7 @@ Pcsx2Config::GSOptions::GSOptions() UserHacks_DisableRenderFixes = false; UserHacks_MergePPSprite = false; UserHacks_WildHack = false; - UserHacks_BilinearHack = false; + UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic; UserHacks_NativePaletteDraw = false; DumpReplaceableTextures = false; @@ -625,6 +625,7 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const OpEqu(UserHacks_CPUCLUTRender) && OpEqu(UserHacks_GPUTargetCLUTMode) && OpEqu(UserHacks_TextureInsideRt) && + OpEqu(UserHacks_BilinearHack) && OpEqu(OverrideTextureBarriers) && OpEqu(CAS_Sharpness) && @@ -758,7 +759,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap) GSSettingBoolEx(UserHacks_DisableRenderFixes, "UserHacks_DisableRenderFixes"); GSSettingBoolEx(UserHacks_MergePPSprite, "UserHacks_merge_pp_sprite"); GSSettingBoolEx(UserHacks_WildHack, "UserHacks_WildHack"); - GSSettingBoolEx(UserHacks_BilinearHack, "UserHacks_BilinearHack"); + GSSettingIntEnumEx(UserHacks_BilinearHack, "UserHacks_BilinearHack"); GSSettingBoolEx(UserHacks_NativePaletteDraw, "UserHacks_NativePaletteDraw"); GSSettingIntEnumEx(UserHacks_TextureInsideRt, "UserHacks_TextureInsideRt"); GSSettingBoolEx(UserHacks_TargetPartialInvalidation, "UserHacks_TargetPartialInvalidation"); @@ -877,7 +878,6 @@ void Pcsx2Config::GSOptions::MaskUserHacks() UserHacks_AlignSpriteX = false; UserHacks_MergePPSprite = false; UserHacks_WildHack = false; - UserHacks_BilinearHack = false; UserHacks_NativePaletteDraw = false; UserHacks_DisableSafeFeatures = false; UserHacks_DisableRenderFixes = false; @@ -899,6 +899,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks() UserHacks_CPUSpriteRenderLevel = 0; UserHacks_CPUCLUTRender = 0; UserHacks_GPUTargetCLUTMode = GSGPUTargetCLUTMode::Disabled; + UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic; SkipDrawStart = 0; SkipDrawEnd = 0; } @@ -911,7 +912,7 @@ void Pcsx2Config::GSOptions::MaskUpscalingHacks() UserHacks_AlignSpriteX = false; UserHacks_MergePPSprite = false; UserHacks_WildHack = false; - UserHacks_BilinearHack = false; + UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic; UserHacks_NativePaletteDraw = false; UserHacks_HalfPixelOffset = 0; UserHacks_RoundSprite = 0;