mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 15:15:40 +00:00
System: Reduce rewind/runahead memory usage w/o 8MB enabled
This commit is contained in:
parent
81295c8a7d
commit
e6a682f8d5
|
@ -25,6 +25,7 @@ struct SAVE_STATE_HEADER
|
||||||
{
|
{
|
||||||
MAX_TITLE_LENGTH = 128,
|
MAX_TITLE_LENGTH = 128,
|
||||||
MAX_SERIAL_LENGTH = 32,
|
MAX_SERIAL_LENGTH = 32,
|
||||||
|
MAX_SAVE_STATE_SIZE = 32 * 1024 * 1024,
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 magic;
|
u32 magic;
|
||||||
|
|
|
@ -122,7 +122,7 @@ static void InternalReset();
|
||||||
static void ClearRunningGame();
|
static void ClearRunningGame();
|
||||||
static void DestroySystem();
|
static void DestroySystem();
|
||||||
static std::string GetMediaPathFromSaveState(const char* path);
|
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 CreateGPU(GPURenderer renderer, bool is_switching, Error* error);
|
||||||
static bool SaveUndoLoadState();
|
static bool SaveUndoLoadState();
|
||||||
static void WarnAboutUnsafeSettings();
|
static void WarnAboutUnsafeSettings();
|
||||||
|
@ -174,6 +174,10 @@ struct MemorySaveState
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
/// Returns the maximum size of a save state, considering the current configuration.
|
||||||
|
static size_t GetMaxSaveStateSize();
|
||||||
|
|
||||||
static bool SaveMemoryState(MemorySaveState* mss);
|
static bool SaveMemoryState(MemorySaveState* mss);
|
||||||
static bool LoadMemoryState(const MemorySaveState& mss);
|
static bool LoadMemoryState(const MemorySaveState& mss);
|
||||||
static bool LoadStateFromBuffer(const SaveStateBuffer& buffer, Error* error, bool update_display);
|
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 screenshot_compression = SaveStateCompression::ZLib,
|
||||||
SaveStateCompression data_compression = SaveStateCompression::ZStd);
|
SaveStateCompression data_compression = SaveStateCompression::ZStd);
|
||||||
static u32 CompressAndWriteStateData(std::FILE* fp, std::span<const u8> src, SaveStateCompression method, Error* error);
|
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);
|
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();
|
g_gpu->RestoreDeviceContext();
|
||||||
|
|
||||||
// save current state
|
// 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);
|
StateWrapper sw(state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
||||||
if (!g_gpu->DoState(sw, nullptr, false) || !TimingEvents::DoState(sw))
|
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)
|
std::string System::GetMediaPathFromSaveState(const char* path)
|
||||||
{
|
{
|
||||||
SaveStateBuffer buffer;
|
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 ||
|
(static_cast<s64>(header.offset_to_screenshot) + header.screenshot_compressed_size) > file_size ||
|
||||||
header.screenshot_width >= 32768 || header.screenshot_height >= 32768 ||
|
header.screenshot_width >= 32768 || header.screenshot_height >= 32768 ||
|
||||||
(static_cast<s64>(header.offset_to_data) + header.data_compressed_size) > file_size ||
|
(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.");
|
Error::SetStringView(error, "Save state header is corrupted.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -2885,7 +2899,7 @@ bool System::SaveStateToBuffer(SaveStateBuffer* buffer, Error* error, u32 screen
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
if (buffer->state_data.empty())
|
if (buffer->state_data.empty())
|
||||||
buffer->state_data.resize(MAX_SAVE_STATE_SIZE);
|
buffer->state_data.resize(GetMaxSaveStateSize());
|
||||||
|
|
||||||
g_gpu->RestoreDeviceContext();
|
g_gpu->RestoreDeviceContext();
|
||||||
StateWrapper sw(buffer->state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
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)
|
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);
|
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) *
|
*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);
|
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)
|
bool System::SaveMemoryState(MemorySaveState* mss)
|
||||||
{
|
{
|
||||||
if (mss->state_data.empty())
|
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();
|
GPUTexture* host_texture = mss->vram_texture.release();
|
||||||
StateWrapper sw(mss->state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
StateWrapper sw(mss->state_data.span(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
||||||
|
|
|
@ -77,12 +77,6 @@ struct ExtendedSaveStateInfo
|
||||||
|
|
||||||
namespace System {
|
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
|
enum : s32
|
||||||
{
|
{
|
||||||
PER_GAME_SAVE_STATE_SLOTS = 10,
|
PER_GAME_SAVE_STATE_SLOTS = 10,
|
||||||
|
|
Loading…
Reference in a new issue