From 0193202964449ba7a6ae46d614a63bf5caa589a7 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 11 Jul 2020 14:26:36 +0100 Subject: [PATCH 1/4] configuration: Add settings to enable/disable specific CPU optimizations --- externals/dynarmic | 2 +- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 28 ++++- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 32 ++++-- src/core/settings.h | 11 +- src/yuzu/CMakeLists.txt | 3 + src/yuzu/configuration/config.cpp | 53 ++++++++- src/yuzu/configuration/config.h | 2 + src/yuzu/configuration/configure.ui | 11 ++ src/yuzu/configuration/configure_cpu.cpp | 64 +++++++++++ src/yuzu/configuration/configure_cpu.h | 31 ++++++ src/yuzu/configuration/configure_cpu.ui | 113 ++++++++++++++++++++ src/yuzu/configuration/configure_debug.cpp | 2 - src/yuzu/configuration/configure_debug.ui | 7 -- src/yuzu/configuration/configure_dialog.cpp | 5 +- src/yuzu_cmd/config.cpp | 2 - src/yuzu_cmd/default_ini.h | 36 ++++++- src/yuzu_tester/default_ini.h | 33 ++++++ 17 files changed, 405 insertions(+), 30 deletions(-) create mode 100644 src/yuzu/configuration/configure_cpu.cpp create mode 100644 src/yuzu/configuration/configure_cpu.h create mode 100644 src/yuzu/configuration/configure_cpu.ui diff --git a/externals/dynarmic b/externals/dynarmic index 4f967387c..82417da78 160000 --- a/externals/dynarmic +++ b/externals/dynarmic @@ -1 +1 @@ -Subproject commit 4f967387c07365b7ea35d2fa3e19b7df8872a09b +Subproject commit 82417da7803e2cf18efc28a1cd3f3d0a4b6045ae diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 0d4ab95b7..369a081cd 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -142,10 +142,30 @@ std::shared_ptr 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.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(config); diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 790981034..e208a4aa7 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -191,15 +191,35 @@ std::shared_ptr 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.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(config); } diff --git a/src/core/settings.h b/src/core/settings.h index 850ca4072..c081c083f 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -427,6 +427,16 @@ struct Values { // Core Setting use_multi_core; + // Cpu + 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 renderer_backend; bool renderer_debug; @@ -505,7 +515,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 6b25a7fa0..39efa962b 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -30,6 +30,9 @@ 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_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 1b2b1b2bb..f28e345a5 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -540,8 +540,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(); @@ -633,6 +631,31 @@ void Config::ReadPathValues() { qt_config->endGroup(); } +void Config::ReadCpuValues() { + qt_config->beginGroup(QStringLiteral("Cpu")); + + if (global) { + 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")); @@ -829,6 +852,7 @@ void Config::ReadValues() { ReadMiscellaneousValues(); } ReadCoreValues(); + ReadCpuValues(); ReadRendererValues(); ReadAudioValues(); ReadSystemValues(); @@ -929,6 +953,7 @@ void Config::SaveValues() { SaveMiscellaneousValues(); } SaveCoreValues(); + SaveCpuValues(); SaveRendererValues(); SaveAudioValues(); SaveSystemValues(); @@ -1033,7 +1058,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(); @@ -1097,6 +1121,29 @@ void Config::SavePathValues() { qt_config->endGroup(); } +void Config::SaveCpuValues() { + qt_config->beginGroup(QStringLiteral("Cpu")); + + if (global) { + 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..a23fd9435 100644 --- a/src/yuzu/configuration/configure.ui +++ b/src/yuzu/configuration/configure.ui @@ -78,6 +78,11 @@ Hotkeys + + + CPU + + Graphics @@ -158,6 +163,12 @@
configuration/configure_debug.h
1 + + ConfigureCpu + QWidget +
configuration/configure_cpu.h
+ 1 +
ConfigureGraphics QWidget diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp new file mode 100644 index 000000000..28e010b6b --- /dev/null +++ b/src/yuzu/configuration/configure_cpu.cpp @@ -0,0 +1,64 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#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(); +} + +ConfigureCpu::~ConfigureCpu() = default; + +void ConfigureCpu::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 ConfigureCpu::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 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..a4c6e5f20 --- /dev/null +++ b/src/yuzu/configuration/configure_cpu.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 +#include +#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 SetConfiguration(); + + std::unique_ptr ui; +}; diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui new file mode 100644 index 000000000..d04cfb2d5 --- /dev/null +++ b/src/yuzu/configuration/configure_cpu.ui @@ -0,0 +1,113 @@ + + + ConfigureCpu + + + + 0 + 0 + 400 + 321 + + + + Form + + + + + + + + Safe CPU Optimizations + + + + + + 1 + + + Keep these enabled. For debugging only. + + + + + + + Enable inline page tables + + + + + + + Enable block linking + + + + + + + Enable return stack buffer + + + + + + + Enable fast dispatcher + + + + + + + Enable context elimination + + + + + + + Enable constant propagation + + + + + + + Enable miscellaneous optimizations + + + + + + + Enable misalignment check reduction + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 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 @@
- - - - Disable CPU JIT optimizations - - - diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 5918e9972..a0f49c282 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -42,6 +42,7 @@ void ConfigureDialog::ApplyConfiguration() { ui->filesystemTab->applyConfiguration(); ui->inputTab->ApplyConfiguration(); ui->hotkeysTab->ApplyConfiguration(registry); + ui->cpuTab->ApplyConfiguration(); ui->graphicsTab->ApplyConfiguration(); ui->graphicsAdvancedTab->ApplyConfiguration(); ui->audioTab->ApplyConfiguration(); @@ -76,9 +77,10 @@ void ConfigureDialog::RetranslateUI() { Q_DECLARE_METATYPE(QList); void ConfigureDialog::PopulateSelectionList() { - const std::array>, 5> items{ + const std::array>, 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}}, {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}}, {tr("Audio"), {ui->audioTab}}, {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}, @@ -107,6 +109,7 @@ void ConfigureDialog::UpdateVisibleTabs() { {ui->profileManagerTab, tr("Profiles")}, {ui->inputTab, tr("Input")}, {ui->hotkeysTab, tr("Hotkeys")}, + {ui->cpuTab, tr("CPU")}, {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 23763144f..441d8e8f7 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -437,8 +437,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 From 505aa3a4c1eb2384ab5a46aecf6431db239b74e3 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 11 Jul 2020 16:25:49 +0100 Subject: [PATCH 2/4] configure_cpu: Show/Hide debugging options --- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 48 ++++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 48 ++++++++++++----------- src/core/settings.h | 7 ++++ src/yuzu/configuration/config.cpp | 6 +++ src/yuzu/configuration/configure_cpu.cpp | 22 +++++++++++ src/yuzu/configuration/configure_cpu.h | 2 + src/yuzu/configuration/configure_cpu.ui | 48 +++++++++++++++++++++++ 7 files changed, 135 insertions(+), 46 deletions(-) diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 369a081cd..443ca72eb 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -143,29 +143,31 @@ std::shared_ptr ARM_Dynarmic_32::MakeJit(Common::PageTable& config.wall_clock_cntpct = uses_wall_clock; // Safe optimizations - 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; + 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(config); diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index e208a4aa7..a63a04a25 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -195,29 +195,31 @@ std::shared_ptr ARM_Dynarmic_64::MakeJit(Common::PageTable& config.wall_clock_cntpct = uses_wall_clock; // Safe optimizations - 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; + 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(config); diff --git a/src/core/settings.h b/src/core/settings.h index c081c083f..b3451a704 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -382,6 +382,11 @@ enum class GPUAccuracy : u32 { Extreme = 2, }; +enum class CPUAccuracy { + Accurate = 0, + DebugMode = 1, +}; + extern bool configuring_global; template @@ -428,6 +433,8 @@ struct Values { Setting use_multi_core; // Cpu + CPUAccuracy cpu_accuracy; + bool cpuopt_page_tables; bool cpuopt_block_linking; bool cpuopt_return_stack_buffer; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index f28e345a5..430e78e5f 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -635,6 +635,9 @@ void Config::ReadCpuValues() { qt_config->beginGroup(QStringLiteral("Cpu")); if (global) { + Settings::values.cpu_accuracy = static_cast( + ReadSetting(QStringLiteral("cpu_accuracy"), 0).toInt()); + Settings::values.cpuopt_page_tables = ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool(); Settings::values.cpuopt_block_linking = @@ -1125,6 +1128,9 @@ void Config::SaveCpuValues() { qt_config->beginGroup(QStringLiteral("Cpu")); if (global) { + WriteSetting(QStringLiteral("cpu_accuracy"), + static_cast(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, diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp index 28e010b6b..4fc392a7e 100644 --- a/src/yuzu/configuration/configure_cpu.cpp +++ b/src/yuzu/configuration/configure_cpu.cpp @@ -15,6 +15,9 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config ui->setupUi(this); SetConfiguration(); + + connect(ui->accuracy, qOverload(&QComboBox::currentIndexChanged), this, + &ConfigureCpu::UpdateGroups); } ConfigureCpu::~ConfigureCpu() = default; @@ -22,6 +25,10 @@ ConfigureCpu::~ConfigureCpu() = default; void ConfigureCpu::SetConfiguration() { const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); + ui->accuracy->setEnabled(runtime_lock); + ui->accuracy->setCurrentIndex(static_cast(Settings::values.cpu_accuracy)); + UpdateGroups(static_cast(Settings::values.cpu_accuracy)); + ui->cpuopt_page_tables->setEnabled(runtime_lock); ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables); ui->cpuopt_block_linking->setEnabled(runtime_lock); @@ -40,7 +47,22 @@ void ConfigureCpu::SetConfiguration() { ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks); } +void ConfigureCpu::UpdateGroups(int index) { + switch (index) { + case 0: + default: + ui->group_safe->setVisible(false); + break; + case 1: + ui->group_safe->setVisible(true); + break; + } +} + void ConfigureCpu::ApplyConfiguration() { + Settings::values.cpu_accuracy = + static_cast(ui->accuracy->currentIndex()); + 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(); diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h index a4c6e5f20..cf55980b0 100644 --- a/src/yuzu/configuration/configure_cpu.h +++ b/src/yuzu/configuration/configure_cpu.h @@ -25,6 +25,8 @@ private: void changeEvent(QEvent* event) override; void RetranslateUI(); + void UpdateGroups(int index); + void SetConfiguration(); std::unique_ptr ui; diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui index d04cfb2d5..27bd4aa42 100644 --- a/src/yuzu/configuration/configure_cpu.ui +++ b/src/yuzu/configuration/configure_cpu.ui @@ -18,6 +18,54 @@ + + General + + + + + + + + Accuracy: + + + + + + + + Accurate + + + + + Debugging Mode (Debugging ONLY) + + + + + + + + + + 1 + + + We recommend setting accuracy to "Accurate". + + + + + + + + + + + + Safe CPU Optimizations From da11a27f42f25a7f24c0b7cece8e499f34880fc8 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 11 Jul 2020 16:26:06 +0100 Subject: [PATCH 3/4] configure_cpu: Add tooltips --- src/yuzu/configuration/configure_cpu.ui | 55 ++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui index 27bd4aa42..308e70356 100644 --- a/src/yuzu/configuration/configure_cpu.ui +++ b/src/yuzu/configuration/configure_cpu.ui @@ -76,7 +76,7 @@ 1 - Keep these enabled. For debugging only. + Keep all of these enabled. For debugging only. @@ -85,6 +85,13 @@ Enable inline page tables + + + <div style="white-space: nowrap">This optimization speeds up memory accesses by the guest program.</div> + <div style="white-space: nowrap">Enabling it inlines accesses to PageTable::pointers into emitted code.</div> + <div style="white-space: nowrap">Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.</div> + + @@ -92,6 +99,11 @@ Enable block linking + + + <div>This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.</div> + + @@ -99,6 +111,11 @@ Enable return stack buffer + + + <div>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.</div> + + @@ -106,6 +123,11 @@ Enable fast dispatcher + + + <div>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.</div> + + @@ -113,6 +135,11 @@ Enable context elimination + + + <div>Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.</div> + + @@ -120,6 +147,11 @@ Enable constant propagation + + + <div>Enables IR optimizations that involve constant propagation.</div> + + @@ -127,6 +159,11 @@ Enable miscellaneous optimizations + + + <div>Enables miscellaneous IR optimizations.</div> + + @@ -134,6 +171,12 @@ Enable misalignment check reduction + + + <div style="white-space: nowrap">When enabled, a misalignment is only triggered when an access crosses a page boundary.</div> + <div style="white-space: nowrap">When disabled, a misalignment is triggered on all misaligned accesses.</div> + + @@ -154,6 +197,16 @@ + + + + CPU settings are available only when game is not running. + + + true + + + From a67d00ef31aba1c45dde956b48844f91427963a1 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 12 Jul 2020 12:06:04 +0100 Subject: [PATCH 4/4] configure_cpu: Split optimization settings off into Debug tab --- src/yuzu/CMakeLists.txt | 3 + src/yuzu/configuration/configure.ui | 11 ++ src/yuzu/configuration/configure_cpu.cpp | 51 ++--- src/yuzu/configuration/configure_cpu.h | 2 +- src/yuzu/configuration/configure_cpu.ui | 124 +------------ .../configuration/configure_cpu_debug.cpp | 65 +++++++ src/yuzu/configuration/configure_cpu_debug.h | 31 ++++ src/yuzu/configuration/configure_cpu_debug.ui | 174 ++++++++++++++++++ src/yuzu/configuration/configure_dialog.cpp | 4 +- 9 files changed, 302 insertions(+), 163 deletions(-) create mode 100644 src/yuzu/configuration/configure_cpu_debug.cpp create mode 100644 src/yuzu/configuration/configure_cpu_debug.h create mode 100644 src/yuzu/configuration/configure_cpu_debug.ui diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 39efa962b..5f175b989 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -33,6 +33,9 @@ add_executable(yuzu 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/configure.ui b/src/yuzu/configuration/configure.ui index a23fd9435..5f5d8e571 100644 --- a/src/yuzu/configuration/configure.ui +++ b/src/yuzu/configuration/configure.ui @@ -83,6 +83,11 @@ CPU + + + Debug + + Graphics @@ -169,6 +174,12 @@
configuration/configure_cpu.h
1 + + ConfigureCpuDebug + QWidget +
configuration/configure_cpu_debug.h
+ 1 +
ConfigureGraphics QWidget diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp index 4fc392a7e..7493e5ffb 100644 --- a/src/yuzu/configuration/configure_cpu.cpp +++ b/src/yuzu/configuration/configure_cpu.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include "common/common_types.h" #include "common/logging/log.h" @@ -16,8 +17,8 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config SetConfiguration(); - connect(ui->accuracy, qOverload(&QComboBox::currentIndexChanged), this, - &ConfigureCpu::UpdateGroups); + connect(ui->accuracy, qOverload(&QComboBox::activated), this, + &ConfigureCpu::AccuracyUpdated); } ConfigureCpu::~ConfigureCpu() = default; @@ -27,50 +28,24 @@ void ConfigureCpu::SetConfiguration() { ui->accuracy->setEnabled(runtime_lock); ui->accuracy->setCurrentIndex(static_cast(Settings::values.cpu_accuracy)); - UpdateGroups(static_cast(Settings::values.cpu_accuracy)); - - 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 ConfigureCpu::UpdateGroups(int index) { - switch (index) { - case 0: - default: - ui->group_safe->setVisible(false); - break; - case 1: - ui->group_safe->setVisible(true); - break; +void ConfigureCpu::AccuracyUpdated(int index) { + if (static_cast(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(Settings::CPUAccuracy::Accurate)); + return; + } } } void ConfigureCpu::ApplyConfiguration() { Settings::values.cpu_accuracy = static_cast(ui->accuracy->currentIndex()); - - 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 ConfigureCpu::changeEvent(QEvent* event) { diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h index cf55980b0..e4741d3a4 100644 --- a/src/yuzu/configuration/configure_cpu.h +++ b/src/yuzu/configuration/configure_cpu.h @@ -25,7 +25,7 @@ private: void changeEvent(QEvent* event) override; void RetranslateUI(); - void UpdateGroups(int index); + void AccuracyUpdated(int index); void SetConfiguration(); diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui index 308e70356..bf6ea79bb 100644 --- a/src/yuzu/configuration/configure_cpu.ui +++ b/src/yuzu/configuration/configure_cpu.ui @@ -40,7 +40,7 @@ - Debugging Mode (Debugging ONLY) + Enable Debug Mode
@@ -62,128 +62,6 @@ - - - - - - Safe CPU Optimizations - - - - - - 1 - - - Keep all of these enabled. For debugging only. - - - - - - - Enable inline page tables - - - - <div style="white-space: nowrap">This optimization speeds up memory accesses by the guest program.</div> - <div style="white-space: nowrap">Enabling it inlines accesses to PageTable::pointers into emitted code.</div> - <div style="white-space: nowrap">Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.</div> - - - - - - - - Enable block linking - - - - <div>This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.</div> - - - - - - - - Enable return stack buffer - - - - <div>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.</div> - - - - - - - - Enable fast dispatcher - - - - <div>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.</div> - - - - - - - - Enable context elimination - - - - <div>Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.</div> - - - - - - - - Enable constant propagation - - - - <div>Enables IR optimizations that involve constant propagation.</div> - - - - - - - - Enable miscellaneous optimizations - - - - <div>Enables miscellaneous IR optimizations.</div> - - - - - - - - Enable misalignment check reduction - - - - <div style="white-space: nowrap">When enabled, a misalignment is only triggered when an access crosses a page boundary.</div> - <div style="white-space: nowrap">When disabled, a misalignment is triggered on all misaligned accesses.</div> - - - - - - - - - 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 + +#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 +#include +#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; +}; 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 @@ + + + ConfigureCpuDebug + + + + 0 + 0 + 400 + 321 + + + + Form + + + + + + + + Toggle CPU Optimizations + + + + + + 1 + + + + <div> + <b>For debugging only.</b> + <br> + If you're not sure what these do, keep all of these enabled. + <br> + These settings only take effect when CPU Accuracy is "Debug Mode". + </div> + + + + + + + + Enable inline page tables + + + + <div style="white-space: nowrap">This optimization speeds up memory accesses by the guest program.</div> + <div style="white-space: nowrap">Enabling it inlines accesses to PageTable::pointers into emitted code.</div> + <div style="white-space: nowrap">Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.</div> + + + + + + + + Enable block linking + + + + <div>This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.</div> + + + + + + + + Enable return stack buffer + + + + <div>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.</div> + + + + + + + + Enable fast dispatcher + + + + <div>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.</div> + + + + + + + + Enable context elimination + + + + <div>Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.</div> + + + + + + + + Enable constant propagation + + + + <div>Enables IR optimizations that involve constant propagation.</div> + + + + + + + + Enable miscellaneous optimizations + + + + <div>Enables miscellaneous IR optimizations.</div> + + + + + + + + Enable misalignment check reduction + + + + <div style="white-space: nowrap">When enabled, a misalignment is only triggered when an access crosses a page boundary.</div> + <div style="white-space: nowrap">When disabled, a misalignment is triggered on all misaligned accesses.</div> + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + CPU settings are available only when game is not running. + + + true + + + + + + + + diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index a0f49c282..a5afb354f 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -43,6 +43,7 @@ void ConfigureDialog::ApplyConfiguration() { ui->inputTab->ApplyConfiguration(); ui->hotkeysTab->ApplyConfiguration(registry); ui->cpuTab->ApplyConfiguration(); + ui->cpuDebugTab->ApplyConfiguration(); ui->graphicsTab->ApplyConfiguration(); ui->graphicsAdvancedTab->ApplyConfiguration(); ui->audioTab->ApplyConfiguration(); @@ -80,7 +81,7 @@ void ConfigureDialog::PopulateSelectionList() { const std::array>, 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}}, + {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}}, {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}}, {tr("Audio"), {ui->audioTab}}, {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}, @@ -110,6 +111,7 @@ void ConfigureDialog::UpdateVisibleTabs() { {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")},