mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
SPU LLVM: Another fix for Game Collection's precompilation
This commit is contained in:
parent
26b3970485
commit
a9810ccb72
@ -270,6 +270,30 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
const T& operator[](usz index) const noexcept
|
||||
{
|
||||
lf_queue_iterator<T> result = begin();
|
||||
|
||||
while (--index != umax)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
T& operator[](usz index) noexcept
|
||||
{
|
||||
lf_queue_iterator<T> result = begin();
|
||||
|
||||
while (--index != umax)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
lf_queue_slice& pop_front()
|
||||
{
|
||||
delete std::exchange(m_head, std::exchange(m_head->m_link, nullptr));
|
||||
@ -315,6 +339,23 @@ class lf_queue final
|
||||
public:
|
||||
constexpr lf_queue() = default;
|
||||
|
||||
lf_queue(lf_queue&& other) noexcept
|
||||
{
|
||||
m_head.release(other.m_head.exchange(0));
|
||||
}
|
||||
|
||||
lf_queue& operator=(lf_queue&& other) noexcept
|
||||
{
|
||||
if (this == std::addressof(other))
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
delete load(m_head);
|
||||
m_head.release(other.m_head.exchange(0));
|
||||
return *this;
|
||||
}
|
||||
|
||||
~lf_queue()
|
||||
{
|
||||
delete load(m_head);
|
||||
|
@ -3907,6 +3907,8 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
|
||||
main_ppu_module& _main = g_fxo->get<main_ppu_module>();
|
||||
_main = {};
|
||||
|
||||
auto current_cache = std::move(g_fxo->get<spu_cache>());
|
||||
|
||||
if (!ppu_load_exec(obj, true, path))
|
||||
{
|
||||
// Abort
|
||||
@ -3916,11 +3918,13 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
|
||||
|
||||
if (std::memcmp(main_module.sha1, _main.sha1, sizeof(_main.sha1)) == 0)
|
||||
{
|
||||
g_fxo->get<spu_cache>() = std::move(current_cache);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_main.analyse(0, _main.elf_entry, _main.seg0_code_end, _main.applied_pathes, [](){ return Emu.IsStopped(); }))
|
||||
{
|
||||
g_fxo->get<spu_cache>() = std::move(current_cache);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3929,8 +3933,10 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
|
||||
_main.name = ' '; // Make ppu_finalize work
|
||||
Emu.ConfigurePPUCache(!Emu.IsPathInsideDir(_main.path, g_cfg_vfs.get_dev_flash()));
|
||||
ppu_initialize(_main);
|
||||
spu_cache::initialize(false);
|
||||
ppu_finalize(_main);
|
||||
_main = {};
|
||||
g_fxo->get<spu_cache>() = std::move(current_cache);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3945,6 +3951,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
|
||||
}
|
||||
|
||||
g_fxo->get<main_ppu_module>() = std::move(main_module);
|
||||
g_fxo->get<spu_cache>().collect_funcs_to_precompile = true;
|
||||
Emu.ConfigurePPUCache();
|
||||
});
|
||||
|
||||
|
@ -516,20 +516,6 @@ spu_cache::~spu_cache()
|
||||
{
|
||||
}
|
||||
|
||||
struct spu_section_data
|
||||
{
|
||||
struct data_t
|
||||
{
|
||||
u32 vaddr;
|
||||
std::basic_string<u32> inst_data;
|
||||
std::vector<u32> funcs;
|
||||
};
|
||||
|
||||
shared_mutex mtx;
|
||||
atomic_t<bool> had_been_used = false;
|
||||
std::vector<data_t> data;
|
||||
};
|
||||
|
||||
extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 size)
|
||||
{
|
||||
if (vaddr % 4)
|
||||
@ -549,9 +535,9 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
|
||||
return;
|
||||
}
|
||||
|
||||
g_fxo->need<spu_section_data>();
|
||||
g_fxo->need<spu_cache>();
|
||||
|
||||
if (g_fxo->get<spu_section_data>().had_been_used)
|
||||
if (!g_fxo->get<spu_cache>().collect_funcs_to_precompile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -559,7 +545,7 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
|
||||
std::basic_string<u32> data(size / 4, 0);
|
||||
std::memcpy(data.data(), ls_data_vaddr, size);
|
||||
|
||||
spu_section_data::data_t obj{vaddr, std::move(data)};
|
||||
spu_cache::precompile_data_t obj{vaddr, std::move(data)};
|
||||
|
||||
obj.funcs = spu_thread::discover_functions(vaddr, { reinterpret_cast<const u8*>(ls_data_vaddr), size }, vaddr != 0, umax);
|
||||
|
||||
@ -576,19 +562,7 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
|
||||
|
||||
spu_log.notice("Found %u SPU functions", obj.funcs.size());
|
||||
|
||||
std::lock_guard lock(g_fxo->get<spu_section_data>().mtx);
|
||||
|
||||
for (const auto& data : g_fxo->get<spu_section_data>().data)
|
||||
{
|
||||
// TODO: More robust duplicates filtering
|
||||
if (data.vaddr == vaddr && data.inst_data.starts_with(obj.inst_data))
|
||||
{
|
||||
spu_log.notice("Avoided duplicate SPU segment");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_fxo->get<spu_section_data>().data.emplace_back(std::move(obj));
|
||||
g_fxo->get<spu_cache>().precompile_funcs.push(std::move(obj));
|
||||
}
|
||||
|
||||
std::deque<spu_program> spu_cache::get()
|
||||
@ -693,8 +667,8 @@ void spu_cache::initialize(bool build_existing_cache)
|
||||
atomic_t<usz> fnext{};
|
||||
atomic_t<u8> fail_flag{0};
|
||||
|
||||
auto data_list = std::move(g_fxo->get<spu_section_data>().data);
|
||||
g_fxo->get<spu_section_data>().had_been_used = true;
|
||||
auto data_list = g_fxo->get<spu_cache>().precompile_funcs.pop_all();
|
||||
g_fxo->get<spu_cache>().collect_funcs_to_precompile = false;
|
||||
|
||||
u32 total_precompile = 0;
|
||||
|
||||
@ -717,7 +691,7 @@ void spu_cache::initialize(bool build_existing_cache)
|
||||
else
|
||||
{
|
||||
total_precompile = 0;
|
||||
data_list.clear();
|
||||
data_list = {};
|
||||
}
|
||||
|
||||
atomic_t<usz> data_indexer = 0;
|
||||
|
@ -35,6 +35,17 @@ public:
|
||||
void add(const struct spu_program& func);
|
||||
|
||||
static void initialize(bool build_existing_cache = true);
|
||||
|
||||
struct precompile_data_t
|
||||
{
|
||||
u32 vaddr;
|
||||
std::basic_string<u32> inst_data;
|
||||
std::vector<u32> funcs;
|
||||
};
|
||||
|
||||
bool collect_funcs_to_precompile = true;
|
||||
|
||||
lf_queue<precompile_data_t> precompile_funcs;
|
||||
};
|
||||
|
||||
struct spu_program
|
||||
|
Loading…
Reference in New Issue
Block a user