Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOTFIX] Do not wait for progress dialog cleanup for SPU Precompilation #14607

Merged
merged 5 commits into from
Sep 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 13 additions & 2 deletions rpcs3/Crypto/unself.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ static bool CheckDebugSelf(fs::file& s)
return false;
}

fs::file decrypt_self(fs::file elf_or_self, u8* klic_key, SelfAdditionalInfo* out_info)
fs::file decrypt_self(fs::file elf_or_self, u8* klic_key, SelfAdditionalInfo* out_info, bool require_encrypted)
{
if (out_info)
{
Expand All @@ -1418,8 +1418,14 @@ fs::file decrypt_self(fs::file elf_or_self, u8* klic_key, SelfAdditionalInfo* ou
elf_or_self.seek(0);

// Check SELF header first. Check for a debug SELF.
if (elf_or_self.size() >= 4 && elf_or_self.read<u32>() == "SCE\0"_u32 && !CheckDebugSelf(elf_or_self))
if (elf_or_self.size() >= 4 && elf_or_self.read<u32>() == "SCE\0"_u32)
{
if (CheckDebugSelf(elf_or_self))
{
// TODO: Decrypt
return elf_or_self;
}

// Check the ELF file class (32 or 64 bit).
const bool isElf32 = IsSelfElf32(elf_or_self);

Expand Down Expand Up @@ -1451,6 +1457,11 @@ fs::file decrypt_self(fs::file elf_or_self, u8* klic_key, SelfAdditionalInfo* ou
return self_dec.MakeElf(isElf32);
}

if (require_encrypted)
{
return {};
}

return elf_or_self;
}

Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Crypto/unself.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ class SELFDecrypter
}
};

fs::file decrypt_self(fs::file elf_or_self, u8* klic_key = nullptr, SelfAdditionalInfo* additional_info = nullptr);
fs::file decrypt_self(fs::file elf_or_self, u8* klic_key = nullptr, SelfAdditionalInfo* additional_info = nullptr, bool require_encrypted = false);
bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key = nullptr, NPD_HEADER* npd_out = nullptr);
bool get_npdrm_self_header(const fs::file& self, NPD_HEADER& npd);

Expand Down
9 changes: 3 additions & 6 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3749,7 +3749,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
// Set low priority
thread_ctrl::scoped_priority low_prio(-1);

for (usz func_i = fnext++; func_i < file_queue.size(); func_i = fnext++, g_progr_fdone++)
for (usz func_i = fnext++, inc_fdone = 1; func_i < file_queue.size(); func_i = fnext++, g_progr_fdone += std::exchange(inc_fdone, 1))
{
if (Emu.IsStopped())
{
Expand Down Expand Up @@ -3843,7 +3843,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_

ppu_log.notice("Failed to precompile '%s' (prx: %s, ovl: %s): Attempting tratment as executable file", path, prx_err, ovl_err);
possible_exec_file_paths.push(path);
continue;
inc_fdone = 0;
}
});

Expand All @@ -3869,8 +3869,6 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_

for (; slice; slice.pop_front(), g_progr_fdone++)
{
g_progr_ftotal++;

if (Emu.IsStopped())
{
continue;
Expand All @@ -3890,7 +3888,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
}

// Some files may fail to decrypt due to the lack of klic
src = decrypt_self(std::move(src));
src = decrypt_self(std::move(src), nullptr, nullptr, true);

if (!src)
{
Expand Down Expand Up @@ -3947,7 +3945,6 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
}

ppu_log.notice("Failed to precompile '%s' as executable (%s)", path, exec_err);
continue;
}

g_fxo->get<main_ppu_module>() = std::move(main_module);
Expand Down
11 changes: 6 additions & 5 deletions rpcs3/Emu/Cell/SPURecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,9 @@ void spu_cache::initialize(bool build_existing_cache)
// Initialize progress dialog (wait for previous progress done)
while (u32 v = g_progr_ptotal)
{
if (Emu.IsStopped())
if (Emu.IsStopped() || !build_existing_cache)
{
// Workaround: disable progress dialog updates in the case of sole SPU precompilation
break;
}

Expand All @@ -776,7 +777,7 @@ void spu_cache::initialize(bool build_existing_cache)

if (add_count)
{
g_progr_ptotal += add_count;
g_progr_ptotal += build_existing_cache ? add_count : 0;
progr.emplace("Building SPU cache...");
}

Expand Down Expand Up @@ -812,7 +813,7 @@ void spu_cache::initialize(bool build_existing_cache)
std::vector<be_t<u32>> ls(0x10000);

// Build functions
for (usz func_i = fnext++; func_i < func_list.size(); func_i = fnext++, g_progr_pdone++)
for (usz func_i = fnext++; func_i < func_list.size(); func_i = fnext++, g_progr_pdone += build_existing_cache ? 1 : 0)
{
const spu_program& func = std::as_const(func_list)[func_i];

Expand Down Expand Up @@ -875,7 +876,7 @@ void spu_cache::initialize(bool build_existing_cache)

u32 last_sec_idx = umax;

for (usz func_i = data_indexer++;; func_i = data_indexer++, g_progr_pdone++)
for (usz func_i = data_indexer++;; func_i = data_indexer++, g_progr_pdone += build_existing_cache ? 1 : 0)
{
u32 passed_count = 0;
u32 func_addr = 0;
Expand Down Expand Up @@ -2270,7 +2271,7 @@ std::vector<u32> spu_thread::discover_functions(u32 base_addr, std::span<const u
// Search for AI R1, +x or OR R3/4, Rx, 0
// Reasoning: AI R1, +x means stack pointer restoration, branch after that is likely a tail call
// R3 and R4 are common function arguments because they are the first two
for (u32 back = addr - 4, it = 5; it && back >= base_addr; back -= 4)
for (u32 back = addr - 4, it = 10; it && back >= base_addr && back < std::min<u32>(base_addr + ls.size(), 0x3FFF0); it--, back -= 4)
{
const spu_opcode_t test_op{read_from_ptr<be_t<u32>>(ls, back - base_addr)};
const auto type = g_spu_itype.decode(test_op.opcode);
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/sys_overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static error_code overlay_load_module(vm::ptr<u32> ovlmid, const std::string& vp

u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();

ppu_exec_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic));
ppu_exec_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic), nullptr, true);

if (obj != elf_error::ok)
{
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_prx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,11 @@ static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptr<s

u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();

ppu_prx_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic));
ppu_prx_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic), nullptr, true);

if (obj != elf_error::ok)
{
return CELL_PRX_ERROR_ILLEGAL_LIBRARY;
return CELL_PRX_ERROR_UNSUPPORTED_PRX_TYPE;
}

const auto prx = ppu_load_prx(obj, false, path, file_offset);
Expand Down
45 changes: 30 additions & 15 deletions rpcs3/Emu/system_progress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ void progress_dialog_server::operator()()
u32 fdone = 0;
u32 ptotal = 0;
u32 pdone = 0;
auto text1 = text0;
const char* text1 = nullptr;

const u64 start_time = get_system_time();

Expand All @@ -171,11 +171,17 @@ void progress_dialog_server::operator()()
fdone = fdone_new;
ptotal = ptotal_new;
pdone = pdone_new;
text1 = text_new;

if (!text_new)
const bool text_changed = text_new && text_new != text1;

if (text_new)
{
text1 = text_new;
}

if (!text1)
{
// Incomplete state
// Cannot do anything
continue;
}

Expand All @@ -202,7 +208,7 @@ void progress_dialog_server::operator()()
// Assume not all programs were found if files were not compiled (as it may contain more)
const u64 total = std::max<u64>(ptotal, 1) * std::max<u64>(ftotal, 1);
const u64 done = pdone * std::max<u64>(fdone, 1);
const f32 value = static_cast<f32>(std::fmin(done * 100. / total, 100.f));
const u32 value = static_cast<u32>(done >= total ? 100 : done * 100 / total);

std::string progr = "Progress:";

Expand All @@ -214,33 +220,42 @@ void progress_dialog_server::operator()()
// Changes detected, send update
if (native_dlg)
{
native_dlg->set_text(text_new);
if (text_changed)
{
native_dlg->set_text(text1);
}

native_dlg->progress_bar_set_message(0, std::move(progr));
native_dlg->progress_bar_set_value(0, std::floor(value));
native_dlg->progress_bar_set_value(0, static_cast<f32>(value));
}
else if (dlg)
{
Emu.CallFromMainThread([=]()
{
dlg->SetMsg(text_new);
if (text_changed)
{
dlg->SetMsg(text1);
}

dlg->ProgressBarSetMsg(0, progr);
dlg->ProgressBarSetValue(0, static_cast<u32>(std::floor(value)));
dlg->ProgressBarSetValue(0, value);
});
}
}
// Leave only if total count is equal to done count
else if (ftotal == fdone && ptotal == pdone && !text_new)
{
// Complete state, empty message: close dialog
break;
}

if (show_overlay_message)
{
// Make sure to update any pending messages. PPU compilation may freeze the image.
rsx::overlays::refresh_message_queue();
}

// Leave only if total count is equal to done count
if (ftotal == fdone && ptotal == pdone && !text_new)
{
// Complete state, empty message: close dialog
break;
}

thread_ctrl::wait_for(10000);
}

Expand Down