diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index eccf0549e7..a412a80a2e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -16,6 +16,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { RENDERER_USE_SPEED_LIMIT("use_speed_limit"), USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"), SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"), + ANTIFLICKER("antiflicker"), FIX_BLOOM_EFFECTS("fix_bloom_effects"), EMULATE_BGR565("emulate_bgr565"), RESCALE_HACK("rescale_hack"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 230390749e..f95c53720f 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -750,6 +750,13 @@ abstract class SettingsItem( descriptionId = R.string.skip_cpu_inner_invalidation_description ) ) + put( + SwitchSetting( + BooleanSetting.ANTIFLICKER, + titleId = R.string.antiflicker, + descriptionId = R.string.antiflicker_description + ) + ) put( SwitchSetting( BooleanSetting.FIX_BLOOM_EFFECTS, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 4da218bfcc..92a4a19fcd 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -291,6 +291,7 @@ class SettingsFragmentPresenter( add(IntSetting.FAST_GPU_TIME.key) add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key) + add(BooleanSetting.ANTIFLICKER.key) add(BooleanSetting.FIX_BLOOM_EFFECTS.key) add(BooleanSetting.EMULATE_BGR565.key) add(BooleanSetting.RESCALE_HACK.key) diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 7372fa5e34..815660fe5c 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -509,6 +509,8 @@ Forces most games to run at their highest native resolution. Use 256 for maximal performance and 512 for maximal graphics fidelity. Skip CPU Inner Invalidation Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games. + Anti-Flicker + Forces GPU fence callbacks to wait for submitted GPU work. Use with Fast GPU mode, to avoid flicker with lower performance impact. Fix Bloom Effects Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games. Emulate BGR565 diff --git a/src/common/settings.h b/src/common/settings.h index e8877fce1e..f38e95d5a4 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -545,6 +545,13 @@ struct Values { Specialization::Default, true, true}; + SwitchableSetting antiflicker{linkage, + false, + "antiflicker", + Category::RendererHacks, + Specialization::Default, + true, + true}; SwitchableSetting async_presentation{linkage, #ifdef ANDROID false, diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 6b8f8e73b6..2429a2632f 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -193,6 +193,9 @@ std::unique_ptr InitializeTranslations(QObject* parent) { INSERT(Settings, skip_cpu_inner_invalidation, tr("Skip CPU Inner Invalidation"), tr("Skips certain cache invalidations during memory updates, reducing CPU usage and " "improving latency. This may cause soft-crashes.")); + INSERT(Settings, antiflicker, tr("Anti-Flicker"), + tr("Forces GPU fence callbacks to wait for submitted GPU work.\n" + "Use with Fast GPU mode, to avoid flicker with lower performance impact.")); INSERT(Settings, vsync_mode, tr("VSync Mode:"), tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " "refresh rate.\nFIFO Relaxed allows tearing as it recovers from a slow down.\n" diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index e4c4329e81..b9f5e1a9c0 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -76,9 +76,9 @@ public: TryReleasePendingFences(); } const bool should_flush = ShouldFlush(); - const bool delay_fence = Settings::IsGPULevelHigh() || (Settings::IsGPULevelMedium() && should_flush); + const bool delay_fence = Settings::values.antiflicker.GetValue() || !Settings::IsGPULevelLow(); CommitAsyncFlushes(); - TFence new_fence = CreateFence(!should_flush); + TFence new_fence = CreateFence(!should_flush && !delay_fence); if constexpr (can_async_check) { guard.lock(); }