diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 8f04a4bff1..f60e2b040b 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -4286,6 +4286,8 @@ bool ppu_initialize(const ppu_module& info, bool check_only) } } + u32 total_compile = 0; + while (!jit_mod.init && fpos < info.funcs.size()) { // Initialize compiler instance @@ -4523,8 +4525,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) if (!check_only) { - // Update progress dialog - g_progr_ptotal++; + total_compile++; link_workload.emplace_back(obj_name, false); } @@ -4536,8 +4537,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) { ppu_log.success("LLVM: Module exists: %s", obj_name); - // Update progress dialog - g_progr_pdone++; + total_compile++; } continue; @@ -4563,6 +4563,17 @@ bool ppu_initialize(const ppu_module& info, bool check_only) return false; } + // Update progress dialog + if (total_compile) + { + g_progr_ptotal += total_compile; + } + + if (g_progr_ftotal) + { + g_progr_fknown++; + } + if (!workload.empty()) { *progr = "Compiling PPU modules..."; diff --git a/rpcs3/Emu/system_progress.cpp b/rpcs3/Emu/system_progress.cpp index 6d5287d163..afb9bbe13b 100644 --- a/rpcs3/Emu/system_progress.cpp +++ b/rpcs3/Emu/system_progress.cpp @@ -13,6 +13,7 @@ LOG_CHANNEL(sys_log, "SYS"); // Progress display server synchronization variables atomic_t g_progr{}; atomic_t g_progr_ftotal{0}; +atomic_t g_progr_fknown{0}; atomic_t g_progr_fdone{0}; atomic_t g_progr_ptotal{0}; atomic_t g_progr_pdone{0}; @@ -39,11 +40,11 @@ void progress_dialog_server::operator()() const auto get_state = []() { - auto whole_state = std::make_tuple(+g_progr.load(), +g_progr_ftotal, +g_progr_fdone, +g_progr_ptotal, +g_progr_pdone); + auto whole_state = std::make_tuple(+g_progr.load(), +g_progr_ftotal, +g_progr_fknown, +g_progr_fdone, +g_progr_ptotal, +g_progr_pdone); while (true) { - auto new_state = std::make_tuple(+g_progr.load(), +g_progr_ftotal, +g_progr_fdone, +g_progr_ptotal, +g_progr_pdone); + auto new_state = std::make_tuple(+g_progr.load(), +g_progr_ftotal, +g_progr_fknown, +g_progr_fdone, +g_progr_ptotal, +g_progr_pdone); if (new_state == whole_state) { @@ -71,7 +72,7 @@ void progress_dialog_server::operator()() if (g_progr_ftotal || g_progr_fdone || g_progr_ptotal || g_progr_pdone) { - const auto& [text_new, ftotal, fdone, ptotal, pdone] = get_state(); + const auto& [text_new, ftotal, fknown, fdone, ptotal, pdone] = get_state(); if (text_new) { @@ -83,6 +84,7 @@ void progress_dialog_server::operator()() { // Cleanup (missed message but do not cry over spilt milk) g_progr_fdone -= fdone; + g_progr_fknown -= fknown; g_progr_pdone -= pdone; g_progr_ftotal -= ftotal; g_progr_ptotal -= ptotal; @@ -154,6 +156,7 @@ void progress_dialog_server::operator()() u32 ftotal = 0; u32 fdone = 0; + u32 fknown = 0; u32 ptotal = 0; u32 pdone = 0; const char* text1 = nullptr; @@ -163,11 +166,12 @@ void progress_dialog_server::operator()() // Update progress while (!g_system_progress_stopping && thread_ctrl::state() != thread_state::aborting) { - const auto& [text_new, ftotal_new, fdone_new, ptotal_new, pdone_new] = get_state(); + const auto& [text_new, ftotal_new, fknown_new, fdone_new, ptotal_new, pdone_new] = get_state(); - if (ftotal != ftotal_new || fdone != fdone_new || ptotal != ptotal_new || pdone != pdone_new || text_new != text1) + if (ftotal != ftotal_new || fknown != fknown_new || fdone != fdone_new || ptotal != ptotal_new || pdone != pdone_new || text_new != text1) { ftotal = ftotal_new; + fknown = fknown_new; fdone = fdone_new; ptotal = ptotal_new; pdone = pdone_new; @@ -206,8 +210,9 @@ void progress_dialog_server::operator()() // Compute new progress in percents // Assume not all programs were found if files were not compiled (as it may contain more) - const u64 total = std::max(ptotal, 1) * std::max(ftotal, 1); - const u64 done = pdone * std::max(fdone, 1); + const u64 known_files = ftotal && fknown ? fknown : ftotal; + const u64 total = std::max(ptotal, 1) * std::max(ftotal, 1) / std::max(known_files, 1); + const u64 done = pdone; const u32 value = static_cast(done >= total ? 100 : done * 100 / total); std::string progr = "Progress:"; @@ -218,10 +223,37 @@ void progress_dialog_server::operator()() fmt::append(progr, " file %u of %u%s", fdone, ftotal, ptotal ? "," : ""); if (ptotal) fmt::append(progr, " module %u of %u", pdone, ptotal); + + if (value >= 3) + { + const u64 passed = (get_system_time() - start_time); + const u64 seconds_passed = passed / 1'000'000; + const u64 seconds_total = (passed / 1'000'000 * 100 / value); + const u64 seconds = seconds_total % 60; + const u64 minutes = (seconds_total / 60) % 60; + const u64 hours = (seconds_total / 3600); + + if (seconds_passed < 4) + { + // Cannot rely on such small duration of time for estimation + } + else if (hours) + { + fmt::append(progr, " (%uh %02um remaining)", hours, minutes); + } + else if (minutes >= 2) + { + fmt::append(progr, " (%um remaining)", minutes); + } + else + { + fmt::append(progr, " (%um %02us remaining)", minutes, seconds); + } + } } else { - fmt::append(progr, " analysing..."); + fmt::append(progr, " analyzing..."); } // Changes detected, send update @@ -289,6 +321,7 @@ void progress_dialog_server::operator()() // Cleanup g_progr_fdone -= fdone; + g_progr_fknown -= fknown; g_progr_pdone -= pdone; g_progr_ftotal -= ftotal; g_progr_ptotal -= ptotal; @@ -310,6 +343,7 @@ void progress_dialog_server::operator()() progress_dialog_server::~progress_dialog_server() { g_progr_ftotal.release(0); + g_progr_fknown.release(0); g_progr_fdone.release(0); g_progr_ptotal.release(0); g_progr_pdone.release(0); diff --git a/rpcs3/Emu/system_progress.hpp b/rpcs3/Emu/system_progress.hpp index 76e8e38ca7..976366f864 100644 --- a/rpcs3/Emu/system_progress.hpp +++ b/rpcs3/Emu/system_progress.hpp @@ -17,6 +17,7 @@ struct alignas(16) progress_dialog_string_t extern atomic_t g_progr; extern atomic_t g_progr_ftotal; +extern atomic_t g_progr_fknown; extern atomic_t g_progr_fdone; extern atomic_t g_progr_ptotal; extern atomic_t g_progr_pdone;