summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFernandoS27 <fsahmkow27@gmail.com>2021-06-06 09:57:24 +0200
committerMarkus Wick <markus@selfnet.de>2021-06-11 17:27:17 +0200
commit5ba28325b262d44fcd7721aa00074955bd794015 (patch)
tree1c388684ccc0ef52b124145cf3dfe98d5d427980
parentcommon/host_memory: Optimize for huge tables. (diff)
downloadyuzu-5ba28325b262d44fcd7721aa00074955bd794015.tar
yuzu-5ba28325b262d44fcd7721aa00074955bd794015.tar.gz
yuzu-5ba28325b262d44fcd7721aa00074955bd794015.tar.bz2
yuzu-5ba28325b262d44fcd7721aa00074955bd794015.tar.lz
yuzu-5ba28325b262d44fcd7721aa00074955bd794015.tar.xz
yuzu-5ba28325b262d44fcd7721aa00074955bd794015.tar.zst
yuzu-5ba28325b262d44fcd7721aa00074955bd794015.zip
-rw-r--r--src/common/settings.cpp8
-rw-r--r--src/common/settings.h4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp5
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp8
-rw-r--r--src/core/memory.cpp14
-rw-r--r--src/yuzu/configuration/config.cpp7
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp9
-rw-r--r--src/yuzu/configuration/configure_cpu.h1
-rw-r--r--src/yuzu/configuration/configure_cpu.ui12
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp3
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui14
-rw-r--r--src/yuzu_cmd/default_ini.h4
12 files changed, 83 insertions, 6 deletions
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index bcb4e4be1..360e878d6 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -90,6 +90,13 @@ bool IsGPULevelHigh() {
values.gpu_accuracy.GetValue() == GPUAccuracy::High;
}
+bool IsFastmemEnabled() {
+ if (values.cpu_accuracy.GetValue() == CPUAccuracy::DebugMode) {
+ return values.cpuopt_fastmem;
+ }
+ return true;
+}
+
float Volume() {
if (values.audio_muted) {
return 0.0f;
@@ -115,6 +122,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
+ values.cpuopt_unsafe_fastmem_check.SetGlobal(true);
// Renderer
values.renderer_backend.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index 48085b9a9..1af8c5ac2 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -125,10 +125,12 @@ struct Values {
bool cpuopt_const_prop;
bool cpuopt_misc_ir;
bool cpuopt_reduce_misalign_checks;
+ bool cpuopt_fastmem;
Setting<bool> cpuopt_unsafe_unfuse_fma;
Setting<bool> cpuopt_unsafe_reduce_fp_error;
Setting<bool> cpuopt_unsafe_inaccurate_nan;
+ Setting<bool> cpuopt_unsafe_fastmem_check;
// Renderer
Setting<RendererBackend> renderer_backend;
@@ -249,6 +251,8 @@ void SetConfiguringGlobal(bool is_global);
bool IsGPULevelExtreme();
bool IsGPULevelHigh();
+bool IsFastmemEnabled();
+
float Volume();
std::string GetTimeZoneString();
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index fb128f735..c8f6dc765 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -144,7 +144,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
// Code cache size
config.code_cache_size = 512 * 1024 * 1024;
- config.far_code_offset = 256 * 1024 * 1024;
+ config.far_code_offset = 400 * 1024 * 1024;
// Safe optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
@@ -172,6 +172,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
if (!Settings::values.cpuopt_reduce_misalign_checks) {
config.only_detect_misalignment_via_page_table_on_page_boundary = false;
}
+ if (!Settings::values.cpuopt_fastmem) {
+ config.fastmem_pointer = nullptr;
+ }
}
// Unsafe optimizations
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index b0ac8cf8a..ba524cd05 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -185,7 +185,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
// Code cache size
config.code_cache_size = 512 * 1024 * 1024;
- config.far_code_offset = 256 * 1024 * 1024;
+ config.far_code_offset = 400 * 1024 * 1024;
// Safe optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
@@ -213,6 +213,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
if (!Settings::values.cpuopt_reduce_misalign_checks) {
config.only_detect_misalignment_via_page_table_on_page_boundary = false;
}
+ if (!Settings::values.cpuopt_fastmem) {
+ config.fastmem_pointer = nullptr;
+ }
}
// Unsafe optimizations
@@ -227,6 +230,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
}
+ if (Settings::values.cpuopt_unsafe_fastmem_check.GetValue()) {
+ config.fastmem_address_space_bits = 64;
+ }
}
return std::make_shared<Dynarmic::A64::Jit>(config);
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 79468e4dc..f285c6f63 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -47,7 +47,9 @@ struct Memory::Impl {
"Out of bounds target: {:016X}", target);
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
- system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size);
+ if (Settings::IsFastmemEnabled()) {
+ system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size);
+ }
}
void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
@@ -55,7 +57,9 @@ struct Memory::Impl {
ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
- system.DeviceMemory().buffer.Unmap(base, size);
+ if (Settings::IsFastmemEnabled()) {
+ system.DeviceMemory().buffer.Unmap(base, size);
+ }
}
bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const {
@@ -475,8 +479,10 @@ struct Memory::Impl {
return;
}
- const bool is_read_enable = Settings::IsGPULevelHigh() || !cached;
- system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
+ if (Settings::IsFastmemEnabled()) {
+ const bool is_read_enable = Settings::IsGPULevelHigh() || !cached;
+ system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
+ }
// Iterate over a contiguous CPU address space, which corresponds to the specified GPU
// address space, marking the region as un/cached. The region is marked un/cached at a
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index e9d4bef60..a59b36e13 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -756,6 +756,8 @@ void Config::ReadCpuValues() {
QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true);
ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true);
+ ReadSettingGlobal(Settings::values.cpuopt_unsafe_fastmem_check,
+ QStringLiteral("cpuopt_unsafe_fastmem_check"), true);
if (global) {
Settings::values.cpuopt_page_tables =
@@ -774,6 +776,8 @@ void Config::ReadCpuValues() {
ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
Settings::values.cpuopt_reduce_misalign_checks =
ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
+ Settings::values.cpuopt_fastmem =
+ ReadSetting(QStringLiteral("cpuopt_fastmem"), true).toBool();
}
qt_config->endGroup();
@@ -1332,6 +1336,8 @@ void Config::SaveCpuValues() {
Settings::values.cpuopt_unsafe_reduce_fp_error, true);
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
Settings::values.cpuopt_unsafe_inaccurate_nan, true);
+ WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_fastmem_check"),
+ Settings::values.cpuopt_unsafe_fastmem_check, true);
if (global) {
WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
@@ -1348,6 +1354,7 @@ void Config::SaveCpuValues() {
WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
Settings::values.cpuopt_reduce_misalign_checks, true);
+ WriteSetting(QStringLiteral("cpuopt_fastmem"), Settings::values.cpuopt_fastmem, true);
}
qt_config->endGroup();
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 525c42ff0..22219cbad 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -35,12 +35,15 @@ void ConfigureCpu::SetConfiguration() {
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
+ ui->cpuopt_unsafe_fastmem_check->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_inaccurate_nan->setChecked(
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
+ ui->cpuopt_unsafe_fastmem_check->setChecked(
+ Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
@@ -84,6 +87,9 @@ void ConfigureCpu::ApplyConfiguration() {
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);
if (Settings::IsConfiguringGlobal()) {
// Guard if during game and set to game-specific value
@@ -134,4 +140,7 @@ void ConfigureCpu::SetupPerGameUI() {
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);
}
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index 8e2eeb7a6..57ff2772a 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -41,4 +41,5 @@ private:
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
+ ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
};
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index 99b573640..31ef9e3f5 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -123,6 +123,18 @@
</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>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index c925c023c..e25c52baf 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -39,6 +39,8 @@ void ConfigureCpuDebug::SetConfiguration() {
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);
+ ui->cpuopt_fastmem->setEnabled(runtime_lock);
+ ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem);
}
void ConfigureCpuDebug::ApplyConfiguration() {
@@ -50,6 +52,7 @@ void ConfigureCpuDebug::ApplyConfiguration() {
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();
+ Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
}
void ConfigureCpuDebug::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index a90dc64fe..11ee19a12 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -139,6 +139,20 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_fastmem">
+ <property name="text">
+ <string>Enable Host MMU Emulation</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 causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
+ &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to use Software MMU Emulation.&lt;/div&gt;
+ </string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 8ce2967ac..f48d935a1 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -150,6 +150,10 @@ cpuopt_misc_ir =
# 0: Disabled, 1 (default): Enabled
cpuopt_reduce_misalign_checks =
+# Enable Host MMU Emulation (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_fastmem =
+
[Renderer]
# Which backend API to use.
# 0 (default): OpenGL, 1: Vulkan