summaryrefslogtreecommitdiff
path: root/src/video_core/macro/macro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/macro/macro.cpp')
-rw-r--r--src/video_core/macro/macro.cpp27
1 files changed, 27 insertions, 0 deletions
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
16namespace Tegra { 20namespace Tegra {
17 21
22static 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
18MacroEngine::MacroEngine(Engines::Maxwell3D& maxwell3d) 39MacroEngine::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)) {