Add SPU Precompilation to Create PPU Cache

This commit is contained in:
Elad Ashkenazi 2023-08-28 15:40:18 +03:00
parent 7144e92ce2
commit 105c5759f3
8 changed files with 56 additions and 28 deletions

View File

@ -2112,7 +2112,14 @@ void ppu_thread::cpu_task()
#endif #endif
cmd_pop(); cmd_pop();
ppu_initialize(), spu_cache::initialize(); ppu_initialize();
if (Emu.IsStopped())
{
return;
}
spu_cache::initialize();
#ifdef __APPLE__ #ifdef __APPLE__
pthread_jit_write_protect_np(true); pthread_jit_write_protect_np(true);

View File

@ -661,7 +661,7 @@ void spu_cache::add(const spu_program& func)
m_file.write_gather(gather, 3); m_file.write_gather(gather, 3);
} }
void spu_cache::initialize() void spu_cache::initialize(bool build_existing_cache)
{ {
spu_runtime::g_interpreter = spu_runtime::g_gateway; spu_runtime::g_interpreter = spu_runtime::g_gateway;
@ -699,13 +699,24 @@ void spu_cache::initialize()
auto data_list = std::move(g_fxo->get<spu_section_data>().data); auto data_list = std::move(g_fxo->get<spu_section_data>().data);
g_fxo->get<spu_section_data>().had_been_used = true; g_fxo->get<spu_section_data>().had_been_used = true;
const bool spu_precompilation_enabled = func_list.empty() && g_cfg.core.spu_cache && g_cfg.core.llvm_precompilation; u32 total_precompile = 0;
for (auto& sec : data_list)
{
total_precompile += sec.funcs.size();
}
const bool spu_precompilation_enabled = (build_existing_cache ? func_list.empty() : func_list.size() < total_precompile) && g_cfg.core.spu_cache && g_cfg.core.llvm_precompilation;
if (spu_precompilation_enabled) if (spu_precompilation_enabled)
{ {
// What compiles in this case goes straight to disk // What compiles in this case goes straight to disk
g_fxo->get<spu_cache>() = std::move(cache); g_fxo->get<spu_cache>() = std::move(cache);
} }
else if (!build_existing_cache)
{
return;
}
else else
{ {
data_list.clear(); data_list.clear();
@ -752,17 +763,14 @@ void spu_cache::initialize()
thread_ctrl::wait_on(g_progr_ptotal, v); thread_ctrl::wait_on(g_progr_ptotal, v);
} }
u32 add_count = ::size32(func_list); const u32 add_count = ::size32(func_list) + total_precompile;
for (auto& sec : data_list) if (add_count)
{ {
add_count += sec.funcs.size(); g_progr_ptotal += add_count;
progr.emplace("Building SPU cache...");
} }
g_progr_ptotal += add_count;
progr.emplace("Building SPU cache...");
worker_count = rpcs3::utils::get_max_threads(); worker_count = rpcs3::utils::get_max_threads();
} }

View File

@ -34,7 +34,7 @@ public:
void add(const struct spu_program& func); void add(const struct spu_program& func);
static void initialize(); static void initialize(bool build_existing_cache = true);
}; };
struct spu_program struct spu_program

View File

@ -15,6 +15,7 @@
#include "Emu/Cell/PPUDisAsm.h" #include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/PPUAnalyser.h" #include "Emu/Cell/PPUAnalyser.h"
#include "Emu/Cell/SPUThread.h" #include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/SPURecompiler.h"
#include "Emu/RSX/RSXThread.h" #include "Emu/RSX/RSXThread.h"
#include "Emu/Cell/lv2/sys_process.h" #include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_sync.h" #include "Emu/Cell/lv2/sys_sync.h"
@ -1385,6 +1386,10 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
// Force LLVM recompiler // Force LLVM recompiler
g_cfg.core.ppu_decoder.from_default(); g_cfg.core.ppu_decoder.from_default();
// Force SPU cache and precompilation
g_cfg.core.llvm_precompilation.set(true);
g_cfg.core.spu_cache.set(true);
// Disable incompatible settings // Disable incompatible settings
fixup_ppu_settings(); fixup_ppu_settings();
@ -1490,6 +1495,13 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
ppu_precompile(dir_queue, nullptr); ppu_precompile(dir_queue, nullptr);
if (Emu.IsStopped())
{
return;
}
spu_cache::initialize(false);
// Exit "process" // Exit "process"
CallFromMainThread([this] CallFromMainThread([this]
{ {

View File

@ -1101,7 +1101,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
? tr("&Change Custom Gamepad Configuration") ? tr("&Change Custom Gamepad Configuration")
: tr("&Create Custom Gamepad Configuration")); : tr("&Create Custom Gamepad Configuration"));
QAction* configure_patches = menu.addAction(tr("&Manage Game Patches")); QAction* configure_patches = menu.addAction(tr("&Manage Game Patches"));
QAction* create_ppu_cache = menu.addAction(tr("&Create PPU Cache")); QAction* create_ppu_cache = menu.addAction(tr("&Create PPU/SPU Cache"));
menu.addSeparator(); menu.addSeparator();
@ -1440,7 +1440,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
{ {
if (m_gui_settings->GetBootConfirmation(this)) if (m_gui_settings->GetBootConfirmation(this))
{ {
CreatePPUCache(gameinfo); CreateCPUCaches(gameinfo);
} }
}); });
connect(remove_game, &QAction::triggered, this, [this, current_game, gameinfo, cache_base_dir, name] connect(remove_game, &QAction::triggered, this, [this, current_game, gameinfo, cache_base_dir, name]
@ -1612,23 +1612,24 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
menu.exec(global_pos); menu.exec(global_pos);
} }
bool game_list_frame::CreatePPUCache(const std::string& path, const std::string& serial) bool game_list_frame::CreateCPUCaches(const std::string& path, const std::string& serial)
{ {
Emu.GracefulShutdown(false); Emu.GracefulShutdown(false);
Emu.SetForceBoot(true); Emu.SetForceBoot(true);
if (const auto error = Emu.BootGame(fs::is_file(path) ? fs::get_parent_dir(path) : path, serial, true); error != game_boot_result::no_errors) if (const auto error = Emu.BootGame(fs::is_file(path) ? fs::get_parent_dir(path) : path, serial, true); error != game_boot_result::no_errors)
{ {
game_list_log.error("Could not create PPU Cache for %s, error: %s", path, error); game_list_log.error("Could not create PPU and SPU caches for %s, error: %s", path, error);
return false; return false;
} }
game_list_log.warning("Creating PPU Cache for %s", path);
game_list_log.warning("Creating PPU/SPU Caches for %s", path);
return true; return true;
} }
bool game_list_frame::CreatePPUCache(const game_info& game) bool game_list_frame::CreateCPUCaches(const game_info& game)
{ {
return game && CreatePPUCache(game->info.path, game->info.serial); return game && CreateCPUCaches(game->info.path, game->info.serial);
} }
bool game_list_frame::RemoveCustomConfiguration(const std::string& title_id, const game_info& game, bool is_interactive) bool game_list_frame::RemoveCustomConfiguration(const std::string& title_id, const game_info& game, bool is_interactive)
@ -1907,7 +1908,7 @@ void game_list_frame::RemoveHDD1Cache(const std::string& base_dir, const std::st
game_list_log.fatal("Only %d/%d HDD1 cache directories could be removed in %s (%s)", dirs_removed, dirs_total, base_dir, title_id); game_list_log.fatal("Only %d/%d HDD1 cache directories could be removed in %s (%s)", dirs_removed, dirs_total, base_dir, title_id);
} }
void game_list_frame::BatchCreatePPUCaches() void game_list_frame::BatchCreateCPUCaches()
{ {
const std::string vsh_path = g_cfg_vfs.get_dev_flash() + "vsh/module/"; const std::string vsh_path = g_cfg_vfs.get_dev_flash() + "vsh/module/";
const bool vsh_exists = fs::is_file(vsh_path + "vsh.self"); const bool vsh_exists = fs::is_file(vsh_path + "vsh.self");
@ -1952,7 +1953,7 @@ void game_list_frame::BatchCreatePPUCaches()
pdlg->setLabelText(tr("%0\nProgress: %1/%2. Compiling caches for VSH...", "Second line after main label").arg(main_label).arg(created).arg(total)); pdlg->setLabelText(tr("%0\nProgress: %1/%2. Compiling caches for VSH...", "Second line after main label").arg(main_label).arg(created).arg(total));
QApplication::processEvents(); QApplication::processEvents();
if (CreatePPUCache(vsh_path) && wait_until_compiled()) if (CreateCPUCaches(vsh_path) && wait_until_compiled())
{ {
pdlg->SetValue(++created); pdlg->SetValue(++created);
} }
@ -1968,7 +1969,7 @@ void game_list_frame::BatchCreatePPUCaches()
pdlg->setLabelText(tr("%0\nProgress: %1/%2. Compiling caches for %3...", "Second line after main label").arg(main_label).arg(created).arg(total).arg(qstr(game->info.serial))); pdlg->setLabelText(tr("%0\nProgress: %1/%2. Compiling caches for %3...", "Second line after main label").arg(main_label).arg(created).arg(total).arg(qstr(game->info.serial)));
QApplication::processEvents(); QApplication::processEvents();
if (CreatePPUCache(game) && wait_until_compiled()) if (CreateCPUCaches(game) && wait_until_compiled())
{ {
pdlg->SetValue(++created); pdlg->SetValue(++created);
} }

View File

@ -63,7 +63,7 @@ public:
bool IsEntryVisible(const game_info& game, bool search_fallback = false) const; bool IsEntryVisible(const game_info& game, bool search_fallback = false) const;
public Q_SLOTS: public Q_SLOTS:
void BatchCreatePPUCaches(); void BatchCreateCPUCaches();
void BatchRemovePPUCaches(); void BatchRemovePPUCaches();
void BatchRemoveSPUCaches(); void BatchRemoveSPUCaches();
void BatchRemoveCustomConfigurations(); void BatchRemoveCustomConfigurations();
@ -108,8 +108,8 @@ private:
bool RemovePPUCache(const std::string& base_dir, bool is_interactive = false); bool RemovePPUCache(const std::string& base_dir, bool is_interactive = false);
bool RemoveSPUCache(const std::string& base_dir, bool is_interactive = false); bool RemoveSPUCache(const std::string& base_dir, bool is_interactive = false);
void RemoveHDD1Cache(const std::string& base_dir, const std::string& title_id, bool is_interactive = false); void RemoveHDD1Cache(const std::string& base_dir, const std::string& title_id, bool is_interactive = false);
static bool CreatePPUCache(const std::string& path, const std::string& serial = {}); static bool CreateCPUCaches(const std::string& path, const std::string& serial = {});
static bool CreatePPUCache(const game_info& game); static bool CreateCPUCaches(const game_info& game);
static std::string GetCacheDirBySerial(const std::string& serial); static std::string GetCacheDirBySerial(const std::string& serial);
static std::string GetDataDirBySerial(const std::string& serial); static std::string GetDataDirBySerial(const std::string& serial);

View File

@ -2506,7 +2506,7 @@ void main_window::CreateConnects()
}); });
connect(ui->exitAct, &QAction::triggered, this, &QWidget::close); connect(ui->exitAct, &QAction::triggered, this, &QWidget::close);
connect(ui->batchCreatePPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchCreatePPUCaches); connect(ui->batchCreateCPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchCreateCPUCaches);
connect(ui->batchRemovePPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemovePPUCaches); connect(ui->batchRemovePPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemovePPUCaches);
connect(ui->batchRemoveSPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemoveSPUCaches); connect(ui->batchRemoveSPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemoveSPUCaches);
connect(ui->batchRemoveShaderCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemoveShaderCaches); connect(ui->batchRemoveShaderCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemoveShaderCaches);

View File

@ -182,7 +182,7 @@
<property name="title"> <property name="title">
<string>All Titles</string> <string>All Titles</string>
</property> </property>
<addaction name="batchCreatePPUCachesAct"/> <addaction name="batchCreateCPUCachesAct"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="batchRemoveCustomConfigurationsAct"/> <addaction name="batchRemoveCustomConfigurationsAct"/>
<addaction name="batchRemoveCustomPadConfigurationsAct"/> <addaction name="batchRemoveCustomPadConfigurationsAct"/>
@ -1094,9 +1094,9 @@
<string>Show Title Bars</string> <string>Show Title Bars</string>
</property> </property>
</action> </action>
<action name="batchCreatePPUCachesAct"> <action name="batchCreateCPUCachesAct">
<property name="text"> <property name="text">
<string>Create PPU Caches</string> <string>Create PPU/SPU Caches</string>
</property> </property>
</action> </action>
<action name="batchRemoveCustomConfigurationsAct"> <action name="batchRemoveCustomConfigurationsAct">