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
cmd_pop();
ppu_initialize(), spu_cache::initialize();
ppu_initialize();
if (Emu.IsStopped())
{
return;
}
spu_cache::initialize();
#ifdef __APPLE__
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);
}
void spu_cache::initialize()
void spu_cache::initialize(bool build_existing_cache)
{
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);
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)
{
// What compiles in this case goes straight to disk
g_fxo->get<spu_cache>() = std::move(cache);
}
else if (!build_existing_cache)
{
return;
}
else
{
data_list.clear();
@ -752,17 +763,14 @@ void spu_cache::initialize()
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();
}

View File

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

View File

@ -15,6 +15,7 @@
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/PPUAnalyser.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/SPURecompiler.h"
#include "Emu/RSX/RSXThread.h"
#include "Emu/Cell/lv2/sys_process.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
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
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);
if (Emu.IsStopped())
{
return;
}
spu_cache::initialize(false);
// Exit "process"
CallFromMainThread([this]
{

View File

@ -1101,7 +1101,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
? tr("&Change Custom Gamepad Configuration")
: tr("&Create Custom Gamepad Configuration"));
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();
@ -1440,7 +1440,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
{
if (m_gui_settings->GetBootConfirmation(this))
{
CreatePPUCache(gameinfo);
CreateCPUCaches(gameinfo);
}
});
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);
}
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.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)
{
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;
}
game_list_log.warning("Creating PPU Cache for %s", path);
game_list_log.warning("Creating PPU/SPU Caches for %s", path);
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)
@ -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);
}
void game_list_frame::BatchCreatePPUCaches()
void game_list_frame::BatchCreateCPUCaches()
{
const std::string vsh_path = g_cfg_vfs.get_dev_flash() + "vsh/module/";
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));
QApplication::processEvents();
if (CreatePPUCache(vsh_path) && wait_until_compiled())
if (CreateCPUCaches(vsh_path) && wait_until_compiled())
{
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)));
QApplication::processEvents();
if (CreatePPUCache(game) && wait_until_compiled())
if (CreateCPUCaches(game) && wait_until_compiled())
{
pdlg->SetValue(++created);
}

View File

@ -63,7 +63,7 @@ public:
bool IsEntryVisible(const game_info& game, bool search_fallback = false) const;
public Q_SLOTS:
void BatchCreatePPUCaches();
void BatchCreateCPUCaches();
void BatchRemovePPUCaches();
void BatchRemoveSPUCaches();
void BatchRemoveCustomConfigurations();
@ -108,8 +108,8 @@ private:
bool RemovePPUCache(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);
static bool CreatePPUCache(const std::string& path, const std::string& serial = {});
static bool CreatePPUCache(const game_info& game);
static bool CreateCPUCaches(const std::string& path, const std::string& serial = {});
static bool CreateCPUCaches(const game_info& game);
static std::string GetCacheDirBySerial(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->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->batchRemoveSPUCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemoveSPUCaches);
connect(ui->batchRemoveShaderCachesAct, &QAction::triggered, m_game_list_frame, &game_list_frame::BatchRemoveShaderCaches);

View File

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