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 81702d7110..594099f159 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
@@ -250,8 +250,9 @@ class SettingsFragmentPresenter(
add(BooleanSetting.USE_CUSTOM_RTC.key)
add(LongSetting.CUSTOM_RTC.key)
- add(HeaderSetting(R.string.cpu))
+ add(HeaderSetting(R.string.clocks))
add(IntSetting.FAST_CPU_TIME.key)
+ add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
add(IntSetting.MEMORY_LAYOUT.key)
@@ -298,7 +299,6 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.hacks))
- add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
add(BooleanSetting.EMULATE_BGR565.key)
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index 7a69d5b48b..1bad110d14 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -34,7 +34,7 @@
- - @string/off
+ - @string/clock_normal
- @string/clock_boost
- @string/clock_fast
@@ -547,7 +547,7 @@
- - @string/off
+ - @string/fast_gpu_normal
- @string/fast_gpu_medium
- @string/fast_gpu_high
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 3023327f14..d534ebb37c 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -450,8 +450,8 @@
Set custom RTC
- CPU Overclock
- Forces the emulated CPU to run at a higher clock, reducing certain FPS limiters. Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.
+ CPU Clocks
+ Forces the emulated CPU to run at a higher clock, reducing certain FPS limiters. Normal is the Switch\'s 1020MHz base clock, Boost (1734MHz) matches its highest native clock, and Fast (2040MHz) runs at 2x base.
Custom CPU Ticks
Set a custom value of CPU ticks. Higher values can increase performance, but may also cause the game to freeze. A range of 77–21000 is recommended.
Ticks
@@ -512,8 +512,8 @@
Hacks
- Fast GPU Time
- Forces most games to run at their highest native resolution. Use 256 for maximal performance and 512 for maximal graphics fidelity.
+ GPU Clocks
+ Makes the game believe GPU work finishes faster than it does, which stops it from lowering resolution or framerate to fit the Switch\'s clocks. Multiplies the reported GPU speed by 256x or 512x.
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.
Fix Bloom Effects
@@ -560,6 +560,7 @@
CPU
+ Clocks
Use Auto Stub
Automatically stub missing services and functions. This may improve compatibility but can cause crashes and stability issues.
@@ -969,13 +970,15 @@
8GB (Unsafe)
- Boost (1700MHz)
- Fast (2000MHz)
+ Normal (1020MHz)
+ Boost (1734MHz)
+ Fast (2040MHz)
Off
- Medium (256)
- High (512)
+ Normal (native)
+ Boost (256x)
+ Fast (512x)
Very Small (16 MB)
diff --git a/src/common/settings.h b/src/common/settings.h
index 00ba7dddc9..d25d5f690b 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -260,10 +260,10 @@ struct Values {
Category::Cpu};
SwitchableSetting cpu_accuracy{linkage, CpuAccuracy::Auto,
"cpu_accuracy", Category::Cpu};
- SwitchableSetting fast_cpu_time{linkage,
- CpuClock::Off,
+ SwitchableSetting cpu_clock{linkage,
+ CpuClock::Normal,
"fast_cpu_time",
- Category::Cpu,
+ Category::System,
Specialization::Default,
true,
true};
@@ -540,13 +540,13 @@ struct Values {
#endif
// Renderer Hacks //
- SwitchableSetting fast_gpu_time{linkage,
- GpuOverclock::Medium,
- "fast_gpu_time",
- Category::RendererHacks,
- Specialization::Default,
- true,
- true};
+ SwitchableSetting gpu_clock{linkage,
+ GpuClock::Boost,
+ "fast_gpu_time",
+ Category::System,
+ Specialization::Default,
+ true,
+ true};
SwitchableSetting skip_cpu_inner_invalidation{linkage,
false,
diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h
index 2db0e02a5f..edcc608b57 100644
--- a/src/common/settings_enums.h
+++ b/src/common/settings_enums.h
@@ -140,7 +140,7 @@ ENUM(DmaAccuracy, Default, Unsafe, Safe);
ENUM(GpuFenceBehavior, Default, Immediate, Balanced, Accurate, Strict);
ENUM(CpuBackend, Dynarmic, Nce);
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging);
-ENUM(CpuClock, Off, Boost, Fast)
+ENUM(CpuClock, Normal, Boost, Fast)
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb);
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
ENUM(FullscreenMode, Borderless, Exclusive);
@@ -152,7 +152,7 @@ ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
ENUM(ConsoleMode, Handheld, Docked);
ENUM(AppletMode, HLE, LLE);
ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
-ENUM(GpuOverclock, Normal, Medium, High)
+ENUM(GpuClock, Normal, Boost, Fast)
ENUM(GpuUnswizzleSize, VerySmall, Small, Normal, Large, VeryLarge)
ENUM(GpuUnswizzle, VeryLow, Low, Normal, Medium, High)
ENUM(GpuUnswizzleChunk, VeryLow, Low, Normal, Medium, High)
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index d18c8a72f1..7b53ae3200 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -23,6 +23,21 @@ namespace Core::Timing {
constexpr s64 MAX_SLICE_LENGTH = 10000;
+constexpr u32 CPU_CLOCK_BASE_MHZ = 1020;
+constexpr u32 CPU_CLOCK_BOOST_MHZ = 1734;
+constexpr u32 CPU_CLOCK_FAST_MHZ = 2040;
+
+constexpr u32 CpuClockTargetMhz(Settings::CpuClock clock) {
+ switch (clock) {
+ case Settings::CpuClock::Boost:
+ return CPU_CLOCK_BOOST_MHZ;
+ case Settings::CpuClock::Fast:
+ return CPU_CLOCK_FAST_MHZ;
+ default:
+ return CPU_CLOCK_BASE_MHZ;
+ }
+}
+
std::shared_ptr CreateEvent(std::string name, TimedCallback&& callback) {
return std::make_shared(std::move(callback), std::move(name));
}
@@ -210,8 +225,9 @@ void CoreTiming::ResetTicks() {
u64 CoreTiming::GetClockTicks() const {
u64 fres = is_multicore ? Common::g_wall_clock.GetCNTPCT() : Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
- if (auto const overclock = Settings::values.fast_cpu_time.GetValue(); overclock != Settings::CpuClock::Off) {
- fres = u64(f64(fres) * (1.7 + 0.3 * u32(overclock)));
+ if (const u32 target = CpuClockTargetMhz(Settings::values.cpu_clock.GetValue());
+ target != CPU_CLOCK_BASE_MHZ) {
+ fres = fres * target / CPU_CLOCK_BASE_MHZ;
}
if (::Settings::values.sync_core_speed.GetValue()) {
auto const ticks = f64(fres);
diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp
index 893e4a0854..a42344647c 100644
--- a/src/qt_common/config/shared_translation.cpp
+++ b/src/qt_common/config/shared_translation.cpp
@@ -92,12 +92,11 @@ std::unique_ptr InitializeTranslations(QObject* parent) {
tr("Change the accuracy of the emulated CPU (for debugging only)."));
INSERT(Settings, cpu_backend, tr("Backend:"), QString());
- INSERT(Settings, fast_cpu_time, tr("CPU Overclock"),
- tr("Overclocks the emulated CPU to remove some FPS limiters. Weaker CPUs may see "
- "reduced performance, "
- "and certain games may behave improperly.\nUse Boost (1700MHz) to run at the "
- "Switch's highest native "
- "clock, or Fast (2000MHz) to run at 2x clock."));
+ INSERT(Settings, cpu_clock, tr("CPU Clocks"),
+ tr("Sets the clock the emulated CPU reports, which removes some FPS limiters. Weaker "
+ "CPUs may see reduced performance, and certain games may behave improperly.\n"
+ "Normal is the Switch's 1020MHz base clock, Boost (1734MHz) matches its highest "
+ "native clock, and Fast (2040MHz) runs at 2x base."));
INSERT(Settings, use_custom_cpu_ticks, QString(), QString());
INSERT(Settings, cpu_ticks, tr("Custom CPU Ticks"),
@@ -230,9 +229,10 @@ std::unique_ptr InitializeTranslations(QObject* parent) {
tr("Preserves GPU-modified data by reading it back before uploading.\nSome games require this to render certain effects properly."));
INSERT(Settings, use_asynchronous_shaders, tr("Enable asynchronous shader compilation"),
tr("May reduce shader stutter."));
- INSERT(Settings, fast_gpu_time, tr("Fast GPU Time"),
- tr("Overclocks the emulated GPU to increase dynamic resolution and render "
- "distance.\nUse 256 for maximal performance and 512 for maximal graphics fidelity."));
+ INSERT(Settings, gpu_clock, tr("GPU Clocks"),
+ tr("Makes the game believe GPU work finishes faster than it does, so it stops lowering "
+ "resolution and render distance to fit the Switch's clocks.\nBoost reports 256x the "
+ "GPU speed, Fast reports 512x."));
INSERT(Settings, gpu_unswizzle_enabled, tr("GPU Unswizzle"),
tr("Accelerates BCn 3D texture decoding using GPU compute.\n"
"Disable if experiencing crashes or graphical glitches."));
@@ -639,9 +639,9 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) {
}});
translations->insert({Settings::EnumMetadata::Index(),
{
- PAIR(CpuClock, Off, tr("Off")),
- PAIR(CpuClock, Boost, tr("Boost (1700MHz)")),
- PAIR(CpuClock, Fast, tr("Fast (2000MHz)")),
+ PAIR(CpuClock, Normal, tr("Normal (1020MHz)")),
+ PAIR(CpuClock, Boost, tr("Boost (1734MHz)")),
+ PAIR(CpuClock, Fast, tr("Fast (2040MHz)")),
}});
translations->insert(
{Settings::EnumMetadata::Index(),
@@ -650,11 +650,11 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) {
PAIR(ConfirmStop, Ask_Based_On_Game, tr("Only if game specifies not to stop")),
PAIR(ConfirmStop, Ask_Never, tr("Never ask")),
}});
- translations->insert({Settings::EnumMetadata::Index(),
+ translations->insert({Settings::EnumMetadata::Index(),
{
- PAIR(GpuOverclock, Normal, tr("Off")),
- PAIR(GpuOverclock, Medium, tr("Medium (256)")),
- PAIR(GpuOverclock, High, tr("High (512)")),
+ PAIR(GpuClock, Normal, tr("Normal (native)")),
+ PAIR(GpuClock, Boost, tr("Boost (256x)")),
+ PAIR(GpuClock, Fast, tr("Fast (512x)")),
}});
translations->insert({Settings::EnumMetadata::Index(),
{
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 548a8bf809..12f37ced80 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -39,6 +39,19 @@
namespace Tegra {
+namespace {
+constexpr u64 GpuClockMultiplier(Settings::GpuClock clock) {
+ switch (clock) {
+ case Settings::GpuClock::Boost:
+ return 256;
+ case Settings::GpuClock::Fast:
+ return 512;
+ default:
+ return 1;
+ }
+}
+} // Anonymous namespace
+
struct GPU::Impl {
explicit Impl(Core::System& system_, bool is_async_, bool use_nvdec_)
: system{system_}
@@ -145,14 +158,8 @@ struct GPU::Impl {
}
[[nodiscard]] u64 GetTicks() const {
- u64 gpu_tick = system.CoreTiming().GetGPUTicks();
- Settings::GpuOverclock overclock = Settings::values.fast_gpu_time.GetValue();
-
- if (overclock != Settings::GpuOverclock::Normal) {
- gpu_tick /= 256 * u64(overclock);
- }
-
- return gpu_tick;
+ const u64 gpu_tick = system.CoreTiming().GetGPUTicks();
+ return gpu_tick / GpuClockMultiplier(Settings::values.gpu_clock.GetValue());
}
void RendererFrameEndNotify() {
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 0511465ee6..8c7b15e4e0 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -76,8 +76,7 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
} else if (setting->Id() == Settings::values.cpu_backend.Id()) {
backend_layout->addWidget(widget);
backend_combobox = widget->combobox;
- } else if (setting->Id() == Settings::values.fast_cpu_time.Id() ||
- setting->Id() == Settings::values.cpu_ticks.Id()) {
+ } else if (setting->Id() == Settings::values.cpu_ticks.Id()) {
ui->general_layout->addWidget(widget);
} else {
// Presently, all other settings here are unsafe checkboxes