mirror of
https://github.com/libretro/tyrquake.git
synced 2026-11-07 04:35:58 -10:00
libretro: size the Quake hunk from frontend-reported free memory
The hunk was a fixed compile-time size (DEFAULT_MEMSIZE_MB, 8/24/32/64 MB depending on platform and whether the Vulkan RHI is built). That is a blunt instrument: too small and large mods hit Hunk_Alloc failures or thrash Cache_FreeLow; too large and constrained targets over-commit. Add an experimental environment callback, RETRO_ENVIRONMENT_GET_MEMORY_STATUS, that reports the frontend's free and total physical memory (bytes), and use it to size the hunk to the running machine. We take at most a quarter of the reported free memory, cap it at 256 MB (ample for the biggest Quake mods, and lazily committed so the reservation is cheap on virtual-memory platforms), and only ever grow above the per-platform default - never below it. The value is treated as an advisory snapshot, not a licence to allocate everything, since "free" can include reclaimable cache. Frontends that do not implement the query return false; in that case the core keeps the exact defaults it uses today, so behaviour is unchanged anywhere the callback is absent. The matching frontend side is a separate RetroArch change wiring the call to frontend_driver_get_free_memory().
This commit is contained in:
1 parent
ff36964795
commit
8f1e7dcdcd
2 files changed
+66
No files matched your search
@@ -134,6 +134,16 @@ static bool libretro_supports_bitmasks = false;
|
||||
#define DEFAULT_MEMSIZE_MB 64
|
||||
#endif
|
||||
|
||||
/* Bounds for frontend-driven hunk sizing via
|
||||
* RETRO_ENVIRONMENT_GET_MEMORY_STATUS: take at most 1/4 of the memory the
|
||||
* frontend reports free, cap it, and never shrink below the per-platform
|
||||
* DEFAULT_MEMSIZE_MB chosen above. The cap keeps the reservation sane on
|
||||
* desktops with gigabytes free while still covering the largest mods; the
|
||||
* floor preserves the current tuned behaviour on constrained targets and
|
||||
* on any frontend that cannot answer the query. */
|
||||
#define HUNK_FREE_SHIFT 2 /* free >> 2 == a quarter of reported free RAM */
|
||||
#define HUNK_MAX_MB 256u /* upper bound; ample for the biggest Quake mods */
|
||||
|
||||
/* Use 44.1 kHz by default (matches CD
|
||||
* audio tracks) */
|
||||
#define AUDIO_SAMPLERATE_DEFAULT 44100
|
||||
@@ -1321,6 +1331,32 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
parms.basedir = g_rom_dir;
|
||||
parms.savedir = g_save_dir;
|
||||
parms.use_exernal_savedir = use_external_savedir ? 1 : 0;
|
||||
|
||||
/* Size the Quake hunk from the memory the frontend actually has, when it
|
||||
* can tell us. We only ever grow above the default and clamp hard, so a
|
||||
* frontend that does not implement the query (returns false) keeps the
|
||||
* compile-time default computed above. */
|
||||
{
|
||||
struct retro_memory_status memstat;
|
||||
memstat.free = memstat.total = 0;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_MEMORY_STATUS, &memstat) && memstat.free)
|
||||
{
|
||||
unsigned free_mb = (unsigned)(memstat.free / (1024 * 1024));
|
||||
unsigned budget = free_mb >> HUNK_FREE_SHIFT;
|
||||
if (budget > HUNK_MAX_MB)
|
||||
budget = HUNK_MAX_MB;
|
||||
if (budget > MEMSIZE_MB)
|
||||
MEMSIZE_MB = budget;
|
||||
log_cb(RETRO_LOG_INFO,
|
||||
"Frontend reports %u MB free; sizing Quake hunk to %u MB.\n",
|
||||
free_mb, MEMSIZE_MB);
|
||||
}
|
||||
else
|
||||
log_cb(RETRO_LOG_INFO,
|
||||
"Frontend has no memory-status query; using default %u MB hunk.\n",
|
||||
MEMSIZE_MB);
|
||||
}
|
||||
|
||||
parms.memsize = MEMSIZE_MB * 1024 * 1024;
|
||||
argv[0] = empty_string;
|
||||
|
||||
|
||||
@@ -2643,6 +2643,36 @@ enum retro_mod
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_AUDIO_SAMPLE_BATCH_FLOAT (85 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/**
|
||||
* Queries how much system memory the frontend has available.
|
||||
*
|
||||
* A core may use this to size large internal allocations (a memory pool,
|
||||
* heap or asset cache) to the running machine instead of to a fixed
|
||||
* compile-time default. The reported values are advisory snapshots: \c free
|
||||
* in particular may include reclaimable cache and can change immediately
|
||||
* after the call, so a core should take a fraction of it and clamp the
|
||||
* result -- it must never assume it can allocate the whole amount.
|
||||
*
|
||||
* Frontends that do not implement this return \c false, in which case the
|
||||
* core is expected to fall back to its own defaults.
|
||||
*
|
||||
* @param[out] data <tt>struct retro_memory_status *</tt>.
|
||||
* @return \c true if the frontend filled in the structure, \c false otherwise.
|
||||
* @see retro_memory_status
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_MEMORY_STATUS (86 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/**
|
||||
* Result of \c RETRO_ENVIRONMENT_GET_MEMORY_STATUS.
|
||||
*
|
||||
* Sizes are in bytes; a field the frontend cannot determine is left at 0.
|
||||
*/
|
||||
struct retro_memory_status
|
||||
{
|
||||
uint64_t free; /**< Physical memory currently available to allocate. */
|
||||
uint64_t total; /**< Total physical memory installed. */
|
||||
};
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user