Savestates: Compressed state files

This commit is contained in:
Eladash 2023-11-15 21:07:42 +02:00 committed by Elad Ashkenazi
parent 91dbd92193
commit f60bdbaece
27 changed files with 1377 additions and 370 deletions

View file

@ -4,6 +4,7 @@
#include "Emu/Cell/PPUCallback.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/timers.hpp"
#include "Emu/savestate_utils.hpp"
#include "Capture/rsx_capture.h"
#include "Common/BufferUtils.h"
@ -19,6 +20,7 @@
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/lv2/sys_time.h"
#include "Emu/Cell/Modules/cellGcmSys.h"
#include "Emu/savestate_utils.hpp"
#include "Overlays/overlay_perf_metrics.h"
#include "Overlays/overlay_message.h"
#include "Program/GLSLCommon.h"
@ -26,7 +28,6 @@
#include "Utilities/StrUtil.h"
#include "Crypto/unzip.h"
#include "util/serialization.hpp"
#include "util/asm.hpp"
#include <span>
@ -3574,6 +3575,8 @@ namespace rsx
void thread::on_frame_end(u32 buffer, bool forced)
{
bool pause_emulator = false;
// Marks the end of a frame scope GPU-side
if (g_user_asked_for_frame_capture.exchange(false) && !capture_current_frame)
{
@ -3594,36 +3597,34 @@ namespace rsx
{
capture_current_frame = false;
std::string file_path = fs::get_config_dir() + "captures/" + Emu.GetTitleID() + "_" + date_time::current_time_narrow() + "_capture.rrc";
utils::serial save_manager;
save_manager.reserve(0x800'0000); // 128MB
save_manager(frame_capture);
if (std::vector<u8> zipped = zip(save_manager.data); !zipped.empty())
{
file_path += ".gz";
save_manager.data = std::move(zipped);
}
else
{
rsx_log.error("Failed to compress capture");
}
std::string file_path = fs::get_config_dir() + "captures/" + Emu.GetTitleID() + "_" + date_time::current_time_narrow() + "_capture.rrc.gz";
fs::pending_file temp(file_path);
if (temp.file && (temp.file.write(save_manager.data), temp.commit(false)))
utils::serial save_manager;
if (temp.file)
{
rsx_log.success("Capture successful: %s", file_path);
save_manager.m_file_handler = make_compressed_serialization_file_handler(temp.file);
save_manager(frame_capture);
save_manager.m_file_handler->finalize(save_manager);
if (temp.commit(false))
{
rsx_log.success("Capture successful: %s", file_path);
frame_capture.reset();
pause_emulator = true;
}
else
{
rsx_log.error("Capture failed: %s (%s)", file_path, fs::g_tls_error);
}
}
else
{
rsx_log.fatal("Capture failed: %s (%s)", file_path, fs::g_tls_error);
}
frame_capture.reset();
Emu.Pause();
}
if (zcull_ctrl->has_pending())
@ -3673,6 +3674,12 @@ namespace rsx
}
}
if (pause_emulator)
{
Emu.Pause();
thread_ctrl::wait_for(30'000);
}
// Reset current stats
m_frame_stats = {};
m_profiler.enabled = !!g_cfg.video.overlay;