diff options
| -rw-r--r-- | src/common/settings.h | 1 | ||||
| -rw-r--r-- | src/video_core/macro/macro.cpp | 27 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_debug.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_debug.ui | 13 |
4 files changed, 44 insertions, 0 deletions
diff --git a/src/common/settings.h b/src/common/settings.h index 5b34169a8..e61d9cd7f 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -606,6 +606,7 @@ struct Values { | |||
| 606 | BasicSetting<bool> dump_exefs{false, "dump_exefs"}; | 606 | BasicSetting<bool> dump_exefs{false, "dump_exefs"}; |
| 607 | BasicSetting<bool> dump_nso{false, "dump_nso"}; | 607 | BasicSetting<bool> dump_nso{false, "dump_nso"}; |
| 608 | BasicSetting<bool> dump_shaders{false, "dump_shaders"}; | 608 | BasicSetting<bool> dump_shaders{false, "dump_shaders"}; |
| 609 | BasicSetting<bool> dump_macros{false, "dump_macros"}; | ||
| 609 | BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"}; | 610 | BasicSetting<bool> enable_fs_access_log{false, "enable_fs_access_log"}; |
| 610 | BasicSetting<bool> reporting_services{false, "reporting_services"}; | 611 | BasicSetting<bool> reporting_services{false, "reporting_services"}; |
| 611 | BasicSetting<bool> quest_flag{false, "quest_flag"}; | 612 | BasicSetting<bool> quest_flag{false, "quest_flag"}; |
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index a033d03be..86393c49c 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp | |||
| @@ -2,11 +2,15 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <cstring> | 4 | #include <cstring> |
| 5 | #include <fstream> | ||
| 5 | #include <optional> | 6 | #include <optional> |
| 7 | #include <span> | ||
| 6 | 8 | ||
| 7 | #include <boost/container_hash/hash.hpp> | 9 | #include <boost/container_hash/hash.hpp> |
| 8 | 10 | ||
| 9 | #include "common/assert.h" | 11 | #include "common/assert.h" |
| 12 | #include "common/fs/fs.h" | ||
| 13 | #include "common/fs/path_util.h" | ||
| 10 | #include "common/settings.h" | 14 | #include "common/settings.h" |
| 11 | #include "video_core/macro/macro.h" | 15 | #include "video_core/macro/macro.h" |
| 12 | #include "video_core/macro/macro_hle.h" | 16 | #include "video_core/macro/macro_hle.h" |
| @@ -15,6 +19,23 @@ | |||
| 15 | 19 | ||
| 16 | namespace Tegra { | 20 | namespace Tegra { |
| 17 | 21 | ||
| 22 | static void Dump(u64 hash, std::span<const u32> code) { | ||
| 23 | const auto base_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)}; | ||
| 24 | const auto macro_dir{base_dir / "macros"}; | ||
| 25 | if (!Common::FS::CreateDir(base_dir) || !Common::FS::CreateDir(macro_dir)) { | ||
| 26 | LOG_ERROR(Common_Filesystem, "Failed to create macro dump directories"); | ||
| 27 | return; | ||
| 28 | } | ||
| 29 | const auto name{macro_dir / fmt::format("{:016x}.macro", hash)}; | ||
| 30 | std::fstream macro_file(name, std::ios::out | std::ios::binary); | ||
| 31 | if (!macro_file) { | ||
| 32 | LOG_ERROR(Common_Filesystem, "Unable to open or create file at {}", | ||
| 33 | Common::FS::PathToUTF8String(name)); | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | macro_file.write(reinterpret_cast<const char*>(code.data()), code.size_bytes()); | ||
| 37 | } | ||
| 38 | |||
| 18 | MacroEngine::MacroEngine(Engines::Maxwell3D& maxwell3d) | 39 | MacroEngine::MacroEngine(Engines::Maxwell3D& maxwell3d) |
| 19 | : hle_macros{std::make_unique<Tegra::HLEMacro>(maxwell3d)} {} | 40 | : hle_macros{std::make_unique<Tegra::HLEMacro>(maxwell3d)} {} |
| 20 | 41 | ||
| @@ -54,6 +75,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 54 | if (!mid_method.has_value()) { | 75 | if (!mid_method.has_value()) { |
| 55 | cache_info.lle_program = Compile(macro_code->second); | 76 | cache_info.lle_program = Compile(macro_code->second); |
| 56 | cache_info.hash = boost::hash_value(macro_code->second); | 77 | cache_info.hash = boost::hash_value(macro_code->second); |
| 78 | if (Settings::values.dump_macros) { | ||
| 79 | Dump(cache_info.hash, macro_code->second); | ||
| 80 | } | ||
| 57 | } else { | 81 | } else { |
| 58 | const auto& macro_cached = uploaded_macro_code[mid_method.value()]; | 82 | const auto& macro_cached = uploaded_macro_code[mid_method.value()]; |
| 59 | const auto rebased_method = method - mid_method.value(); | 83 | const auto rebased_method = method - mid_method.value(); |
| @@ -63,6 +87,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 63 | code.size() * sizeof(u32)); | 87 | code.size() * sizeof(u32)); |
| 64 | cache_info.hash = boost::hash_value(code); | 88 | cache_info.hash = boost::hash_value(code); |
| 65 | cache_info.lle_program = Compile(code); | 89 | cache_info.lle_program = Compile(code); |
| 90 | if (Settings::values.dump_macros) { | ||
| 91 | Dump(cache_info.hash, code); | ||
| 92 | } | ||
| 66 | } | 93 | } |
| 67 | 94 | ||
| 68 | if (auto hle_program = hle_macros->GetHLEProgram(cache_info.hash)) { | 95 | if (auto hle_program = hle_macros->GetHLEProgram(cache_info.hash)) { |
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index bd50f7a68..d6e8b5ead 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp | |||
| @@ -53,6 +53,8 @@ void ConfigureDebug::SetConfiguration() { | |||
| 53 | ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue()); | 53 | ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue()); |
| 54 | ui->dump_shaders->setEnabled(runtime_lock); | 54 | ui->dump_shaders->setEnabled(runtime_lock); |
| 55 | ui->dump_shaders->setChecked(Settings::values.dump_shaders.GetValue()); | 55 | ui->dump_shaders->setChecked(Settings::values.dump_shaders.GetValue()); |
| 56 | ui->dump_macros->setEnabled(runtime_lock); | ||
| 57 | ui->dump_macros->setChecked(Settings::values.dump_macros.GetValue()); | ||
| 56 | ui->disable_macro_jit->setEnabled(runtime_lock); | 58 | ui->disable_macro_jit->setEnabled(runtime_lock); |
| 57 | ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue()); | 59 | ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue()); |
| 58 | ui->disable_loop_safety_checks->setEnabled(runtime_lock); | 60 | ui->disable_loop_safety_checks->setEnabled(runtime_lock); |
| @@ -83,6 +85,7 @@ void ConfigureDebug::ApplyConfiguration() { | |||
| 83 | Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked(); | 85 | Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked(); |
| 84 | Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked(); | 86 | Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked(); |
| 85 | Settings::values.dump_shaders = ui->dump_shaders->isChecked(); | 87 | Settings::values.dump_shaders = ui->dump_shaders->isChecked(); |
| 88 | Settings::values.dump_macros = ui->dump_macros->isChecked(); | ||
| 86 | Settings::values.disable_shader_loop_safety_checks = | 89 | Settings::values.disable_shader_loop_safety_checks = |
| 87 | ui->disable_loop_safety_checks->isChecked(); | 90 | ui->disable_loop_safety_checks->isChecked(); |
| 88 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); | 91 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); |
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index c1d90d588..863a3fd57 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui | |||
| @@ -118,6 +118,19 @@ | |||
| 118 | </property> | 118 | </property> |
| 119 | </widget> | 119 | </widget> |
| 120 | </item> | 120 | </item> |
| 121 | <item row="0" column="2"> | ||
| 122 | <widget class="QCheckBox" name="dump_macros"> | ||
| 123 | <property name="enabled"> | ||
| 124 | <bool>true</bool> | ||
| 125 | </property> | ||
| 126 | <property name="toolTip"> | ||
| 127 | <string>When checked, it will dump all the macro programs of the GPU</string> | ||
| 128 | </property> | ||
| 129 | <property name="text"> | ||
| 130 | <string>Dump Maxwell Macros</string> | ||
| 131 | </property> | ||
| 132 | </widget> | ||
| 133 | </item> | ||
| 121 | <item row="0" column="1"> | 134 | <item row="0" column="1"> |
| 122 | <widget class="QCheckBox" name="disable_macro_jit"> | 135 | <widget class="QCheckBox" name="disable_macro_jit"> |
| 123 | <property name="enabled"> | 136 | <property name="enabled"> |