aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/macro/macro.cpp
diff options
context:
space:
mode:
authorDavid <25727384+ogniK5377@users.noreply.github.com>2020-06-30 15:32:24 +1000
committerGitHub <noreply@github.com>2020-06-30 02:32:24 -0300
commitac1a57c28ad4e10094f9ea947980e5b17759fc33 (patch)
tree01a9b3f65f6a93d6bc6866ef09300020344f1496 /src/video_core/macro/macro.cpp
parenta21d49c9feec55baf38ef3e41ee208e2dc0526c7 (diff)
macro: Add support for "middle methods" on the code cache (#4112)
Macro code is just uploaded sequentially from a starting address, however that does not mean the entry point for the macro is at that address. This PR adds preliminary support for executing macros in the middle of our cached code.
Diffstat (limited to 'src/video_core/macro/macro.cpp')
-rw-r--r--src/video_core/macro/macro.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp
index ef7dad349e..a50e7b4e0b 100644
--- a/src/video_core/macro/macro.cpp
+++ b/src/video_core/macro/macro.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <optional>
#include <boost/container_hash/hash.hpp>
#include "common/assert.h"
#include "common/logging/log.h"
@@ -35,22 +36,40 @@ void MacroEngine::Execute(Engines::Maxwell3D& maxwell3d, u32 method,
}
} else {
// Macro not compiled, check if it's uploaded and if so, compile it
- auto macro_code = uploaded_macro_code.find(method);
+ std::optional<u32> mid_method = std::nullopt;
+ const auto macro_code = uploaded_macro_code.find(method);
if (macro_code == uploaded_macro_code.end()) {
- UNREACHABLE_MSG("Macro 0x{0:x} was not uploaded", method);
- return;
+ for (const auto& [method_base, code] : uploaded_macro_code) {
+ if (method >= method_base && (method - method_base) < code.size()) {
+ mid_method = method_base;
+ break;
+ }
+ }
+ if (!mid_method.has_value()) {
+ UNREACHABLE_MSG("Macro 0x{0:x} was not uploaded", method);
+ return;
+ }
}
auto& cache_info = macro_cache[method];
- cache_info.hash = boost::hash_value(macro_code->second);
- cache_info.lle_program = Compile(macro_code->second);
+
+ if (!mid_method.has_value()) {
+ cache_info.lle_program = Compile(macro_code->second);
+ cache_info.hash = boost::hash_value(macro_code->second);
+ } else {
+ const auto& macro_cached = uploaded_macro_code[mid_method.value()];
+ const auto rebased_method = method - mid_method.value();
+ auto& code = uploaded_macro_code[method];
+ code.resize(macro_cached.size() - rebased_method);
+ std::memcpy(code.data(), macro_cached.data() + rebased_method,
+ code.size() * sizeof(u32));
+ cache_info.hash = boost::hash_value(code);
+ cache_info.lle_program = Compile(code);
+ }
auto hle_program = hle_macros->GetHLEProgram(cache_info.hash);
if (hle_program.has_value()) {
cache_info.has_hle_program = true;
cache_info.hle_program = std::move(hle_program.value());
- }
-
- if (cache_info.has_hle_program) {
cache_info.hle_program->Execute(parameters, method);
} else {
cache_info.lle_program->Execute(parameters, method);