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.
This commit is contained in:
parent
fa8e35c49f
commit
7c970132b5
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <boost/container_hash/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
@ -35,22 +36,40 @@ void MacroEngine::Execute(Engines::Maxwell3D& maxwell3d, u32 method,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Macro not compiled, check if it's uploaded and if so, compile it
|
// 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()) {
|
if (macro_code == uploaded_macro_code.end()) {
|
||||||
|
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);
|
UNREACHABLE_MSG("Macro 0x{0:x} was not uploaded", method);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
auto& cache_info = macro_cache[method];
|
auto& cache_info = macro_cache[method];
|
||||||
cache_info.hash = boost::hash_value(macro_code->second);
|
|
||||||
|
if (!mid_method.has_value()) {
|
||||||
cache_info.lle_program = Compile(macro_code->second);
|
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);
|
auto hle_program = hle_macros->GetHLEProgram(cache_info.hash);
|
||||||
if (hle_program.has_value()) {
|
if (hle_program.has_value()) {
|
||||||
cache_info.has_hle_program = true;
|
cache_info.has_hle_program = true;
|
||||||
cache_info.hle_program = std::move(hle_program.value());
|
cache_info.hle_program = std::move(hle_program.value());
|
||||||
}
|
|
||||||
|
|
||||||
if (cache_info.has_hle_program) {
|
|
||||||
cache_info.hle_program->Execute(parameters, method);
|
cache_info.hle_program->Execute(parameters, method);
|
||||||
} else {
|
} else {
|
||||||
cache_info.lle_program->Execute(parameters, method);
|
cache_info.lle_program->Execute(parameters, method);
|
||||||
|
|
Loading…
Reference in New Issue