configure_cpu: Generate UI

This commit is contained in:
lat9nq 2023-05-18 22:54:58 -04:00
parent c5a3642cb6
commit daa31121ee
5 changed files with 92 additions and 188 deletions

View file

@ -5,88 +5,83 @@
#include <memory> #include <memory>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/settings.h" #include "common/settings.h"
#include "configuration/shared_widget.h"
#include "core/core.h" #include "core/core.h"
#include "ui_configure_cpu.h" #include "ui_configure_cpu.h"
#include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_cpu.h" #include "yuzu/configuration/configure_cpu.h"
ConfigureCpu::ConfigureCpu(const Core::System& system_, ConfigureCpu::ConfigureCpu(
const Core::System& system_,
std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
QWidget* parent) const ConfigurationShared::TranslationMap& translations_,
: Tab(group, parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_} { const ConfigurationShared::ComboboxTranslationMap& combobox_translations_, QWidget* parent)
: Tab(group, parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_},
translations{translations_}, combobox_translations{combobox_translations_} {
ui->setupUi(this); ui->setupUi(this);
SetupPerGameUI(); Setup();
SetConfiguration(); SetConfiguration();
connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this, connect(accuracy_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureCpu::UpdateGroup); &ConfigureCpu::UpdateGroup);
} }
ConfigureCpu::~ConfigureCpu() = default; ConfigureCpu::~ConfigureCpu() = default;
void ConfigureCpu::SetConfiguration() { void ConfigureCpu::SetConfiguration() {}
void ConfigureCpu::Setup() {
const bool runtime_lock = !system.IsPoweredOn(); const bool runtime_lock = !system.IsPoweredOn();
auto* accuracy_layout = ui->widget_accuracy->layout();
auto* unsafe_layout = ui->unsafe_widget->layout();
std::map<std::string, QWidget*> unsafe_hold{};
ui->accuracy->setEnabled(runtime_lock); std::forward_list<Settings::BasicSetting*> settings;
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock); const auto push = [&](Settings::Category category) {
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock); for (const auto setting : Settings::values.linkage.by_category[category]) {
ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock); settings.push_front(setting);
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
ui->cpuopt_unsafe_ignore_global_monitor->setEnabled(runtime_lock);
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue());
ui->cpuopt_unsafe_ignore_standard_fpcr->setChecked(
Settings::values.cpuopt_unsafe_ignore_standard_fpcr.GetValue());
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
ui->cpuopt_unsafe_fastmem_check->setChecked(
Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
ui->cpuopt_unsafe_ignore_global_monitor->setChecked(
Settings::values.cpuopt_unsafe_ignore_global_monitor.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
} else {
ConfigurationShared::SetPerGameSetting(ui->accuracy, &Settings::values.cpu_accuracy);
ConfigurationShared::SetHighlight(ui->widget_accuracy,
!Settings::values.cpu_accuracy.UsingGlobal());
} }
UpdateGroup(ui->accuracy->currentIndex()); };
push(Settings::Category::Cpu);
push(Settings::Category::CpuUnsafe);
for (const auto setting : settings) {
auto* widget = new ConfigurationShared::Widget(setting, translations, combobox_translations,
this, runtime_lock, apply_funcs);
if (!widget->Valid()) {
delete widget;
continue;
}
if (setting->Id() == Settings::values.cpu_accuracy.Id()) {
accuracy_layout->addWidget(widget);
accuracy_combobox = widget->combobox;
} else {
unsafe_hold.insert({setting->GetLabel(), widget});
}
}
for (const auto& [label, widget] : unsafe_hold) {
unsafe_layout->addWidget(widget);
}
UpdateGroup(accuracy_combobox->currentIndex());
} }
void ConfigureCpu::UpdateGroup(int index) { void ConfigureCpu::UpdateGroup(int index) {
if (!Settings::IsConfiguringGlobal()) { const auto accuracy = static_cast<Settings::CPUAccuracy>(
index -= ConfigurationShared::USE_GLOBAL_OFFSET; combobox_translations.at(typeid(Settings::CPUAccuracy))[index].first);
}
const auto accuracy = static_cast<Settings::CPUAccuracy>(index);
ui->unsafe_group->setVisible(accuracy == Settings::CPUAccuracy::Unsafe); ui->unsafe_group->setVisible(accuracy == Settings::CPUAccuracy::Unsafe);
} }
void ConfigureCpu::ApplyConfiguration() { void ConfigureCpu::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpu_accuracy, ui->accuracy); const bool is_powered_on = system.IsPoweredOn();
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_unfuse_fma, for (const auto& apply_func : apply_funcs) {
ui->cpuopt_unsafe_unfuse_fma, apply_func(is_powered_on);
cpuopt_unsafe_unfuse_fma); }
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_reduce_fp_error,
ui->cpuopt_unsafe_reduce_fp_error,
cpuopt_unsafe_reduce_fp_error);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
ui->cpuopt_unsafe_ignore_standard_fpcr,
cpuopt_unsafe_ignore_standard_fpcr);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
ui->cpuopt_unsafe_inaccurate_nan,
cpuopt_unsafe_inaccurate_nan);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
ui->cpuopt_unsafe_fastmem_check,
cpuopt_unsafe_fastmem_check);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_global_monitor,
ui->cpuopt_unsafe_ignore_global_monitor,
cpuopt_unsafe_ignore_global_monitor);
} }
void ConfigureCpu::changeEvent(QEvent* event) { void ConfigureCpu::changeEvent(QEvent* event) {
@ -100,32 +95,3 @@ void ConfigureCpu::changeEvent(QEvent* event) {
void ConfigureCpu::RetranslateUI() { void ConfigureCpu::RetranslateUI() {
ui->retranslateUi(this); ui->retranslateUi(this);
} }
void ConfigureCpu::SetupPerGameUI() {
if (Settings::IsConfiguringGlobal()) {
return;
}
ConfigurationShared::SetColoredComboBox(
ui->accuracy, ui->widget_accuracy,
static_cast<u32>(Settings::values.cpu_accuracy.GetValue(true)));
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_unfuse_fma,
Settings::values.cpuopt_unsafe_unfuse_fma,
cpuopt_unsafe_unfuse_fma);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_reduce_fp_error,
Settings::values.cpuopt_unsafe_reduce_fp_error,
cpuopt_unsafe_reduce_fp_error);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_standard_fpcr,
Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
cpuopt_unsafe_ignore_standard_fpcr);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
Settings::values.cpuopt_unsafe_inaccurate_nan,
cpuopt_unsafe_inaccurate_nan);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check,
Settings::values.cpuopt_unsafe_fastmem_check,
cpuopt_unsafe_fastmem_check);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_global_monitor,
Settings::values.cpuopt_unsafe_ignore_global_monitor,
cpuopt_unsafe_ignore_global_monitor);
}

View file

@ -19,6 +19,8 @@ class ConfigureCpu : public ConfigurationShared::Tab {
public: public:
explicit ConfigureCpu(const Core::System& system_, explicit ConfigureCpu(const Core::System& system_,
std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
const ConfigurationShared::TranslationMap& translations,
const ConfigurationShared::ComboboxTranslationMap& combobox_translations,
QWidget* parent = nullptr); QWidget* parent = nullptr);
~ConfigureCpu() override; ~ConfigureCpu() override;
@ -31,7 +33,7 @@ private:
void UpdateGroup(int index); void UpdateGroup(int index);
void SetupPerGameUI(); void Setup();
std::unique_ptr<Ui::ConfigureCpu> ui; std::unique_ptr<Ui::ConfigureCpu> ui;
@ -43,4 +45,11 @@ private:
ConfigurationShared::CheckState cpuopt_unsafe_ignore_global_monitor; ConfigurationShared::CheckState cpuopt_unsafe_ignore_global_monitor;
const Core::System& system; const Core::System& system;
const ConfigurationShared::TranslationMap& translations;
const ConfigurationShared::ComboboxTranslationMap& combobox_translations;
std::forward_list<std::function<void(bool)>> apply_funcs{};
QComboBox* accuracy_combobox;
}; };

View file

@ -27,38 +27,19 @@
<layout class="QVBoxLayout"> <layout class="QVBoxLayout">
<item> <item>
<widget class="QWidget" name="widget_accuracy" native="true"> <widget class="QWidget" name="widget_accuracy" native="true">
<layout class="QHBoxLayout" name="layout_accuracy"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <property name="leftMargin">
<widget class="QLabel" name="label_accuracy"> <number>0</number>
<property name="text">
<string>Accuracy:</string>
</property> </property>
</widget> <property name="topMargin">
</item> <number>0</number>
<item>
<widget class="QComboBox" name="accuracy">
<item>
<property name="text">
<string>Auto</string>
</property> </property>
</item> <property name="rightMargin">
<item> <number>0</number>
<property name="text">
<string>Accurate</string>
</property> </property>
</item> <property name="bottomMargin">
<item> <number>0</number>
<property name="text">
<string>Unsafe</string>
</property> </property>
</item>
<item>
<property name="text">
<string>Paranoid (disables most optimizations)</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -96,75 +77,21 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cpuopt_unsafe_unfuse_fma"> <widget class="QWidget" name="unsafe_widget" native="true">
<property name="toolTip"> <layout class="QVBoxLayout" name="unsafe_layout">
<string> <property name="leftMargin">
&lt;div&gt;This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.&lt;/div&gt; <number>0</number>
</string>
</property> </property>
<property name="text"> <property name="topMargin">
<string>Unfuse FMA (improve performance on CPUs without FMA)</string> <number>0</number>
</property> </property>
</widget> <property name="rightMargin">
</item> <number>0</number>
<item>
<widget class="QCheckBox" name="cpuopt_unsafe_reduce_fp_error">
<property name="toolTip">
<string>
&lt;div&gt;This option improves the speed of some approximate floating-point functions by using less accurate native approximations.&lt;/div&gt;
</string>
</property> </property>
<property name="text"> <property name="bottomMargin">
<string>Faster FRSQRTE and FRECPE</string> <number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_standard_fpcr">
<property name="toolTip">
<string>
&lt;div&gt;This option improves the speed of 32 bits ASIMD floating-point functions by running with incorrect rounding modes.&lt;/div&gt;
</string>
</property>
<property name="text">
<string>Faster ASIMD instructions (32 bits only)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_unsafe_inaccurate_nan">
<property name="toolTip">
<string>
&lt;div&gt;This option improves speed by removing NaN checking. Please note this also reduces accuracy of certain floating-point instructions.&lt;/div&gt;
</string>
</property>
<property name="text">
<string>Inaccurate NaN handling</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_unsafe_fastmem_check">
<property name="toolTip">
<string>
&lt;div&gt;This option improves speed by eliminating a safety check before every memory read/write in guest. Disabling it may allow a game to read/write the emulator's memory.&lt;/div&gt;
</string>
</property>
<property name="text">
<string>Disable address space checks</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_global_monitor">
<property name="toolTip">
<string>
&lt;div&gt;This option improves speed by relying only on the semantics of cmpxchg to ensure safety of exclusive access instructions. Please note this may result in deadlocks and other race conditions.&lt;/div&gt;
</string>
</property>
<property name="text">
<string>Ignore global monitor</string>
</property> </property>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>

View file

@ -37,7 +37,8 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
combobox_translations{ConfigurationShared::ComboboxEnumeration(this)}, combobox_translations{ConfigurationShared::ComboboxEnumeration(this)},
audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, *translations, audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, *translations,
*combobox_translations, this)}, *combobox_translations, this)},
cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, this)}, cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, *translations,
*combobox_translations, this)},
debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)},
filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, filesystem_tab{std::make_unique<ConfigureFilesystem>(this)},
general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, *translations, general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, *translations,

View file

@ -53,7 +53,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this); addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this);
audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *translations, audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *translations,
*combobox_translations, this); *combobox_translations, this);
cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, this); cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, *translations,
*combobox_translations, this);
graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>( graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(
system_, tab_group, *translations, *combobox_translations, this); system_, tab_group, *translations, *combobox_translations, this);
graphics_tab = std::make_unique<ConfigureGraphics>( graphics_tab = std::make_unique<ConfigureGraphics>(