diff --git a/common/HostSys.h b/common/HostSys.h index b41581a7d1..f79c36fb70 100644 --- a/common/HostSys.h +++ b/common/HostSys.h @@ -181,6 +181,10 @@ private: extern u64 GetTickFrequency(); extern u64 GetCPUTicks(); extern u64 GetPhysicalMemory(); +#ifdef _WIN32 +// TODO: Someone do linux/mac. +extern u64 GetAvailablePhysicalMemory(); +#endif /// Spin for a short period of time (call while spinning waiting for a lock) /// Returns the approximate number of ns that passed extern u32 ShortSpin(); diff --git a/common/Windows/WinMisc.cpp b/common/Windows/WinMisc.cpp index 3cbdc201d0..b7bdb89d24 100644 --- a/common/Windows/WinMisc.cpp +++ b/common/Windows/WinMisc.cpp @@ -57,6 +57,14 @@ u64 GetPhysicalMemory() return status.ullTotalPhys; } +u64 GetAvailablePhysicalMemory() +{ + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx(&status); + return status.ullAvailPhys; +} + // Calculates the Windows OS Version and processor architecture, and returns it as a // human-readable string. :) std::string GetOSVersionString() diff --git a/pcsx2/CDVD/ThreadedFileReader.cpp b/pcsx2/CDVD/ThreadedFileReader.cpp index 4a1b5828e0..550b2794a7 100644 --- a/pcsx2/CDVD/ThreadedFileReader.cpp +++ b/pcsx2/CDVD/ThreadedFileReader.cpp @@ -266,10 +266,26 @@ bool ThreadedFileReader::Precache2(ProgressCallback* progress, Error* error) bool ThreadedFileReader::CheckAvailableMemoryForPrecaching(u64 required_size, Error* error) { +#ifdef _WIN32 + // We want to check available physical memory instead of total. + const u64 memory_available = GetAvailablePhysicalMemory(); + // Reserve 2GB of available memory for headroom. + constexpr u64 memory_reserve = 2147483648; + const u64 max_precache_size = std::max(0LL, static_cast(memory_available - memory_reserve)); + + if (required_size > max_precache_size) + { + Error::SetStringFmt(error, + TRANSLATE_FS("CDVD", "Not enough free memory available for precaching, ({}GB) required."), + (required_size + memory_reserve) / _1gb); + return false; + } +#else // Don't allow precaching to use more than 50% of system memory. // Hopefully nobody's running 2-4GB potatoes anymore.... const u64 memory_size = GetPhysicalMemory(); const u64 max_precache_size = memory_size / 2; + if (required_size > max_precache_size) { Error::SetStringFmt(error, @@ -277,6 +293,7 @@ bool ThreadedFileReader::CheckAvailableMemoryForPrecaching(u64 required_size, Er required_size / _1gb, max_precache_size / _1gb); return false; } +#endif return true; }