diff --git a/pcsx2-qt/Settings/GraphicsHardwareRenderingSettingsTab.ui b/pcsx2-qt/Settings/GraphicsHardwareRenderingSettingsTab.ui index 24634ca5e7..cfb70e836d 100644 --- a/pcsx2-qt/Settings/GraphicsHardwareRenderingSettingsTab.ui +++ b/pcsx2-qt/Settings/GraphicsHardwareRenderingSettingsTab.ui @@ -116,6 +116,11 @@ + + + Automatic (Default) + + Minimum @@ -123,7 +128,7 @@ - Basic (Recommended) + Basic diff --git a/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp b/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp index de7bce69ab..3f481dedee 100644 --- a/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp +++ b/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp @@ -121,7 +121,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog, SettingWidgetBinder::BindWidgetToIntSetting(sif, m_hw.dithering, "EmuCore/GS", "dithering_ps2", 2); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_hw.mipmapping, "EmuCore/GS", "hw_mipmap", true); SettingWidgetBinder::BindWidgetToIntSetting( - sif, m_hw.blending, "EmuCore/GS", "accurate_blending_unit", static_cast(AccBlendLevel::Basic)); + sif, m_hw.blending, "EmuCore/GS", "accurate_blending_unit", static_cast(AccBlendLevel::Automatic), -1); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_hw.enableHWFixes, "EmuCore/GS", "UserHacks", false); connect(m_hw.upscaleMultiplier, QOverload::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onUpscaleMultiplierChanged); diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 786843f2da..d6379ea6da 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -327,8 +327,9 @@ enum class TriFiltering : s8 Forced, }; -enum class AccBlendLevel : u8 +enum class AccBlendLevel : s8 { + Automatic = -1, Minimum, Basic, Medium, @@ -811,7 +812,7 @@ struct Pcsx2Config GSRendererType Renderer = GSRendererType::Auto; float UpscaleMultiplier = 1.0f; - AccBlendLevel AccurateBlendingUnit = AccBlendLevel::Basic; + AccBlendLevel AccurateBlendingUnit = AccBlendLevel::Automatic; BiFiltering TextureFiltering = BiFiltering::PS2; TexturePreloadingLevel TexturePreloading = TexturePreloadingLevel::Full; GSDumpCompressionMethod GSDumpCompression = GSDumpCompressionMethod::Zstandard; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 155ba563c9..ab0de4a657 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -5180,6 +5180,8 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS enable_fbmask_emulation = true; break; case AccBlendLevel::Basic: + case AccBlendLevel::Automatic: + default: // Enable Fbmask emulation excluding triangle class because it is quite slow. enable_fbmask_emulation = (m_vt.m_primclass != GS_TRIANGLE_CLASS); break; @@ -5784,7 +5786,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo const bool blend_ad = m_conf.ps.blend_c == 1; const bool alpha_mask = (m_cached_ctx.FRAME.FBMSK & 0xFF000000) == 0xFF000000; bool blend_ad_alpha_masked = blend_ad && alpha_mask; - const bool is_basic_blend = GSConfig.AccurateBlendingUnit >= AccBlendLevel::Basic; + const bool is_basic_blend = GSConfig.AccurateBlendingUnit != AccBlendLevel::Minimum; if (blend_ad_alpha_masked && (((is_basic_blend || (COLCLAMP.CLAMP == 0)) && (features.texture_barrier || features.multidraw_fb_copy)) || ((GSConfig.AccurateBlendingUnit >= AccBlendLevel::Medium) || m_conf.require_one_barrier))) { @@ -5894,6 +5896,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo sw_blending |= m_vt.m_primclass == GS_SPRITE_CLASS && m_drawlist.size() < 100; [[fallthrough]]; case AccBlendLevel::Basic: + case AccBlendLevel::Automatic: + default: // Prefer sw blend if possible. color_dest_blend &= !prefer_sw_blend; color_dest_blend2 &= !prefer_sw_blend; @@ -5935,6 +5939,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo sw_blending |= !(blend_ad_alpha_masked || ad_second_pass) && (alpha_c1_high_max_one || alpha_c1_high_no_rta_correct) && no_prim_overlap; [[fallthrough]]; case AccBlendLevel::Basic: + case AccBlendLevel::Automatic: + default: // Prefer sw blend if possible. color_dest_blend &= !prefer_sw_blend; color_dest_blend2 &= !prefer_sw_blend; diff --git a/pcsx2/GameDatabase.cpp b/pcsx2/GameDatabase.cpp index bdb28e3c9d..7abb23da05 100644 --- a/pcsx2/GameDatabase.cpp +++ b/pcsx2/GameDatabase.cpp @@ -664,10 +664,10 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti return (config.GPUPaletteConversion == ((value > 1) ? (config.TexturePreloading == TexturePreloadingLevel::Full) : (value != 0))); case GSHWFixId::MinimumBlendingLevel: - return (static_cast(config.AccurateBlendingUnit) >= value); + return (config.AccurateBlendingUnit == AccBlendLevel::Automatic || static_cast(config.AccurateBlendingUnit) >= value); case GSHWFixId::MaximumBlendingLevel: - return (static_cast(config.AccurateBlendingUnit) <= value); + return (config.AccurateBlendingUnit == AccBlendLevel::Automatic || static_cast(config.AccurateBlendingUnit) <= value); case GSHWFixId::RecommendedBlendingLevel: return true; @@ -868,21 +868,23 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions& case GSHWFixId::MinimumBlendingLevel: { - if (value >= 0 && value <= static_cast(AccBlendLevel::Maximum)) - config.AccurateBlendingUnit = std::max(config.AccurateBlendingUnit, static_cast(value)); + if (value >= 0 && value <= static_cast(AccBlendLevel::Maximum) && config.AccurateBlendingUnit == AccBlendLevel::Automatic) + config.AccurateBlendingUnit = static_cast(value); } break; case GSHWFixId::MaximumBlendingLevel: { - if (value >= 0 && value <= static_cast(AccBlendLevel::Maximum)) - config.AccurateBlendingUnit = std::min(config.AccurateBlendingUnit, static_cast(value)); + if (value >= 0 && value <= static_cast(AccBlendLevel::Maximum) && config.AccurateBlendingUnit == AccBlendLevel::Automatic) + config.AccurateBlendingUnit = static_cast(value); } break; case GSHWFixId::RecommendedBlendingLevel: { - if (!is_sw_renderer && value >= 0 && value <= static_cast(AccBlendLevel::Maximum) && static_cast(EmuConfig.GS.AccurateBlendingUnit) < value) + // Need to increment by 1 because Automatic is -1. + const int blend_level = static_cast(config.AccurateBlendingUnit) + 1; + if (!is_sw_renderer && value >= static_cast(AccBlendLevel::Automatic) && value <= static_cast(AccBlendLevel::Maximum) && blend_level < value) { Host::AddKeyedOSDMessage("HWBlendingWarning", fmt::format(TRANSLATE_FS("GameDatabase", @@ -891,8 +893,7 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions& "You can adjust the blending level in Game Properties to improve\n" "graphical quality, but this will increase system requirements."), ICON_FA_PAINTBRUSH, - Pcsx2Config::GSOptions::BlendingLevelNames[static_cast( - EmuConfig.GS.AccurateBlendingUnit)], + Pcsx2Config::GSOptions::BlendingLevelNames[blend_level], Pcsx2Config::GSOptions::BlendingLevelNames[value]), Host::OSD_WARNING_DURATION); } diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp index d1c55892ce..c2a14a9a1a 100644 --- a/pcsx2/ImGui/FullscreenUI.cpp +++ b/pcsx2/ImGui/FullscreenUI.cpp @@ -4066,8 +4066,9 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad FSUI_NSTR("Force 32bit"), }; static constexpr const char* s_blending_options[] = { + FSUI_NSTR("Automatic (Default)"), FSUI_NSTR("Minimum"), - FSUI_NSTR("Basic (Recommended)"), + FSUI_NSTR("Basic"), FSUI_NSTR("Medium"), FSUI_NSTR("High"), FSUI_NSTR("Full (Slow)"), @@ -4199,7 +4200,7 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad "EmuCore/GS", "dithering_ps2", 2, s_dithering_options, std::size(s_dithering_options), true); DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_SPLOTCH, "Blending Accuracy"), FSUI_CSTR("Determines the level of accuracy when emulating blend modes not supported by the host graphics API."), "EmuCore/GS", - "accurate_blending_unit", static_cast(AccBlendLevel::Basic), s_blending_options, std::size(s_blending_options), true); + "accurate_blending_unit", static_cast(AccBlendLevel::Automatic), s_blending_options, std::size(s_blending_options), true); DrawToggleSetting( bsi, FSUI_ICONSTR(ICON_FA_BULLSEYE, "Mipmapping"), FSUI_CSTR("Enables emulation of the GS's texture mipmapping."), "EmuCore/GS", "hw_mipmap", true); } diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 91346dabab..15587f7e11 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -653,6 +653,7 @@ const char* Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames[(size_t)FMVAspectR nullptr}; const char* Pcsx2Config::GSOptions::BlendingLevelNames[] = { + "Automatic", "Minimum", "Basic", "Medium", diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index 5b4f84acae..7c2eb171c3 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -3150,12 +3150,12 @@ void VMManager::WarnAboutUnsafeSettings() if (EmuConfig.GS.TriFilter != TriFiltering::Automatic) { append(ICON_FA_PAGER, - TRANSLATE_SV("VMManager", "Trilinear filtering is not set to automatic. This may break rendering in some games.")); + TRANSLATE_SV("VMManager", "Trilinear filtering is not set to Automatic. This may break rendering in some games.")); } - if (EmuConfig.GS.AccurateBlendingUnit <= AccBlendLevel::Minimum) + if (EmuConfig.GS.AccurateBlendingUnit == AccBlendLevel::Minimum) { append(ICON_FA_PAINTBRUSH, - TRANSLATE_SV("VMManager", "Blending Accuracy is below Basic, this may break effects in some games.")); + TRANSLATE_SV("VMManager", "Blending Accuracy is set to Minimum. This may break rendering in some games.")); } if (EmuConfig.GS.HWDownloadMode != GSHardwareDownloadMode::Enabled) {