System: Reduce rewind/runahead memory usage w/o 8MB enabled

This commit is contained in:
Stenzek 2024-08-06 16:02:18 +10:00
parent 81295c8a7d
commit e6a682f8d5
No known key found for this signature in database
3 changed files with 21 additions and 12 deletions

View file

@ -25,6 +25,7 @@ struct SAVE_STATE_HEADER
{
MAX_TITLE_LENGTH = 128,
MAX_SERIAL_LENGTH = 32,
MAX_SAVE_STATE_SIZE = 32 * 1024 * 1024,
};
u32 magic;

View file

@ -122,7 +122,7 @@ static void InternalReset();
static void ClearRunningGame();
static void DestroySystem();
static std::string GetMediaPathFromSaveState(const char* path);
static bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display, bool is_memory_state);
static bool CreateGPU(GPURenderer renderer, bool is_switching, Error* error);
static bool SaveUndoLoadState();
static void WarnAboutUnsafeSettings();
@ -174,6 +174,10 @@ struct MemorySaveState
#endif
};
} // namespace
/// Returns the maximum size of a save state, considering the current configuration.
static size_t GetMaxSaveStateSize();
static bool SaveMemoryState(MemorySaveState* mss);
static bool LoadMemoryState(const MemorySaveState& mss);
static bool LoadStateFromBuffer(const SaveStateBuffer& buffer, Error* error, bool update_display);
@ -186,6 +190,7 @@ static bool SaveStateBufferToFile(const SaveStateBuffer& buffer, std::FILE* fp,
SaveStateCompression screenshot_compression = SaveStateCompression::ZLib,
SaveStateCompression data_compression = SaveStateCompression::ZStd);
static u32 CompressAndWriteStateData(std::FILE* fp, std::span<const u8> src, SaveStateCompression method, Error* error);
static bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display, bool is_memory_state);
static void UpdateSessionTime(const std::string& prev_serial);
@ -1103,7 +1108,7 @@ bool System::RecreateGPU(GPURenderer renderer, bool force_recreate_device, bool
g_gpu->RestoreDeviceContext();
// save current state
DynamicHeapArray<u8> state_data(MAX_SAVE_STATE_SIZE);
DynamicHeapArray<u8> state_data(GetMaxSaveStateSize());
{
StateWrapper sw(state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
if (!g_gpu->DoState(sw, nullptr, false) || !TimingEvents::DoState(sw))
@ -2434,6 +2439,15 @@ void System::ResetBootMode()
}
}
size_t System::GetMaxSaveStateSize()
{
// 5 megabytes is sufficient for now, at the moment they're around 4.3MB, or 10.3MB with 8MB RAM enabled.
static constexpr u32 MAX_2MB_SAVE_STATE_SIZE = 5 * 1024 * 1024;
static constexpr u32 MAX_8MB_SAVE_STATE_SIZE = 11 * 1024 * 1024;
const bool is_8mb_ram = (System::IsValid() ? (Bus::g_ram_size > Bus::RAM_2MB_SIZE) : g_settings.enable_8mb_ram);
return is_8mb_ram ? MAX_8MB_SAVE_STATE_SIZE : MAX_2MB_SAVE_STATE_SIZE;
}
std::string System::GetMediaPathFromSaveState(const char* path)
{
SaveStateBuffer buffer;
@ -2634,7 +2648,7 @@ bool System::LoadStateBufferFromFile(SaveStateBuffer* buffer, std::FILE* fp, Err
(static_cast<s64>(header.offset_to_screenshot) + header.screenshot_compressed_size) > file_size ||
header.screenshot_width >= 32768 || header.screenshot_height >= 32768 ||
(static_cast<s64>(header.offset_to_data) + header.data_compressed_size) > file_size ||
header.data_uncompressed_size > MAX_SAVE_STATE_SIZE) [[unlikely]]
header.data_uncompressed_size > SAVE_STATE_HEADER::MAX_SAVE_STATE_SIZE) [[unlikely]]
{
Error::SetStringView(error, "Save state header is corrupted.");
return false;
@ -2885,7 +2899,7 @@ bool System::SaveStateToBuffer(SaveStateBuffer* buffer, Error* error, u32 screen
// write data
if (buffer->state_data.empty())
buffer->state_data.resize(MAX_SAVE_STATE_SIZE);
buffer->state_data.resize(GetMaxSaveStateSize());
g_gpu->RestoreDeviceContext();
StateWrapper sw(buffer->state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
@ -4476,7 +4490,7 @@ void System::LogUnsafeSettingsToConsole(const SmallStringBase& messages)
void System::CalculateRewindMemoryUsage(u32 num_saves, u32 resolution_scale, u64* ram_usage, u64* vram_usage)
{
const u64 real_resolution_scale = std::max<u64>(g_settings.gpu_resolution_scale, 1u);
*ram_usage = MAX_SAVE_STATE_SIZE * static_cast<u64>(num_saves);
*ram_usage = GetMaxSaveStateSize() * static_cast<u64>(num_saves);
*vram_usage = ((VRAM_WIDTH * real_resolution_scale) * (VRAM_HEIGHT * real_resolution_scale) * 4) *
static_cast<u64>(g_settings.gpu_multisamples) * static_cast<u64>(num_saves);
}
@ -4536,7 +4550,7 @@ bool System::LoadMemoryState(const MemorySaveState& mss)
bool System::SaveMemoryState(MemorySaveState* mss)
{
if (mss->state_data.empty())
mss->state_data.resize(MAX_SAVE_STATE_SIZE);
mss->state_data.resize(GetMaxSaveStateSize());
GPUTexture* host_texture = mss->vram_texture.release();
StateWrapper sw(mss->state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);

View file

@ -77,12 +77,6 @@ struct ExtendedSaveStateInfo
namespace System {
enum : u32
{
// 5 megabytes is sufficient for now, at the moment they're around 4.3MB, or 10.3MB with 8MB RAM enabled.
MAX_SAVE_STATE_SIZE = 11 * 1024 * 1024,
};
enum : s32
{
PER_GAME_SAVE_STATE_SLOTS = 10,