summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------externals/dynarmic0
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp13
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp13
-rw-r--r--src/core/settings.h6
-rw-r--r--src/video_core/macro/macro_interpreter.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp23
-rw-r--r--src/yuzu/configuration/config.cpp10
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp17
-rw-r--r--src/yuzu/configuration/configure_cpu.h1
-rw-r--r--src/yuzu/configuration/configure_cpu.ui52
10 files changed, 120 insertions, 16 deletions
diff --git a/externals/dynarmic b/externals/dynarmic
Subproject 82417da7803e2cf18efc28a1cd3f3d0a4b6045a Subproject 0e1112b7df77ae55a62a51622940d5c8f9e8c84
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 443ca72eb..b5f28a86e 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -143,7 +143,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
143 config.wall_clock_cntpct = uses_wall_clock; 143 config.wall_clock_cntpct = uses_wall_clock;
144 144
145 // Safe optimizations 145 // Safe optimizations
146 if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) { 146 if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) {
147 if (!Settings::values.cpuopt_page_tables) { 147 if (!Settings::values.cpuopt_page_tables) {
148 config.page_table = nullptr; 148 config.page_table = nullptr;
149 } 149 }
@@ -170,6 +170,17 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
170 } 170 }
171 } 171 }
172 172
173 // Unsafe optimizations
174 if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) {
175 config.unsafe_optimizations = true;
176 if (Settings::values.cpuopt_unsafe_unfuse_fma) {
177 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
178 }
179 if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
180 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
181 }
182 }
183
173 return std::make_unique<Dynarmic::A32::Jit>(config); 184 return std::make_unique<Dynarmic::A32::Jit>(config);
174} 185}
175 186
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index a63a04a25..ce9968724 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -195,7 +195,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
195 config.wall_clock_cntpct = uses_wall_clock; 195 config.wall_clock_cntpct = uses_wall_clock;
196 196
197 // Safe optimizations 197 // Safe optimizations
198 if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) { 198 if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) {
199 if (!Settings::values.cpuopt_page_tables) { 199 if (!Settings::values.cpuopt_page_tables) {
200 config.page_table = nullptr; 200 config.page_table = nullptr;
201 } 201 }
@@ -222,6 +222,17 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
222 } 222 }
223 } 223 }
224 224
225 // Unsafe optimizations
226 if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) {
227 config.unsafe_optimizations = true;
228 if (Settings::values.cpuopt_unsafe_unfuse_fma) {
229 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
230 }
231 if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
232 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
233 }
234 }
235
225 return std::make_shared<Dynarmic::A64::Jit>(config); 236 return std::make_shared<Dynarmic::A64::Jit>(config);
226} 237}
227 238
diff --git a/src/core/settings.h b/src/core/settings.h
index bb145f193..3681b5e9d 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -359,7 +359,8 @@ enum class GPUAccuracy : u32 {
359 359
360enum class CPUAccuracy { 360enum class CPUAccuracy {
361 Accurate = 0, 361 Accurate = 0,
362 DebugMode = 1, 362 Unsafe = 1,
363 DebugMode = 2,
363}; 364};
364 365
365extern bool configuring_global; 366extern bool configuring_global;
@@ -419,6 +420,9 @@ struct Values {
419 bool cpuopt_misc_ir; 420 bool cpuopt_misc_ir;
420 bool cpuopt_reduce_misalign_checks; 421 bool cpuopt_reduce_misalign_checks;
421 422
423 bool cpuopt_unsafe_unfuse_fma;
424 bool cpuopt_unsafe_reduce_fp_error;
425
422 // Renderer 426 // Renderer
423 Setting<RendererBackend> renderer_backend; 427 Setting<RendererBackend> renderer_backend;
424 bool renderer_debug; 428 bool renderer_debug;
diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp
index aa5256419..bd01fd1f2 100644
--- a/src/video_core/macro/macro_interpreter.cpp
+++ b/src/video_core/macro/macro_interpreter.cpp
@@ -34,7 +34,6 @@ void MacroInterpreterImpl::Execute(const std::vector<u32>& parameters, u32 metho
34 this->parameters = std::make_unique<u32[]>(num_parameters); 34 this->parameters = std::make_unique<u32[]>(num_parameters);
35 } 35 }
36 std::memcpy(this->parameters.get(), parameters.data(), num_parameters * sizeof(u32)); 36 std::memcpy(this->parameters.get(), parameters.data(), num_parameters * sizeof(u32));
37 this->num_parameters = num_parameters;
38 37
39 // Execute the code until we hit an exit condition. 38 // Execute the code until we hit an exit condition.
40 bool keep_executing = true; 39 bool keep_executing = true;
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index 52fbab3c1..40c0877c1 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -214,20 +214,20 @@ std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTran
214 // Skip games without title id 214 // Skip games without title id
215 const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0; 215 const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0;
216 if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) { 216 if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) {
217 return {}; 217 return std::nullopt;
218 } 218 }
219 219
220 Common::FS::IOFile file(GetTransferablePath(), "rb"); 220 Common::FS::IOFile file(GetTransferablePath(), "rb");
221 if (!file.IsOpen()) { 221 if (!file.IsOpen()) {
222 LOG_INFO(Render_OpenGL, "No transferable shader cache found"); 222 LOG_INFO(Render_OpenGL, "No transferable shader cache found");
223 is_usable = true; 223 is_usable = true;
224 return {}; 224 return std::nullopt;
225 } 225 }
226 226
227 u32 version{}; 227 u32 version{};
228 if (file.ReadBytes(&version, sizeof(version)) != sizeof(version)) { 228 if (file.ReadBytes(&version, sizeof(version)) != sizeof(version)) {
229 LOG_ERROR(Render_OpenGL, "Failed to get transferable cache version, skipping it"); 229 LOG_ERROR(Render_OpenGL, "Failed to get transferable cache version, skipping it");
230 return {}; 230 return std::nullopt;
231 } 231 }
232 232
233 if (version < NativeVersion) { 233 if (version < NativeVersion) {
@@ -235,12 +235,12 @@ std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTran
235 file.Close(); 235 file.Close();
236 InvalidateTransferable(); 236 InvalidateTransferable();
237 is_usable = true; 237 is_usable = true;
238 return {}; 238 return std::nullopt;
239 } 239 }
240 if (version > NativeVersion) { 240 if (version > NativeVersion) {
241 LOG_WARNING(Render_OpenGL, "Transferable shader cache was generated with a newer version " 241 LOG_WARNING(Render_OpenGL, "Transferable shader cache was generated with a newer version "
242 "of the emulator, skipping"); 242 "of the emulator, skipping");
243 return {}; 243 return std::nullopt;
244 } 244 }
245 245
246 // Version is valid, load the shaders 246 // Version is valid, load the shaders
@@ -249,7 +249,7 @@ std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTran
249 ShaderDiskCacheEntry& entry = entries.emplace_back(); 249 ShaderDiskCacheEntry& entry = entries.emplace_back();
250 if (!entry.Load(file)) { 250 if (!entry.Load(file)) {
251 LOG_ERROR(Render_OpenGL, "Failed to load transferable raw entry, skipping"); 251 LOG_ERROR(Render_OpenGL, "Failed to load transferable raw entry, skipping");
252 return {}; 252 return std::nullopt;
253 } 253 }
254 } 254 }
255 255
@@ -290,12 +290,12 @@ std::optional<std::vector<ShaderDiskCachePrecompiled>> ShaderDiskCacheOpenGL::Lo
290 ShaderCacheVersionHash file_hash{}; 290 ShaderCacheVersionHash file_hash{};
291 if (!LoadArrayFromPrecompiled(file_hash.data(), file_hash.size())) { 291 if (!LoadArrayFromPrecompiled(file_hash.data(), file_hash.size())) {
292 precompiled_cache_virtual_file_offset = 0; 292 precompiled_cache_virtual_file_offset = 0;
293 return {}; 293 return std::nullopt;
294 } 294 }
295 if (GetShaderCacheVersionHash() != file_hash) { 295 if (GetShaderCacheVersionHash() != file_hash) {
296 LOG_INFO(Render_OpenGL, "Precompiled cache is from another version of the emulator"); 296 LOG_INFO(Render_OpenGL, "Precompiled cache is from another version of the emulator");
297 precompiled_cache_virtual_file_offset = 0; 297 precompiled_cache_virtual_file_offset = 0;
298 return {}; 298 return std::nullopt;
299 } 299 }
300 300
301 std::vector<ShaderDiskCachePrecompiled> entries; 301 std::vector<ShaderDiskCachePrecompiled> entries;
@@ -305,15 +305,16 @@ std::optional<std::vector<ShaderDiskCachePrecompiled>> ShaderDiskCacheOpenGL::Lo
305 if (!LoadObjectFromPrecompiled(entry.unique_identifier) || 305 if (!LoadObjectFromPrecompiled(entry.unique_identifier) ||
306 !LoadObjectFromPrecompiled(entry.binary_format) || 306 !LoadObjectFromPrecompiled(entry.binary_format) ||
307 !LoadObjectFromPrecompiled(binary_size)) { 307 !LoadObjectFromPrecompiled(binary_size)) {
308 return {}; 308 return std::nullopt;
309 } 309 }
310 310
311 entry.binary.resize(binary_size); 311 entry.binary.resize(binary_size);
312 if (!LoadArrayFromPrecompiled(entry.binary.data(), entry.binary.size())) { 312 if (!LoadArrayFromPrecompiled(entry.binary.data(), entry.binary.size())) {
313 return {}; 313 return std::nullopt;
314 } 314 }
315 } 315 }
316 return entries; 316
317 return std::move(entries);
317} 318}
318 319
319void ShaderDiskCacheOpenGL::InvalidateTransferable() { 320void ShaderDiskCacheOpenGL::InvalidateTransferable() {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index a372190cc..7af974d8d 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -635,6 +635,11 @@ void Config::ReadCpuValues() {
635 ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool(); 635 ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
636 Settings::values.cpuopt_reduce_misalign_checks = 636 Settings::values.cpuopt_reduce_misalign_checks =
637 ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool(); 637 ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
638
639 Settings::values.cpuopt_unsafe_unfuse_fma =
640 ReadSetting(QStringLiteral("cpuopt_unsafe_unfuse_fma"), true).toBool();
641 Settings::values.cpuopt_unsafe_reduce_fp_error =
642 ReadSetting(QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true).toBool();
638 } 643 }
639 644
640 qt_config->endGroup(); 645 qt_config->endGroup();
@@ -1132,6 +1137,11 @@ void Config::SaveCpuValues() {
1132 WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true); 1137 WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
1133 WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), 1138 WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
1134 Settings::values.cpuopt_reduce_misalign_checks, true); 1139 Settings::values.cpuopt_reduce_misalign_checks, true);
1140
1141 WriteSetting(QStringLiteral("cpuopt_unsafe_unfuse_fma"),
1142 Settings::values.cpuopt_unsafe_unfuse_fma, true);
1143 WriteSetting(QStringLiteral("cpuopt_unsafe_reduce_fp_error"),
1144 Settings::values.cpuopt_unsafe_reduce_fp_error, true);
1135 } 1145 }
1136 1146
1137 qt_config->endGroup(); 1147 qt_config->endGroup();
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 7493e5ffb..37fcd6adc 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -19,6 +19,8 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config
19 19
20 connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this, 20 connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
21 &ConfigureCpu::AccuracyUpdated); 21 &ConfigureCpu::AccuracyUpdated);
22 connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
23 &ConfigureCpu::UpdateGroup);
22} 24}
23 25
24ConfigureCpu::~ConfigureCpu() = default; 26ConfigureCpu::~ConfigureCpu() = default;
@@ -28,6 +30,12 @@ void ConfigureCpu::SetConfiguration() {
28 30
29 ui->accuracy->setEnabled(runtime_lock); 31 ui->accuracy->setEnabled(runtime_lock);
30 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy)); 32 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy));
33 UpdateGroup(static_cast<int>(Settings::values.cpu_accuracy));
34
35 ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
36 ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma);
37 ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
38 ui->cpuopt_unsafe_reduce_fp_error->setChecked(Settings::values.cpuopt_unsafe_reduce_fp_error);
31} 39}
32 40
33void ConfigureCpu::AccuracyUpdated(int index) { 41void ConfigureCpu::AccuracyUpdated(int index) {
@@ -38,14 +46,21 @@ void ConfigureCpu::AccuracyUpdated(int index) {
38 QMessageBox::Yes | QMessageBox::No); 46 QMessageBox::Yes | QMessageBox::No);
39 if (result == QMessageBox::No) { 47 if (result == QMessageBox::No) {
40 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate)); 48 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate));
41 return; 49 UpdateGroup(static_cast<int>(Settings::CPUAccuracy::Accurate));
42 } 50 }
43 } 51 }
44} 52}
45 53
54void ConfigureCpu::UpdateGroup(int index) {
55 ui->unsafe_group->setVisible(static_cast<Settings::CPUAccuracy>(index) ==
56 Settings::CPUAccuracy::Unsafe);
57}
58
46void ConfigureCpu::ApplyConfiguration() { 59void ConfigureCpu::ApplyConfiguration() {
47 Settings::values.cpu_accuracy = 60 Settings::values.cpu_accuracy =
48 static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex()); 61 static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex());
62 Settings::values.cpuopt_unsafe_unfuse_fma = ui->cpuopt_unsafe_unfuse_fma->isChecked();
63 Settings::values.cpuopt_unsafe_reduce_fp_error = ui->cpuopt_unsafe_reduce_fp_error->isChecked();
49} 64}
50 65
51void ConfigureCpu::changeEvent(QEvent* event) { 66void ConfigureCpu::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index e4741d3a4..3c5683d81 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -26,6 +26,7 @@ private:
26 void RetranslateUI(); 26 void RetranslateUI();
27 27
28 void AccuracyUpdated(int index); 28 void AccuracyUpdated(int index);
29 void UpdateGroup(int index);
29 30
30 void SetConfiguration(); 31 void SetConfiguration();
31 32
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index bf6ea79bb..ebdd2e6e9 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -40,6 +40,11 @@
40 </item> 40 </item>
41 <item> 41 <item>
42 <property name="text"> 42 <property name="text">
43 <string>Unsafe</string>
44 </property>
45 </item>
46 <item>
47 <property name="text">
43 <string>Enable Debug Mode</string> 48 <string>Enable Debug Mode</string>
44 </property> 49 </property>
45 </item> 50 </item>
@@ -63,6 +68,53 @@
63 </layout> 68 </layout>
64 </item> 69 </item>
65 <item> 70 <item>
71 <layout class="QVBoxLayout">
72 <item>
73 <widget class="QGroupBox" name="unsafe_group">
74 <property name="title">
75 <string>Unsafe CPU Optimization Settings</string>
76 </property>
77 <layout class="QVBoxLayout">
78 <item>
79 <widget class="QLabel">
80 <property name="wordWrap">
81 <bool>1</bool>
82 </property>
83 <property name="text">
84 <string>These settings reduce accuracy for speed.</string>
85 </property>
86 </widget>
87 </item>
88 <item>
89 <widget class="QCheckBox" name="cpuopt_unsafe_unfuse_fma">
90 <property name="text">
91 <string>Unfuse FMA (improve performance on CPUs without FMA)</string>
92 </property>
93 <property name="toolTip">
94 <string>
95 &lt;div&gt;This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.&lt;/div&gt;
96 </string>
97 </property>
98 </widget>
99 </item>
100 <item>
101 <widget class="QCheckBox" name="cpuopt_unsafe_reduce_fp_error">
102 <property name="text">
103 <string>Faster FRSQRTE and FRECPE</string>
104 </property>
105 <property name="toolTip">
106 <string>
107 &lt;div&gt;This option improves the speed of some approximate floating-point functions by using less accurate native approximations.&lt;/div&gt;
108 </string>
109 </property>
110 </widget>
111 </item>
112 </layout>
113 </widget>
114 </item>
115 </layout>
116 </item>
117 <item>
66 <spacer name="verticalSpacer"> 118 <spacer name="verticalSpacer">
67 <property name="orientation"> 119 <property name="orientation">
68 <enum>Qt::Vertical</enum> 120 <enum>Qt::Vertical</enum>