summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-07-14 18:38:03 +0200
committerGitHub <noreply@github.com>2020-07-14 18:38:03 +0200
commite2730372b8b26bf3141bf91107f9982e270f751b (patch)
treefb09276b0a1a736c6b106f1c6b51af9f97b3c307 /src
parentMerge pull request #4282 from Morph1984/fs-size (diff)
parentconfigure_cpu: Split optimization settings off into Debug tab (diff)
downloadyuzu-e2730372b8b26bf3141bf91107f9982e270f751b.tar
yuzu-e2730372b8b26bf3141bf91107f9982e270f751b.tar.gz
yuzu-e2730372b8b26bf3141bf91107f9982e270f751b.tar.bz2
yuzu-e2730372b8b26bf3141bf91107f9982e270f751b.tar.lz
yuzu-e2730372b8b26bf3141bf91107f9982e270f751b.tar.xz
yuzu-e2730372b8b26bf3141bf91107f9982e270f751b.tar.zst
yuzu-e2730372b8b26bf3141bf91107f9982e270f751b.zip
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp30
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp34
-rw-r--r--src/core/settings.h18
-rw-r--r--src/yuzu/CMakeLists.txt6
-rw-r--r--src/yuzu/configuration/config.cpp59
-rw-r--r--src/yuzu/configuration/config.h2
-rw-r--r--src/yuzu/configuration/configure.ui22
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp61
-rw-r--r--src/yuzu/configuration/configure_cpu.h33
-rw-r--r--src/yuzu/configuration/configure_cpu.ui92
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp65
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.h31
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui174
-rw-r--r--src/yuzu/configuration/configure_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp7
-rw-r--r--src/yuzu_cmd/config.cpp2
-rw-r--r--src/yuzu_cmd/default_ini.h36
-rw-r--r--src/yuzu_tester/default_ini.h33
19 files changed, 685 insertions, 29 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 0d4ab95b7..443ca72eb 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -142,10 +142,32 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
// Timing
config.wall_clock_cntpct = uses_wall_clock;
- // Optimizations
- if (Settings::values.disable_cpu_opt) {
- config.enable_optimizations = false;
- config.enable_fast_dispatch = false;
+ // Safe optimizations
+ if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) {
+ if (!Settings::values.cpuopt_page_tables) {
+ config.page_table = nullptr;
+ }
+ if (!Settings::values.cpuopt_block_linking) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
+ }
+ if (!Settings::values.cpuopt_return_stack_buffer) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
+ }
+ if (!Settings::values.cpuopt_fast_dispatcher) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
+ }
+ if (!Settings::values.cpuopt_context_elimination) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
+ }
+ if (!Settings::values.cpuopt_const_prop) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
+ }
+ if (!Settings::values.cpuopt_misc_ir) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
+ }
+ if (!Settings::values.cpuopt_reduce_misalign_checks) {
+ config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+ }
}
return std::make_unique<Dynarmic::A32::Jit>(config);
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 790981034..a63a04a25 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -191,15 +191,37 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
// Unpredictable instructions
config.define_unpredictable_behaviour = true;
- // Optimizations
- if (Settings::values.disable_cpu_opt) {
- config.enable_optimizations = false;
- config.enable_fast_dispatch = false;
- }
-
// Timing
config.wall_clock_cntpct = uses_wall_clock;
+ // Safe optimizations
+ if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) {
+ if (!Settings::values.cpuopt_page_tables) {
+ config.page_table = nullptr;
+ }
+ if (!Settings::values.cpuopt_block_linking) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
+ }
+ if (!Settings::values.cpuopt_return_stack_buffer) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
+ }
+ if (!Settings::values.cpuopt_fast_dispatcher) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
+ }
+ if (!Settings::values.cpuopt_context_elimination) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
+ }
+ if (!Settings::values.cpuopt_const_prop) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
+ }
+ if (!Settings::values.cpuopt_misc_ir) {
+ config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
+ }
+ if (!Settings::values.cpuopt_reduce_misalign_checks) {
+ config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+ }
+ }
+
return std::make_shared<Dynarmic::A64::Jit>(config);
}
diff --git a/src/core/settings.h b/src/core/settings.h
index 29dc57c16..3eb336f75 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -357,6 +357,11 @@ enum class GPUAccuracy : u32 {
Extreme = 2,
};
+enum class CPUAccuracy {
+ Accurate = 0,
+ DebugMode = 1,
+};
+
extern bool configuring_global;
template <typename Type>
@@ -402,6 +407,18 @@ struct Values {
// Core
Setting<bool> use_multi_core;
+ // Cpu
+ CPUAccuracy cpu_accuracy;
+
+ bool cpuopt_page_tables;
+ bool cpuopt_block_linking;
+ bool cpuopt_return_stack_buffer;
+ bool cpuopt_fast_dispatcher;
+ bool cpuopt_context_elimination;
+ bool cpuopt_const_prop;
+ bool cpuopt_misc_ir;
+ bool cpuopt_reduce_misalign_checks;
+
// Renderer
Setting<RendererBackend> renderer_backend;
bool renderer_debug;
@@ -476,7 +493,6 @@ struct Values {
bool dump_nso;
bool reporting_services;
bool quest_flag;
- bool disable_cpu_opt;
bool disable_macro_jit;
// Misceallaneous
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index ff7d9c1fa..a862b2610 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -30,6 +30,12 @@ add_executable(yuzu
configuration/configure_audio.cpp
configuration/configure_audio.h
configuration/configure_audio.ui
+ configuration/configure_cpu.cpp
+ configuration/configure_cpu.h
+ configuration/configure_cpu.ui
+ configuration/configure_cpu_debug.cpp
+ configuration/configure_cpu_debug.h
+ configuration/configure_cpu_debug.ui
configuration/configure_debug.cpp
configuration/configure_debug.h
configuration/configure_debug.ui
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index f48785697..9e9b38214 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -524,8 +524,6 @@ void Config::ReadDebuggingValues() {
Settings::values.reporting_services =
ReadSetting(QStringLiteral("reporting_services"), false).toBool();
Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool();
- Settings::values.disable_cpu_opt =
- ReadSetting(QStringLiteral("disable_cpu_opt"), false).toBool();
Settings::values.disable_macro_jit =
ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
@@ -617,6 +615,34 @@ void Config::ReadPathValues() {
qt_config->endGroup();
}
+void Config::ReadCpuValues() {
+ qt_config->beginGroup(QStringLiteral("Cpu"));
+
+ if (global) {
+ Settings::values.cpu_accuracy = static_cast<Settings::CPUAccuracy>(
+ ReadSetting(QStringLiteral("cpu_accuracy"), 0).toInt());
+
+ Settings::values.cpuopt_page_tables =
+ ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool();
+ Settings::values.cpuopt_block_linking =
+ ReadSetting(QStringLiteral("cpuopt_block_linking"), true).toBool();
+ Settings::values.cpuopt_return_stack_buffer =
+ ReadSetting(QStringLiteral("cpuopt_return_stack_buffer"), true).toBool();
+ Settings::values.cpuopt_fast_dispatcher =
+ ReadSetting(QStringLiteral("cpuopt_fast_dispatcher"), true).toBool();
+ Settings::values.cpuopt_context_elimination =
+ ReadSetting(QStringLiteral("cpuopt_context_elimination"), true).toBool();
+ Settings::values.cpuopt_const_prop =
+ ReadSetting(QStringLiteral("cpuopt_const_prop"), true).toBool();
+ Settings::values.cpuopt_misc_ir =
+ ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
+ Settings::values.cpuopt_reduce_misalign_checks =
+ ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
+ }
+
+ qt_config->endGroup();
+}
+
void Config::ReadRendererValues() {
qt_config->beginGroup(QStringLiteral("Renderer"));
@@ -813,6 +839,7 @@ void Config::ReadValues() {
ReadMiscellaneousValues();
}
ReadCoreValues();
+ ReadCpuValues();
ReadRendererValues();
ReadAudioValues();
ReadSystemValues();
@@ -913,6 +940,7 @@ void Config::SaveValues() {
SaveMiscellaneousValues();
}
SaveCoreValues();
+ SaveCpuValues();
SaveRendererValues();
SaveAudioValues();
SaveSystemValues();
@@ -1006,7 +1034,6 @@ void Config::SaveDebuggingValues() {
WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false);
- WriteSetting(QStringLiteral("disable_cpu_opt"), Settings::values.disable_cpu_opt, false);
WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
qt_config->endGroup();
@@ -1070,6 +1097,32 @@ void Config::SavePathValues() {
qt_config->endGroup();
}
+void Config::SaveCpuValues() {
+ qt_config->beginGroup(QStringLiteral("Cpu"));
+
+ if (global) {
+ WriteSetting(QStringLiteral("cpu_accuracy"),
+ static_cast<int>(Settings::values.cpu_accuracy), 0);
+
+ WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
+ true);
+ WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking,
+ true);
+ WriteSetting(QStringLiteral("cpuopt_return_stack_buffer"),
+ Settings::values.cpuopt_return_stack_buffer, true);
+ WriteSetting(QStringLiteral("cpuopt_fast_dispatcher"),
+ Settings::values.cpuopt_fast_dispatcher, true);
+ WriteSetting(QStringLiteral("cpuopt_context_elimination"),
+ Settings::values.cpuopt_context_elimination, true);
+ WriteSetting(QStringLiteral("cpuopt_const_prop"), Settings::values.cpuopt_const_prop, true);
+ WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
+ WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
+ Settings::values.cpuopt_reduce_misalign_checks, true);
+ }
+
+ qt_config->endGroup();
+}
+
void Config::SaveRendererValues() {
qt_config->beginGroup(QStringLiteral("Renderer"));
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 681f0bca5..8e815f829 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -49,6 +49,7 @@ private:
void ReadDisabledAddOnValues();
void ReadMiscellaneousValues();
void ReadPathValues();
+ void ReadCpuValues();
void ReadRendererValues();
void ReadShortcutValues();
void ReadSystemValues();
@@ -73,6 +74,7 @@ private:
void SaveDisabledAddOnValues();
void SaveMiscellaneousValues();
void SavePathValues();
+ void SaveCpuValues();
void SaveRendererValues();
void SaveShortcutValues();
void SaveSystemValues();
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index 9aec1bd09..5f5d8e571 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -78,6 +78,16 @@
<string>Hotkeys</string>
</attribute>
</widget>
+ <widget class="ConfigureCpu" name="cpuTab">
+ <attribute name="title">
+ <string>CPU</string>
+ </attribute>
+ </widget>
+ <widget class="ConfigureCpuDebug" name="cpuDebugTab">
+ <attribute name="title">
+ <string>Debug</string>
+ </attribute>
+ </widget>
<widget class="ConfigureGraphics" name="graphicsTab">
<attribute name="title">
<string>Graphics</string>
@@ -159,6 +169,18 @@
<container>1</container>
</customwidget>
<customwidget>
+ <class>ConfigureCpu</class>
+ <extends>QWidget</extends>
+ <header>configuration/configure_cpu.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>ConfigureCpuDebug</class>
+ <extends>QWidget</extends>
+ <header>configuration/configure_cpu_debug.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
<class>ConfigureGraphics</class>
<extends>QWidget</extends>
<header>configuration/configure_graphics.h</header>
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
new file mode 100644
index 000000000..7493e5ffb
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -0,0 +1,61 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QComboBox>
+#include <QMessageBox>
+
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/settings.h"
+#include "ui_configure_cpu.h"
+#include "yuzu/configuration/configure_cpu.h"
+
+ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureCpu) {
+ ui->setupUi(this);
+
+ SetConfiguration();
+
+ connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
+ &ConfigureCpu::AccuracyUpdated);
+}
+
+ConfigureCpu::~ConfigureCpu() = default;
+
+void ConfigureCpu::SetConfiguration() {
+ const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
+
+ ui->accuracy->setEnabled(runtime_lock);
+ ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy));
+}
+
+void ConfigureCpu::AccuracyUpdated(int index) {
+ if (static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) {
+ const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"),
+ tr("CPU Debug Mode is only intended for developer "
+ "use. Are you sure you want to enable this?"),
+ QMessageBox::Yes | QMessageBox::No);
+ if (result == QMessageBox::No) {
+ ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate));
+ return;
+ }
+ }
+}
+
+void ConfigureCpu::ApplyConfiguration() {
+ Settings::values.cpu_accuracy =
+ static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex());
+}
+
+void ConfigureCpu::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void ConfigureCpu::RetranslateUI() {
+ ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
new file mode 100644
index 000000000..e4741d3a4
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -0,0 +1,33 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+#include "core/settings.h"
+
+namespace Ui {
+class ConfigureCpu;
+}
+
+class ConfigureCpu : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit ConfigureCpu(QWidget* parent = nullptr);
+ ~ConfigureCpu() override;
+
+ void ApplyConfiguration();
+
+private:
+ void changeEvent(QEvent* event) override;
+ void RetranslateUI();
+
+ void AccuracyUpdated(int index);
+
+ void SetConfiguration();
+
+ std::unique_ptr<Ui::ConfigureCpu> ui;
+};
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
new file mode 100644
index 000000000..bf6ea79bb
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureCpu</class>
+ <widget class="QWidget" name="ConfigureCpu">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>321</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox">
+ <property name="title">
+ <string>General</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel">
+ <property name="text">
+ <string>Accuracy:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="accuracy">
+ <item>
+ <property name="text">
+ <string>Accurate</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Enable Debug Mode</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel">
+ <property name="wordWrap">
+ <bool>1</bool>
+ </property>
+ <property name="text">
+ <string>We recommend setting accuracy to "Accurate".</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_disable_info">
+ <property name="text">
+ <string>CPU settings are available only when game is not running.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
new file mode 100644
index 000000000..3385b2cf6
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -0,0 +1,65 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QComboBox>
+
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/settings.h"
+#include "ui_configure_cpu_debug.h"
+#include "yuzu/configuration/configure_cpu_debug.h"
+
+ConfigureCpuDebug::ConfigureCpuDebug(QWidget* parent)
+ : QWidget(parent), ui(new Ui::ConfigureCpuDebug) {
+ ui->setupUi(this);
+
+ SetConfiguration();
+}
+
+ConfigureCpuDebug::~ConfigureCpuDebug() = default;
+
+void ConfigureCpuDebug::SetConfiguration() {
+ const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
+
+ ui->cpuopt_page_tables->setEnabled(runtime_lock);
+ ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
+ ui->cpuopt_block_linking->setEnabled(runtime_lock);
+ ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking);
+ ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
+ ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer);
+ ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
+ ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher);
+ ui->cpuopt_context_elimination->setEnabled(runtime_lock);
+ ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination);
+ ui->cpuopt_const_prop->setEnabled(runtime_lock);
+ ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop);
+ ui->cpuopt_misc_ir->setEnabled(runtime_lock);
+ ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
+ ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
+ ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
+}
+
+void ConfigureCpuDebug::ApplyConfiguration() {
+ Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked();
+ Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked();
+ Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked();
+ Settings::values.cpuopt_fast_dispatcher = ui->cpuopt_fast_dispatcher->isChecked();
+ Settings::values.cpuopt_context_elimination = ui->cpuopt_context_elimination->isChecked();
+ Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
+ Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
+ Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
+}
+
+void ConfigureCpuDebug::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void ConfigureCpuDebug::RetranslateUI() {
+ ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h
new file mode 100644
index 000000000..c9941ef3b
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.h
@@ -0,0 +1,31 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+#include "core/settings.h"
+
+namespace Ui {
+class ConfigureCpuDebug;
+}
+
+class ConfigureCpuDebug : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit ConfigureCpuDebug(QWidget* parent = nullptr);
+ ~ConfigureCpuDebug() override;
+
+ void ApplyConfiguration();
+
+private:
+ void changeEvent(QEvent* event) override;
+ void RetranslateUI();
+
+ void SetConfiguration();
+
+ std::unique_ptr<Ui::ConfigureCpuDebug> ui;
+};
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
new file mode 100644
index 000000000..a90dc64fe
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureCpuDebug</class>
+ <widget class="QWidget" name="ConfigureCpuDebug">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>321</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox">
+ <property name="title">
+ <string>Toggle CPU Optimizations</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel">
+ <property name="wordWrap">
+ <bool>1</bool>
+ </property>
+ <property name="text">
+ <string>
+ &lt;div&gt;
+ &lt;b&gt;For debugging only.&lt;/b&gt;
+ &lt;br&gt;
+ If you're not sure what these do, keep all of these enabled.
+ &lt;br&gt;
+ These settings only take effect when CPU Accuracy is "Debug Mode".
+ &lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_page_tables">
+ <property name="text">
+ <string>Enable inline page tables</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
+ &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_block_linking">
+ <property name="text">
+ <string>Enable block linking</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_return_stack_buffer">
+ <property name="text">
+ <string>Enable return stack buffer</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_fast_dispatcher">
+ <property name="text">
+ <string>Enable fast dispatcher</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_context_elimination">
+ <property name="text">
+ <string>Enable context elimination</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_const_prop">
+ <property name="text">
+ <string>Enable constant propagation</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_misc_ir">
+ <property name="text">
+ <string>Enable miscellaneous optimizations</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
+ <property name="text">
+ <string>Enable misalignment check reduction</string>
+ </property>
+ <property name="toolTip">
+ <string>
+ &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
+ &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_disable_info">
+ <property name="text">
+ <string>CPU settings are available only when game is not running.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 2c77441fd..d0e71dd60 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -36,7 +36,6 @@ void ConfigureDebug::SetConfiguration() {
ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args));
ui->reporting_services->setChecked(Settings::values.reporting_services);
ui->quest_flag->setChecked(Settings::values.quest_flag);
- ui->disable_cpu_opt->setChecked(Settings::values.disable_cpu_opt);
ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn());
ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
@@ -51,7 +50,6 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.program_args = ui->homebrew_args_edit->text().toStdString();
Settings::values.reporting_services = ui->reporting_services->isChecked();
Settings::values.quest_flag = ui->quest_flag->isChecked();
- Settings::values.disable_cpu_opt = ui->disable_cpu_opt->isChecked();
Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
Debugger::ToggleConsole();
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 46f0208c6..272bdd6b8 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -228,13 +228,6 @@
</property>
</widget>
</item>
- <item>
- <widget class="QCheckBox" name="disable_cpu_opt">
- <property name="text">
- <string>Disable CPU JIT optimizations</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 5918e9972..a5afb354f 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -42,6 +42,8 @@ void ConfigureDialog::ApplyConfiguration() {
ui->filesystemTab->applyConfiguration();
ui->inputTab->ApplyConfiguration();
ui->hotkeysTab->ApplyConfiguration(registry);
+ ui->cpuTab->ApplyConfiguration();
+ ui->cpuDebugTab->ApplyConfiguration();
ui->graphicsTab->ApplyConfiguration();
ui->graphicsAdvancedTab->ApplyConfiguration();
ui->audioTab->ApplyConfiguration();
@@ -76,9 +78,10 @@ void ConfigureDialog::RetranslateUI() {
Q_DECLARE_METATYPE(QList<QWidget*>);
void ConfigureDialog::PopulateSelectionList() {
- const std::array<std::pair<QString, QList<QWidget*>>, 5> items{
+ const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
{{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
{tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
+ {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}},
{tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
{tr("Audio"), {ui->audioTab}},
{tr("Controls"), {ui->inputTab, ui->hotkeysTab}}},
@@ -107,6 +110,8 @@ void ConfigureDialog::UpdateVisibleTabs() {
{ui->profileManagerTab, tr("Profiles")},
{ui->inputTab, tr("Input")},
{ui->hotkeysTab, tr("Hotkeys")},
+ {ui->cpuTab, tr("CPU")},
+ {ui->cpuDebugTab, tr("Debug")},
{ui->graphicsTab, tr("Graphics")},
{ui->graphicsAdvancedTab, tr("Advanced")},
{ui->audioTab, tr("Audio")},
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index dce70a1e0..7773228c8 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -428,8 +428,6 @@ void Config::ReadValues() {
Settings::values.reporting_services =
sdl2_config->GetBoolean("Debugging", "reporting_services", false);
Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
- Settings::values.disable_cpu_opt =
- sdl2_config->GetBoolean("Debugging", "disable_cpu_opt", false);
Settings::values.disable_macro_jit =
sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 45c07ed5d..5bed47fd7 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -97,6 +97,39 @@ udp_pad_index=
# 0 (default): Disabled, 1: Enabled
use_multi_core=
+[Cpu]
+# Enable inline page tables optimization (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_page_tables =
+
+# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_block_linking =
+
+# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_return_stack_buffer =
+
+# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_fast_dispatcher =
+
+# Enable context elimination CPU Optimization (reduce host memory use for guest context)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_context_elimination =
+
+# Enable constant propagation CPU optimization (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_const_prop =
+
+# Enable miscellaneous CPU optimizations (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_misc_ir =
+
+# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_reduce_misalign_checks =
+
[Renderer]
# Which backend API to use.
# 0 (default): OpenGL, 1: Vulkan
@@ -283,9 +316,6 @@ dump_nso=false
# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
# false: Retail/Normal Mode (default), true: Kiosk Mode
quest_flag =
-# Determines whether or not JIT CPU optimizations are enabled
-# false: Optimizations Enabled, true: Optimizations Disabled
-disable_cpu_opt =
# Enables/Disables the macro JIT compiler
disable_macro_jit=false
diff --git a/src/yuzu_tester/default_ini.h b/src/yuzu_tester/default_ini.h
index 41bbbbf60..3eb64e9d7 100644
--- a/src/yuzu_tester/default_ini.h
+++ b/src/yuzu_tester/default_ini.h
@@ -12,6 +12,39 @@ const char* sdl2_config_file = R"(
# 0 (default): Disabled, 1: Enabled
use_multi_core=
+[Cpu]
+# Enable inline page tables optimization (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_page_tables =
+
+# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_block_linking =
+
+# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_return_stack_buffer =
+
+# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_fast_dispatcher =
+
+# Enable context elimination CPU Optimization (reduce host memory use for guest context)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_context_elimination =
+
+# Enable constant propagation CPU optimization (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_const_prop =
+
+# Enable miscellaneous CPU optimizations (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_misc_ir =
+
+# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_reduce_misalign_checks =
+
[Renderer]
# Whether to use software or hardware rendering.
# 0: Software, 1 (default): Hardware