Compare commits

...

4 Commits

Author SHA1 Message Date
David Marcec
5e6902e8d5 Fix nullptr deref for rebased method 2020-06-28 17:14:23 +10:00
David Marcec
9641d7d7df Rebase 2020-06-24 23:46:28 +10:00
David Marcec
746adc8885 Change pair to optional 2020-06-24 23:19:10 +10:00
David Marcec
61c89aed2e macro: Add support "middle methods" on the code cache
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.
2020-06-24 23:17:42 +10:00

View File

@@ -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);