CPU clock rate slider
Some checks failed
eden-build / source (push) Successful in 7m40s
eden-build / android (push) Failing after 17m50s
eden-build / linux (push) Failing after 25m30s
eden-license / license-header (pull_request_target) Has been cancelled
eden-build / windows (msvc) (push) Has been cancelled

very wip

Signed-off-by: swurl <swurl@swurl.xyz>
This commit is contained in:
swurl 2025-04-17 01:40:19 -04:00
parent be1c1e4a48
commit 2b0a8fcd6d
Signed by: crueter
GPG key ID: A5A7629F109C8FD1
13 changed files with 94 additions and 35 deletions

View file

@ -198,6 +198,7 @@ struct Values {
MemoryLayout::Memory_8Gb, MemoryLayout::Memory_8Gb,
"memory_layout_mode", "memory_layout_mode",
Category::Core}; Category::Core};
SwitchableSetting<bool> use_speed_limit{ SwitchableSetting<bool> use_speed_limit{
linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, false, true}; linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, false, true};
SwitchableSetting<u16, true> speed_limit{linkage, SwitchableSetting<u16, true> speed_limit{linkage,
@ -229,6 +230,12 @@ struct Values {
SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto, SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto,
CpuAccuracy::Auto, CpuAccuracy::Paranoid, CpuAccuracy::Auto, CpuAccuracy::Paranoid,
"cpu_accuracy", Category::Cpu}; "cpu_accuracy", Category::Cpu};
SwitchableSetting<u32, true> cpu_clock_rate{linkage, 1020,
500, 1785,
"cpu_clock_rate", Category::Cpu,
Specialization::Scalar};
SwitchableSetting<bool> cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug}; SwitchableSetting<bool> cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug};
Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug}; Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};

View file

@ -8,6 +8,7 @@
#include <ratio> #include <ratio>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hardware_properties.h"
namespace Common { namespace Common {
@ -15,7 +16,9 @@ class WallClock {
public: public:
static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz
static constexpr u64 CPUTickFreq = 1'020'000'000; // T210/4 A57 CPU Tick Frequency = 1020.0 MHz static inline u64 CPUTickFreq() {
return Core::Hardware::BASE_CLOCK_RATE();
}
virtual ~WallClock() = default; virtual ~WallClock() = default;
@ -51,19 +54,19 @@ public:
// Cycle Timing // Cycle Timing
static inline u64 CPUTickToNS(u64 cpu_tick) { static inline u64 CPUTickToNS(u64 cpu_tick) {
return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den; return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den();
} }
static inline u64 CPUTickToUS(u64 cpu_tick) { static inline u64 CPUTickToUS(u64 cpu_tick) {
return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den; return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den();
} }
static inline u64 CPUTickToCNTPCT(u64 cpu_tick) { static inline u64 CPUTickToCNTPCT(u64 cpu_tick) {
return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den; return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den();
} }
static inline u64 CPUTickToGPUTick(u64 cpu_tick) { static inline u64 CPUTickToGPUTick(u64 cpu_tick) {
return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den; return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den();
} }
protected: protected:
@ -78,10 +81,33 @@ protected:
// Cycle Timing // Cycle Timing
using CPUTickToNsRatio = std::ratio<std::nano::den, CPUTickFreq>; struct CPUTickToNsRatio {
using CPUTickToUsRatio = std::ratio<std::micro::den, CPUTickFreq>; static inline std::intmax_t num = std::nano::den;
using CPUTickToCNTPCTRatio = std::ratio<CNTFRQ, CPUTickFreq>; static inline std::intmax_t den() {
using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>; return CPUTickFreq();
}
};
struct CPUTickToUsRatio {
static inline std::intmax_t num = std::micro::den;
static inline std::intmax_t den() {
return CPUTickFreq();
}
};
struct CPUTickToCNTPCTRatio {
static inline std::intmax_t num = CNTFRQ;
static inline std::intmax_t den() {
return CPUTickFreq();
}
};
struct CPUTickToGPUTickRatio {
static inline std::intmax_t num = GPUTickFreq;
static inline std::intmax_t den() {
return CPUTickFreq();
}
};
}; };
std::unique_ptr<WallClock> CreateOptimalClock(); std::unique_ptr<WallClock> CreateOptimalClock();

View file

@ -1,19 +1,26 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <array> #include <array>
#include <tuple> #include <iostream>
#include "common/bit_util.h" #include "common/bit_util.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/settings.h"
#include "common/logging/log.h"
namespace Core { namespace Core {
namespace Hardware { namespace Hardware {
constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz inline u64 BASE_CLOCK_RATE() {
LOG_DEBUG(Core, "Settings reported clock rate={:08X}", Settings::values.cpu_clock_rate.GetValue());
// std::cout << Settings::values.cpu_clock_rate.GetValue() << std::endl;
return Settings::values.cpu_clock_rate.GetValue() * 1'000'000;
}
constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores

View file

@ -7,7 +7,6 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hle/service/apm/apm_controller.h" #include "core/hle/service/apm/apm_controller.h"
@ -81,8 +80,10 @@ PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(Performa
void Controller::SetClockSpeed(u32 mhz) { void Controller::SetClockSpeed(u32 mhz) {
LOG_DEBUG(Service_APM, "called, mhz={:08X}", mhz); LOG_DEBUG(Service_APM, "called, mhz={:08X}", mhz);
// TODO(DarkLordZach): Actually signal core_timing to change clock speed.
// TODO(Rodrigo): Remove [[maybe_unused]] when core_timing is used. // TODO: needs to be verified
// Settings::values.cpu_clock_rate.SetGlobal(false);
// Settings::values.cpu_clock_rate.SetValue(mhz);
} }
} // namespace Service::APM } // namespace Service::APM

View file

@ -184,7 +184,7 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
CheckIfParametersMet(); CheckIfParametersMet();
}); });
connect(connected_controller_checkboxes[i], &QCheckBox::stateChanged, [this, i](int state) { connect(connected_controller_checkboxes[i], &QCheckBox::checkStateChanged, [this, i](int state) {
player_groupboxes[i]->setChecked(state == Qt::Checked); player_groupboxes[i]->setChecked(state == Qt::Checked);
UpdateControllerIcon(i); UpdateControllerIcon(i);
UpdateControllerState(i); UpdateControllerState(i);

View file

@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <memory> #include <memory>
#include <typeinfo>
#include <vector> #include <vector>
#include <QComboBox> #include <QComboBox>
#include "common/common_types.h" #include "common/common_types.h"
@ -39,10 +38,12 @@ ConfigureCpu::ConfigureCpu(const Core::System& system_,
ConfigureCpu::~ConfigureCpu() = default; ConfigureCpu::~ConfigureCpu() = default;
void ConfigureCpu::SetConfiguration() {} void ConfigureCpu::SetConfiguration() {}
void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) { void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
auto* accuracy_layout = ui->widget_accuracy->layout(); auto* accuracy_layout = ui->widget_accuracy->layout();
auto* backend_layout = ui->widget_backend->layout(); auto* backend_layout = ui->widget_backend->layout();
auto* unsafe_layout = ui->unsafe_widget->layout(); auto* unsafe_layout = ui->unsafe_widget->layout();
auto* clock_layout = ui->widget_clock->layout();
std::map<u32, QWidget*> unsafe_hold{}; std::map<u32, QWidget*> unsafe_hold{};
std::vector<Settings::BasicSetting*> settings; std::vector<Settings::BasicSetting*> settings;
@ -73,6 +74,8 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
} else if (setting->Id() == Settings::values.cpu_backend.Id()) { } else if (setting->Id() == Settings::values.cpu_backend.Id()) {
backend_layout->addWidget(widget); backend_layout->addWidget(widget);
backend_combobox = widget->combobox; backend_combobox = widget->combobox;
} else if (setting->Id() == Settings::values.cpu_clock_rate.Id()) {
clock_layout->addWidget(widget);
} else { } else {
// Presently, all other settings here are unsafe checkboxes // Presently, all other settings here are unsafe checkboxes
unsafe_hold.insert({setting->Id(), widget}); unsafe_hold.insert({setting->Id(), widget});

View file

@ -59,8 +59,25 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="clock_group">
<property name="title">
<string>Clock</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="widget_clock" native="true">
<layout class="QVBoxLayout" name="clock_layout"/>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="backend_group"> <widget class="QGroupBox" name="backend_group">
<property name="visible">
<bool>false</bool>
</property>
<property name="title"> <property name="title">
<string>CPU Backend</string> <string>CPU Backend</string>
</property> </property>
@ -84,9 +101,6 @@
</widget> </widget>
</item> </item>
</layout> </layout>
<property name="visible">
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -129,10 +143,10 @@
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Orientation::Vertical</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Expanding</enum> <enum>QSizePolicy::Policy::Expanding</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>

View file

@ -29,9 +29,9 @@ ConfigureFilesystem::ConfigureFilesystem(QWidget* parent)
connect(ui->reset_game_list_cache, &QPushButton::pressed, this, connect(ui->reset_game_list_cache, &QPushButton::pressed, this,
&ConfigureFilesystem::ResetMetadata); &ConfigureFilesystem::ResetMetadata);
connect(ui->gamecard_inserted, &QCheckBox::stateChanged, this, connect(ui->gamecard_inserted, &QCheckBox::checkStateChanged, this,
&ConfigureFilesystem::UpdateEnabledControls); &ConfigureFilesystem::UpdateEnabledControls);
connect(ui->gamecard_current_game, &QCheckBox::stateChanged, this, connect(ui->gamecard_current_game, &QCheckBox::checkStateChanged, this,
&ConfigureFilesystem::UpdateEnabledControls); &ConfigureFilesystem::UpdateEnabledControls);
} }

View file

@ -74,13 +74,13 @@ ConfigureInputAdvanced::ConfigureInputAdvanced(Core::HID::HIDCore& hid_core_, QW
} }
} }
connect(ui->mouse_enabled, &QCheckBox::stateChanged, this, connect(ui->mouse_enabled, &QCheckBox::checkStateChanged, this,
&ConfigureInputAdvanced::UpdateUIEnabled); &ConfigureInputAdvanced::UpdateUIEnabled);
connect(ui->debug_enabled, &QCheckBox::stateChanged, this, connect(ui->debug_enabled, &QCheckBox::checkStateChanged, this,
&ConfigureInputAdvanced::UpdateUIEnabled); &ConfigureInputAdvanced::UpdateUIEnabled);
connect(ui->touchscreen_enabled, &QCheckBox::stateChanged, this, connect(ui->touchscreen_enabled, &QCheckBox::checkStateChanged, this,
&ConfigureInputAdvanced::UpdateUIEnabled); &ConfigureInputAdvanced::UpdateUIEnabled);
connect(ui->enable_ring_controller, &QCheckBox::stateChanged, this, connect(ui->enable_ring_controller, &QCheckBox::checkStateChanged, this,
&ConfigureInputAdvanced::UpdateUIEnabled); &ConfigureInputAdvanced::UpdateUIEnabled);
connect(ui->debug_configure, &QPushButton::clicked, this, connect(ui->debug_configure, &QPushButton::clicked, this,

View file

@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono> #include <chrono>
#include <optional>
#include <vector> #include <vector>
#include <QCheckBox> #include <QCheckBox>
@ -83,7 +82,7 @@ ConfigureSystem::ConfigureSystem(Core::System& system_,
connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check); connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check); connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
connect(checkbox_rtc, qOverload<int>(&QCheckBox::stateChanged), this, update_rtc_date); connect(checkbox_rtc, &QCheckBox::checkStateChanged, this, update_rtc_date);
connect(date_rtc_offset, qOverload<int>(&QSpinBox::valueChanged), this, update_rtc_date); connect(date_rtc_offset, qOverload<int>(&QSpinBox::valueChanged), this, update_rtc_date);
connect(date_rtc, &QDateTimeEdit::dateTimeChanged, this, update_date_offset); connect(date_rtc, &QDateTimeEdit::dateTimeChanged, this, update_date_offset);

View file

@ -119,11 +119,11 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent)
SetConfiguration(); SetConfiguration();
// Force game list reload if any of the relevant settings are changed. // Force game list reload if any of the relevant settings are changed.
connect(ui->show_add_ons, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); connect(ui->show_add_ons, &QCheckBox::checkStateChanged, this, &ConfigureUi::RequestGameListUpdate);
connect(ui->show_compat, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); connect(ui->show_compat, &QCheckBox::checkStateChanged, this, &ConfigureUi::RequestGameListUpdate);
connect(ui->show_size, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); connect(ui->show_size, &QCheckBox::checkStateChanged, this, &ConfigureUi::RequestGameListUpdate);
connect(ui->show_types, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); connect(ui->show_types, &QCheckBox::checkStateChanged, this, &ConfigureUi::RequestGameListUpdate);
connect(ui->show_play_time, &QCheckBox::stateChanged, this, connect(ui->show_play_time, &QCheckBox::checkStateChanged, this,
&ConfigureUi::RequestGameListUpdate); &ConfigureUi::RequestGameListUpdate);
connect(ui->game_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(ui->game_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&ConfigureUi::RequestGameListUpdate); &ConfigureUi::RequestGameListUpdate);

View file

@ -77,6 +77,8 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless " tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless "
"you know what you are doing.")); "you know what you are doing."));
INSERT(Settings, cpu_backend, tr("Backend:"), QStringLiteral()); INSERT(Settings, cpu_backend, tr("Backend:"), QStringLiteral());
INSERT(Settings, cpu_clock_rate, tr("CPU Clock Rate (MHz):"), tr("Increasing CPU clock rate may "
"improve performance, but may also reduce stability."));
// Cpu Debug // Cpu Debug

View file

@ -699,7 +699,7 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
restore_func(); restore_func();
} }
}; };
connect(checkbox, &QCheckBox::stateChanged, reset); connect(checkbox, &QCheckBox::checkStateChanged, reset);
reset(checkbox->checkState()); reset(checkbox->checkState());
} }
} }