Skip to content

Commit 654587e

Browse files
committed
System: Add 'Low VRAM' rewind mode
i.e. use the software renderer for rewinding instead. Works fairly well, and takes away the VRAM hit when upscaling.
1 parent a8967b2 commit 654587e

File tree

11 files changed

+167
-63
lines changed

11 files changed

+167
-63
lines changed

src/core/cpu_pgxp.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ enum : u32
6363

6464
#define PGXP_GTE_REGISTER(field) g_state.pgxp_gte[offsetof(GTE::Regs, field) / sizeof(u32)]
6565

66-
static bool ShouldSavePGXPState();
67-
6866
static double f16Sign(double val);
6967
static double f16Unsign(double val);
7068
static double f16Overflow(double val);
@@ -203,9 +201,6 @@ bool CPU::PGXP::ShouldSavePGXPState()
203201

204202
size_t CPU::PGXP::GetStateSize()
205203
{
206-
if (!ShouldSavePGXPState())
207-
return 0;
208-
209204
const size_t base_size = sizeof(g_state.pgxp_gpr) + sizeof(g_state.pgxp_cop0) + sizeof(g_state.pgxp_gte) +
210205
(sizeof(PGXPValue) * PGXP_MEM_SIZE);
211206
const size_t vertex_cache_size = sizeof(PGXPValue) * VERTEX_CACHE_SIZE;

src/core/cpu_pgxp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ void Initialize();
1111
void Reset();
1212
void Shutdown();
1313

14+
/// Returns true if PGXP state should be saved to memory save states.
15+
bool ShouldSavePGXPState();
16+
1417
/// Returns memory usage to serialize additional PGXP state.
1518
size_t GetStateSize();
1619

src/core/fullscreenui_settings.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,11 @@ void FullscreenUI::DrawEmulationSettingsPage()
28042804
FSUI_VSTR("Saves state periodically so you can rewind any mistakes while playing."), "Main",
28052805
"RewindEnable", false, !runahead_enabled);
28062806

2807+
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_PF_GPU_GRAPHICS_CARD, "Use Software Renderer (Low VRAM Mode)"),
2808+
FSUI_VSTR("Uses the software renderer when creating rewind states to prevent additional VRAM "
2809+
"usage. Especially useful when upscaling."),
2810+
"GPU", "UseSoftwareRendererForMemoryStates", false, rewind_enabled);
2811+
28072812
DrawFloatRangeSetting(
28082813
bsi, FSUI_ICONVSTR(ICON_FA_FLOPPY_DISK, "Rewind Save Frequency"),
28092814
FSUI_VSTR("How often a rewind state will be created. Higher frequencies have greater system requirements."), "Main",
@@ -2837,17 +2842,29 @@ void FullscreenUI::DrawEmulationSettingsPage()
28372842
else if (rewind_enabled)
28382843
{
28392844
const u32 resolution_scale = GetEffectiveUIntSetting(bsi, "GPU", "ResolutionScale", 1);
2845+
const u32 multisamples = GetEffectiveUIntSetting(bsi, "GPU", "Multisamples", 1);
2846+
const bool use_software_renderer = GetEffectiveBoolSetting(bsi, "GPU", "UseSoftwareRendererForMemoryStates", false);
2847+
const bool enable_8mb_ram = GetEffectiveBoolSetting(bsi, "Console", "Enable8MBRAM", false);
28402848
const float rewind_frequency = GetEffectiveFloatSetting(bsi, "Main", "RewindFrequency", 10.0f);
28412849
const s32 rewind_save_slots = GetEffectiveIntSetting(bsi, "Main", "RewindSaveSlots", 10);
28422850
const float duration =
28432851
((rewind_frequency <= std::numeric_limits<float>::epsilon()) ? (1.0f / 60.0f) : rewind_frequency) *
28442852
static_cast<float>(rewind_save_slots);
28452853

28462854
u64 ram_usage, vram_usage;
2847-
System::CalculateRewindMemoryUsage(rewind_save_slots, resolution_scale, &ram_usage, &vram_usage);
2848-
rewind_summary.format(
2849-
FSUI_FSTR("Rewind for {0} frames, lasting {1:.2f} seconds will require up to {2} MB of RAM and {3} MB of VRAM."),
2850-
rewind_save_slots, duration, ram_usage / 1048576, vram_usage / 1048576);
2855+
System::CalculateRewindMemoryUsage(rewind_save_slots, resolution_scale, multisamples, use_software_renderer,
2856+
enable_8mb_ram, &ram_usage, &vram_usage);
2857+
if (vram_usage > 0)
2858+
{
2859+
rewind_summary.format(
2860+
FSUI_FSTR("Rewind for {0} frames, lasting {1:.2f} seconds will require {2} MB of RAM and {3} MB of VRAM."),
2861+
rewind_save_slots, duration, ram_usage / 1048576, vram_usage / 1048576);
2862+
}
2863+
else
2864+
{
2865+
rewind_summary.format(FSUI_FSTR("Rewind for {0} frames, lasting {1:.2f} seconds will require {2} MB of RAM."),
2866+
rewind_save_slots, duration, ram_usage / 1048576);
2867+
}
28512868
}
28522869
else
28532870
{

src/core/fullscreenui_strings.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,8 @@ TRANSLATE_NOOP("FullscreenUI", "Return to the previous menu.");
589589
TRANSLATE_NOOP("FullscreenUI", "Reverses the game list sort order from the default (usually ascending to descending).");
590590
TRANSLATE_NOOP("FullscreenUI", "Rewind Save Frequency");
591591
TRANSLATE_NOOP("FullscreenUI", "Rewind Save Slots");
592-
TRANSLATE_NOOP("FullscreenUI", "Rewind for {0} frames, lasting {1:.2f} seconds will require up to {2} MB of RAM and {3} MB of VRAM.");
592+
TRANSLATE_NOOP("FullscreenUI", "Rewind for {0} frames, lasting {1:.2f} seconds will require {2} MB of RAM and {3} MB of VRAM.");
593+
TRANSLATE_NOOP("FullscreenUI", "Rewind for {0} frames, lasting {1:.2f} seconds will require {2} MB of RAM.");
593594
TRANSLATE_NOOP("FullscreenUI", "Rewind is disabled because runahead is enabled. Runahead will significantly increase system requirements.");
594595
TRANSLATE_NOOP("FullscreenUI", "Rewind is not enabled. Please note that enabling rewind may significantly increase system requirements.");
595596
TRANSLATE_NOOP("FullscreenUI", "Right: ");
@@ -780,6 +781,7 @@ TRANSLATE_NOOP("FullscreenUI", "Use Global Setting");
780781
TRANSLATE_NOOP("FullscreenUI", "Use Old MDEC Routines");
781782
TRANSLATE_NOOP("FullscreenUI", "Use Separate Disc Settings");
782783
TRANSLATE_NOOP("FullscreenUI", "Use Single Card For Multi-Disc Games");
784+
TRANSLATE_NOOP("FullscreenUI", "Use Software Renderer (Low VRAM Mode)");
783785
TRANSLATE_NOOP("FullscreenUI", "Use Software Renderer For Readbacks");
784786
TRANSLATE_NOOP("FullscreenUI", "User Name");
785787
TRANSLATE_NOOP("FullscreenUI", "Uses OpenGL ES even when desktop OpenGL is supported. May improve performance on some SBC drivers.");
@@ -793,6 +795,7 @@ TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for color
793795
TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for texture coordinates, straightening out warped textures.");
794796
TRANSLATE_NOOP("FullscreenUI", "Uses screen positions to resolve PGXP data. May improve visuals in some games.");
795797
TRANSLATE_NOOP("FullscreenUI", "Uses separate game settings for each disc of multi-disc games. Can only be set on the first/main disc.");
798+
TRANSLATE_NOOP("FullscreenUI", "Uses the software renderer when creating rewind states to prevent additional VRAM usage. Especially useful when upscaling.");
796799
TRANSLATE_NOOP("FullscreenUI", "Utilizes the chosen frame rate regardless of the game's setting.");
797800
TRANSLATE_NOOP("FullscreenUI", "Value Range");
798801
TRANSLATE_NOOP("FullscreenUI", "Value: {} | Default: {} | Minimum: {} | Maximum: {}");

src/core/gpu_hw.cpp

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,14 @@ ALWAYS_INLINE_RELEASE static u32 GetBoxDownsampleScale(u32 resolution_scale)
101101

102102
ALWAYS_INLINE static bool ShouldDrawWithSoftwareRenderer()
103103
{
104-
return g_gpu_settings.gpu_use_software_renderer_for_readbacks;
104+
return (g_gpu_settings.gpu_use_software_renderer_for_readbacks ||
105+
g_gpu_settings.gpu_use_software_renderer_for_memory_states);
105106
}
106107

107108
ALWAYS_INLINE static bool ShouldClampUVs(GPUTextureFilter texture_filter)
108109
{
109110
// We only need UV limits if PGXP is enabled, or texture filtering is enabled.
110-
return g_gpu_settings.gpu_pgxp_enable || texture_filter != GPUTextureFilter::Nearest;
111+
return (g_gpu_settings.gpu_pgxp_enable || texture_filter != GPUTextureFilter::Nearest);
111112
}
112113

113114
ALWAYS_INLINE static bool ShouldAllowSpriteMode(u8 resolution_scale, GPUTextureFilter texture_filter,
@@ -390,17 +391,24 @@ void GPU_HW::LoadState(const GPUBackendLoadStateCommand* cmd)
390391

391392
bool GPU_HW::AllocateMemorySaveState(System::MemorySaveState& mss, Error* error)
392393
{
393-
mss.vram_texture = g_gpu_device->FetchTexture(
394-
m_vram_texture->GetWidth(), m_vram_texture->GetHeight(), 1, 1, m_vram_texture->GetSamples(),
395-
m_vram_texture->IsMultisampled() ? GPUTexture::Type::RenderTarget : GPUTexture::Type::Texture,
396-
GPUTexture::Format::RGBA8, GPUTexture::Flags::None, nullptr, 0, error);
397-
if (!mss.vram_texture) [[unlikely]]
394+
if (!g_gpu_settings.gpu_use_software_renderer_for_memory_states)
398395
{
399-
Error::AddPrefix(error, "Failed to allocate VRAM texture for memory save state: ");
400-
return false;
401-
}
396+
mss.vram_texture = g_gpu_device->FetchTexture(
397+
m_vram_texture->GetWidth(), m_vram_texture->GetHeight(), 1, 1, m_vram_texture->GetSamples(),
398+
m_vram_texture->IsMultisampled() ? GPUTexture::Type::RenderTarget : GPUTexture::Type::Texture,
399+
GPUTexture::Format::RGBA8, GPUTexture::Flags::None, nullptr, 0, error);
400+
if (!mss.vram_texture) [[unlikely]]
401+
{
402+
Error::AddPrefix(error, "Failed to allocate VRAM texture for memory save state: ");
403+
return false;
404+
}
402405

403-
GL_OBJECT_NAME(mss.vram_texture, "Memory save state VRAM copy");
406+
GL_OBJECT_NAME(mss.vram_texture, "Memory save state VRAM copy");
407+
}
408+
else
409+
{
410+
mss.vram_texture.reset();
411+
}
404412

405413
static constexpr u32 MAX_TC_SIZE = 1024 * 1024;
406414

@@ -420,32 +428,19 @@ bool GPU_HW::AllocateMemorySaveState(System::MemorySaveState& mss, Error* error)
420428

421429
void GPU_HW::DoMemoryState(StateWrapper& sw, System::MemorySaveState& mss)
422430
{
423-
Assert(mss.vram_texture && mss.vram_texture->GetWidth() == m_vram_texture->GetWidth() &&
424-
mss.vram_texture->GetHeight() == m_vram_texture->GetHeight() &&
425-
mss.vram_texture->GetSamples() == m_vram_texture->GetSamples());
426-
427431
if (sw.IsReading())
428432
{
429433
if (m_batch_vertex_ptr)
430434
UnmapGPUBuffer(0, 0);
431435

432-
g_gpu_device->CopyTextureRegion(m_vram_texture.get(), 0, 0, 0, 0, mss.vram_texture.get(), 0, 0, 0, 0,
433-
m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
434-
435436
m_batch = {};
436-
ClearVRAMDirtyRectangle();
437-
SetFullVRAMDirtyRectangle();
438-
UpdateVRAMReadTexture(true, false);
439-
ClearVRAMDirtyRectangle();
440437
ResetBatchVertexDepth();
441438
}
442439
else
443440
{
444-
FlushRender();
445-
446-
// saving state
447-
g_gpu_device->CopyTextureRegion(mss.vram_texture.get(), 0, 0, 0, 0, m_vram_texture.get(), 0, 0, 0, 0,
448-
m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
441+
// don't bother flushing render if we're using the software renderer
442+
if (mss.vram_texture)
443+
FlushRender();
449444
}
450445

451446
// Save VRAM/CLUT.
@@ -458,6 +453,37 @@ void GPU_HW::DoMemoryState(StateWrapper& sw, System::MemorySaveState& mss)
458453
if (!GPUTextureCache::DoState(sw, false)) [[unlikely]]
459454
Panic("Failed to process texture cache state.");
460455
}
456+
457+
if (sw.IsReading())
458+
{
459+
if (mss.vram_texture)
460+
{
461+
Assert(mss.vram_texture->GetWidth() == m_vram_texture->GetWidth() &&
462+
mss.vram_texture->GetHeight() == m_vram_texture->GetHeight() &&
463+
mss.vram_texture->GetSamples() == m_vram_texture->GetSamples());
464+
465+
g_gpu_device->CopyTextureRegion(m_vram_texture.get(), 0, 0, 0, 0, mss.vram_texture.get(), 0, 0, 0, 0,
466+
m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
467+
}
468+
else
469+
{
470+
UpdateVRAMOnGPU(0, 0, VRAM_WIDTH, VRAM_HEIGHT, g_vram, VRAM_WIDTH * sizeof(u16), false, false, VRAM_SIZE_RECT);
471+
}
472+
473+
ClearVRAMDirtyRectangle();
474+
SetFullVRAMDirtyRectangle();
475+
UpdateVRAMReadTexture(true, false);
476+
ClearVRAMDirtyRectangle();
477+
}
478+
else
479+
{
480+
// saving state
481+
if (mss.vram_texture)
482+
{
483+
g_gpu_device->CopyTextureRegion(mss.vram_texture.get(), 0, 0, 0, 0, m_vram_texture.get(), 0, 0, 0, 0,
484+
m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
485+
}
486+
}
461487
}
462488

463489
void GPU_HW::RestoreDeviceContext()

src/core/settings.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
256256
gpu_use_thread = si.GetBoolValue("GPU", "UseThread", true);
257257
gpu_max_queued_frames = static_cast<u8>(si.GetUIntValue("GPU", "MaxQueuedFrames", DEFAULT_GPU_MAX_QUEUED_FRAMES));
258258
gpu_use_software_renderer_for_readbacks = si.GetBoolValue("GPU", "UseSoftwareRendererForReadbacks", false);
259+
gpu_use_software_renderer_for_memory_states = si.GetBoolValue("GPU", "UseSoftwareRendererForMemoryStates", false);
259260
gpu_scaled_interlacing = si.GetBoolValue("GPU", "ScaledInterlacing", true);
260261
gpu_force_round_texcoords = si.GetBoolValue("GPU", "ForceRoundTextureCoordinates", false);
261262
gpu_texture_filter =
@@ -637,6 +638,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
637638
si.SetUIntValue("GPU", "MaxQueuedFrames", gpu_max_queued_frames);
638639
si.SetBoolValue("GPU", "UseThread", gpu_use_thread);
639640
si.SetBoolValue("GPU", "UseSoftwareRendererForReadbacks", gpu_use_software_renderer_for_readbacks);
641+
si.SetBoolValue("GPU", "UseSoftwareRendererForMemoryStates", gpu_use_software_renderer_for_memory_states);
640642
si.SetBoolValue("GPU", "ScaledInterlacing", gpu_scaled_interlacing);
641643
si.SetBoolValue("GPU", "ForceRoundTextureCoordinates", gpu_force_round_texcoords);
642644
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
@@ -1176,6 +1178,9 @@ void Settings::FixIncompatibleSettings(const SettingsInterface& si, bool display
11761178
cpu_recompiler_block_linking = false;
11771179
}
11781180
}
1181+
1182+
// Don't waste time running the software renderer for CPU-only rewind when rewind isn't enabled.
1183+
gpu_use_software_renderer_for_memory_states &= rewind_enable;
11791184
}
11801185

11811186
bool Settings::AreGPUDeviceSettingsChanged(const Settings& old_settings) const

src/core/settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct GPUSettings
5858
u8 gpu_max_queued_frames = DEFAULT_GPU_MAX_QUEUED_FRAMES;
5959
bool gpu_use_thread : 1 = true;
6060
bool gpu_use_software_renderer_for_readbacks : 1 = false;
61+
bool gpu_use_software_renderer_for_memory_states : 1 = false;
6162
bool gpu_use_debug_device : 1 = false;
6263
bool gpu_use_debug_device_gpu_validation : 1 = false;
6364
bool gpu_prefer_gles_context : 1 = DEFAULT_GPU_PREFER_GLES_CONTEXT;

src/core/system.cpp

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,7 +2636,7 @@ bool System::AllocateMemoryStates(size_t state_count, bool recycle_old_textures)
26362636

26372637
// Allocate CPU buffers.
26382638
// TODO: Maybe look at host memory limits here...
2639-
const size_t size = GetMaxMemorySaveStateSize();
2639+
const size_t size = GetMaxMemorySaveStateSize(g_settings.cpu_enable_8mb_ram, CPU::PGXP::ShouldSavePGXPState());
26402640
for (MemorySaveState& mss : s_state.memory_save_states)
26412641
{
26422642
mss.state_size = 0;
@@ -2904,18 +2904,17 @@ bool System::SetBootMode(BootMode new_boot_mode, DiscRegion disc_region, Error*
29042904
return true;
29052905
}
29062906

2907-
size_t System::GetMaxSaveStateSize()
2907+
size_t System::GetMaxSaveStateSize(bool enable_8mb_ram)
29082908
{
29092909
// 5 megabytes is sufficient for now, at the moment they're around 4.3MB, or 10.3MB with 8MB RAM enabled.
29102910
static constexpr u32 MAX_2MB_SAVE_STATE_SIZE = 5 * 1024 * 1024;
29112911
static constexpr u32 MAX_8MB_SAVE_STATE_SIZE = 11 * 1024 * 1024;
2912-
const bool is_8mb_ram = (System::IsValid() ? (Bus::g_ram_size > Bus::RAM_2MB_SIZE) : g_settings.cpu_enable_8mb_ram);
2913-
return is_8mb_ram ? MAX_8MB_SAVE_STATE_SIZE : MAX_2MB_SAVE_STATE_SIZE;
2912+
return enable_8mb_ram ? MAX_8MB_SAVE_STATE_SIZE : MAX_2MB_SAVE_STATE_SIZE;
29142913
}
29152914

2916-
size_t System::GetMaxMemorySaveStateSize()
2915+
size_t System::GetMaxMemorySaveStateSize(bool enable_8mb_ram, bool pgxp)
29172916
{
2918-
return GetMaxSaveStateSize() + CPU::PGXP::GetStateSize();
2917+
return GetMaxSaveStateSize(enable_8mb_ram) + (pgxp ? CPU::PGXP::GetStateSize() : 0);
29192918
}
29202919

29212920
std::string System::GetMediaPathFromSaveState(const char* path)
@@ -3448,7 +3447,7 @@ bool System::SaveStateToBuffer(SaveStateBuffer* buffer, Error* error, u32 screen
34483447

34493448
// write data
34503449
if (buffer->state_data.empty())
3451-
buffer->state_data.resize(GetMaxSaveStateSize());
3450+
buffer->state_data.resize(GetMaxSaveStateSize(Bus::g_ram_size > Bus::RAM_2MB_SIZE));
34523451

34533452
return SaveStateDataToBuffer(buffer->state_data, &buffer->state_size, error);
34543453
}
@@ -4559,6 +4558,8 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
45594558
g_settings.gpu_max_queued_frames != old_settings.gpu_max_queued_frames ||
45604559
g_settings.gpu_use_software_renderer_for_readbacks !=
45614560
old_settings.gpu_use_software_renderer_for_readbacks ||
4561+
g_settings.gpu_use_software_renderer_for_memory_states !=
4562+
old_settings.gpu_use_software_renderer_for_memory_states ||
45624563
g_settings.gpu_scaled_interlacing != old_settings.gpu_scaled_interlacing ||
45634564
g_settings.gpu_force_round_texcoords != old_settings.gpu_force_round_texcoords ||
45644565
g_settings.gpu_texture_filter != old_settings.gpu_texture_filter ||
@@ -4596,9 +4597,19 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
45964597
GPUThread::UpdateSettings(true, false, false);
45974598

45984599
// NOTE: Must come after the GPU thread settings update, otherwise it allocs the wrong size textures.
4599-
const bool use_existing_textures = (g_settings.gpu_resolution_scale == old_settings.gpu_resolution_scale);
4600+
const bool use_existing_textures = (g_settings.gpu_resolution_scale == old_settings.gpu_resolution_scale &&
4601+
g_settings.gpu_use_software_renderer_for_memory_states ==
4602+
old_settings.gpu_use_software_renderer_for_memory_states);
46004603
FreeMemoryStateStorage(false, true, use_existing_textures);
4601-
ClearMemorySaveStates(true, true);
4604+
4605+
if (g_settings.rewind_enable == old_settings.rewind_enable &&
4606+
g_settings.rewind_save_frequency == old_settings.rewind_save_frequency &&
4607+
g_settings.rewind_save_slots == old_settings.rewind_save_slots &&
4608+
g_settings.runahead_frames == old_settings.runahead_frames)
4609+
{
4610+
// done below if rewind settings changed
4611+
ClearMemorySaveStates(true, true);
4612+
}
46024613

46034614
if (IsPaused())
46044615
{
@@ -4633,7 +4644,15 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
46334644
FreeMemoryStateStorage(false, true, false);
46344645
StopMediaCapture();
46354646
GPUThread::UpdateSettings(true, true, g_settings.gpu_use_thread != old_settings.gpu_use_thread);
4636-
ClearMemorySaveStates(true, false);
4647+
4648+
if (g_settings.rewind_enable == old_settings.rewind_enable &&
4649+
g_settings.rewind_save_frequency == old_settings.rewind_save_frequency &&
4650+
g_settings.rewind_save_slots == old_settings.rewind_save_slots &&
4651+
g_settings.runahead_frames == old_settings.runahead_frames)
4652+
{
4653+
// done below if rewind settings changed
4654+
ClearMemorySaveStates(true, false);
4655+
}
46374656

46384657
if (IsPaused())
46394658
{
@@ -5019,12 +5038,16 @@ void System::LogUnsafeSettingsToConsole(const SmallStringBase& messages)
50195038
WARNING_LOG(console_messages);
50205039
}
50215040

5022-
void System::CalculateRewindMemoryUsage(u32 num_saves, u32 resolution_scale, u64* ram_usage, u64* vram_usage)
5041+
void System::CalculateRewindMemoryUsage(u32 num_saves, u32 resolution_scale, u32 multisamples,
5042+
bool use_software_renderer, bool enable_8mb_ram, u64* ram_usage,
5043+
u64* vram_usage)
50235044
{
5024-
const u64 real_resolution_scale = std::max<u64>(g_settings.gpu_resolution_scale, 1u);
5025-
*ram_usage = GetMaxMemorySaveStateSize() * static_cast<u64>(num_saves);
5026-
*vram_usage = ((VRAM_WIDTH * real_resolution_scale) * (VRAM_HEIGHT * real_resolution_scale) * 4) *
5027-
static_cast<u64>(g_settings.gpu_multisamples) * static_cast<u64>(num_saves);
5045+
const u32 real_resolution_scale = std::max<u32>(resolution_scale, 1u);
5046+
*ram_usage = GetMaxMemorySaveStateSize(enable_8mb_ram, false) * static_cast<u64>(num_saves);
5047+
*vram_usage = use_software_renderer ? 0 :
5048+
((static_cast<u64>(VRAM_WIDTH * real_resolution_scale) *
5049+
static_cast<u64>(VRAM_HEIGHT * real_resolution_scale) * 4) *
5050+
static_cast<u64>(multisamples) * static_cast<u64>(num_saves));
50285051
}
50295052

50305053
void System::UpdateMemorySaveStateSettings()
@@ -5048,7 +5071,9 @@ void System::UpdateMemorySaveStateSettings()
50485071
num_slots = g_settings.rewind_save_slots;
50495072

50505073
u64 ram_usage, vram_usage;
5051-
CalculateRewindMemoryUsage(g_settings.rewind_save_slots, g_settings.gpu_resolution_scale, &ram_usage, &vram_usage);
5074+
CalculateRewindMemoryUsage(g_settings.rewind_save_slots, g_settings.gpu_resolution_scale,
5075+
g_settings.gpu_multisamples, g_settings.gpu_use_software_renderer_for_memory_states,
5076+
g_settings.cpu_enable_8mb_ram, &ram_usage, &vram_usage);
50525077
INFO_LOG("Rewind is enabled, saving every {} frames, with {} slots and {}MB RAM and {}MB VRAM usage",
50535078
std::max(s_state.rewind_save_frequency, 1), g_settings.rewind_save_slots, ram_usage / 1048576,
50545079
vram_usage / 1048576);

0 commit comments

Comments
 (0)