mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Keep released textures the game takes back intact for as long as their longest release, not 120 presents.
Once the released entries pass RELEASED_MAX, the sweep dropped an entry that comes back intact as soon as its 120 presents were up. Kakariko releases the ASTC textures of its hazy air and takes them back every few hundred frames, so about 30 of them went each time, and the frame that needed one again sampled its stand-in while it was made and uploaded anew. Such an entry now waits out GAP_TIMES the longest it stayed released before a take-back, as an entry whose content lives only in its image does. NX2NAVI_TEX_KEEP_TAKEN=0 goes back to the old rule, and NX2NAVI_TEX_RELEASED_MAX (a test) lowers the count from which the sweep starts, so a short run reaches it. The haze still dropped out with this alone: most of those frames came from finalized slots, which the next commit deals with. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,7 +58,7 @@ static const char *const known[] = {
|
||||
"MENU_CURSOR", "MENU_CURSOR_LOG", "MENU_TEST_CLICK", "MENU_TEST_DIR", "MENU_TEST_SET", "MINIMAL_LAYOUT", "MICROPHONE", "MIRROR_GAP", "MODS_DIR", "MODS_DISABLED", "MODS_ORDER", "MODS_REBUILD", "MONITOR", "MOTION", "MOUSE_MODE", "MOUSE_DIRECT_PATCH", "MOUSE_SENS", "MOUSE_TRACE", "MOVIE_HOST", "MOVIE_PACE", "MOVIE_CLOCK", "TEST_HITCH",
|
||||
"MVOBJ_ALL", "MVOBJ_BANKS", "MVOBJ_EQUAL", "MVOBJ_EXACT", "MVOBJ_EXEC", "MVOBJ_NOC4", "MVOBJ_ONLY", "MVOBJ_TIMES", "MVPREV_CHECK", "MVPREV_GROW", "MVPREV_SKIP", "MVPREV_TRUST", "MV_CHECK",
|
||||
"MV_SURVEY",
|
||||
"ONE_PER_CORE", "OPERATION_MODE", "OUTPUT_RES", "PAD_LAYOUT", "PACE_HZ", "PASS_CRUMBS", "PATCH_OUTPUT", "PATCH_RES_FIXED", "PATCH_SCENE", "PATCH_WIDE_ASPECT", "PATCH_WIDE_HUD", "PATCH_WIDE_MOVIE", "PATCH_WIDE_OUT", "PATCH_FREECAM", "PATCH_WIDE_SCENE", "PCSS", "PCSS_K", "PERF_OVERLAY", "PERF_SLOW_MS", "PIPELINE_CACHE", "PIPELINE_CACHE_MAX_MB", "PIPELINE_CACHE_PLAY", "PIPELINE_CACHE_PLAY_MB", "PIPE_BINARIES", "PIPE_BINARIES_MAX_MB", "PIPE_FEEDBACK", "PIPE_MEMO", "PIPE_PREBUILD", "PIPE_SKIP", "PIPE_SYNC", "PIPE_WAIT", "POWER_FULL", "TEX_SAME", "TEX_FLAT3D", "PRESENT_HELD", "HELD_SYNC",
|
||||
"ONE_PER_CORE", "OPERATION_MODE", "OUTPUT_RES", "PAD_LAYOUT", "PACE_HZ", "PASS_CRUMBS", "PATCH_OUTPUT", "PATCH_RES_FIXED", "PATCH_SCENE", "PATCH_WIDE_ASPECT", "PATCH_WIDE_HUD", "PATCH_WIDE_MOVIE", "PATCH_WIDE_OUT", "PATCH_FREECAM", "PATCH_WIDE_SCENE", "PCSS", "PCSS_K", "PERF_OVERLAY", "PERF_SLOW_MS", "PIPELINE_CACHE", "PIPELINE_CACHE_MAX_MB", "PIPELINE_CACHE_PLAY", "PIPELINE_CACHE_PLAY_MB", "PIPE_BINARIES", "PIPE_BINARIES_MAX_MB", "PIPE_FEEDBACK", "PIPE_MEMO", "PIPE_PREBUILD", "PIPE_SKIP", "PIPE_SYNC", "PIPE_WAIT", "POWER_FULL", "TEX_SAME", "TEX_FLAT3D", "TEX_KEEP_TAKEN", "TEX_RELEASED_MAX", "PRESENT_HELD", "HELD_SYNC",
|
||||
"PREPARE_PIPELINES", "PREWARM_FULL", "PREWARM_WAIT_MS", "PREWARM_XLATE", "PROBE_MOVIE", "PROBE_MOVIE_SHOT", "PROFILE", "PROFILE_CHAINS", "PROFILE_DIR", "PROFILE_FRAMES", "PROFILE_REPLAY", "PROFILE_SLOW",
|
||||
"POOL_FAST", "POOL_GROUP", "POOL_GROUP_CHECK", "POOL_PRESNAP",
|
||||
"PROFILE_MAIN", "PROFILE_RENDER", "PROMPTS", "PUSH_SKIP", "PUSH_STAGE", "RDOC", "RDOC_DIR", "RDOC_DLL", "REALTIME", "REC_END", "REEXEC",
|
||||
|
||||
@@ -1951,14 +1951,26 @@ static int others_at(char *out, size_t n, const Tex *e, const Tex *skip) {
|
||||
// the others is bounded by NX2NAVI_TEX_RELEASED_MB (drop_stale).
|
||||
// Each call looks at up to SWEEP_LOOK entries from where the last one stopped (sweep_at; rel_unlink moves it off an
|
||||
// entry that leaves): with thousands of entries that stay, a walk from the head at every release would cross them all.
|
||||
#define RELEASED_MAX 2048
|
||||
#define RELEASED_MAX_DEFAULT 2048
|
||||
#define RELEASED_HARD 16384
|
||||
// NX2NAVI_TEX_RELEASED_MAX (test; default RELEASED_MAX_DEFAULT): the count from which released entries are swept, so a
|
||||
// short run reaches the sweep a long session reaches after minutes.
|
||||
static int released_max_v = -1;
|
||||
#define RELEASED_MAX (released_max_v)
|
||||
#define SWEEP_LOOK 64
|
||||
#define SWEEP_UNSAMPLED PRESENTS(120)
|
||||
|
||||
static int comes_back_intact(const Tex *e);
|
||||
|
||||
static uint64_t stale_after(const Tex *e);
|
||||
|
||||
static void sweep_released(void) {
|
||||
if (released_max_v < 0) {
|
||||
const char *t = cfg_get("NX2NAVI_TEX_RELEASED_MAX");
|
||||
int v = t && *t ? atoi(t) : 0;
|
||||
released_max_v = v > 0 ? v : RELEASED_MAX_DEFAULT;
|
||||
if (v > 0) rt_log("vk: released textures are swept from %d on (NX2NAVI_TEX_RELEASED_MAX, a test)", v);
|
||||
}
|
||||
if (nreleased <= RELEASED_MAX) return;
|
||||
{
|
||||
uint64_t now = frames_now();
|
||||
@@ -1967,7 +1979,8 @@ static void sweep_released(void) {
|
||||
for (int n = 0; n < SWEEP_LOOK && nreleased > RELEASED_MAX; n++) {
|
||||
if (!e || now - e->rel_frame < stale) { e = rel_head; break; } // the rest is younger: from the oldest again
|
||||
Tex *next = e->rel_next;
|
||||
if (comes_back_intact(e) || e->overwritten) drop_tex(e, DROP_MAX);
|
||||
// an entry the game took back before waits out GAP_TIMES the longest of those releases (stale_after)
|
||||
if ((comes_back_intact(e) || e->overwritten) && now - e->rel_frame >= stale_after(e)) drop_tex(e, DROP_MAX);
|
||||
e = next;
|
||||
}
|
||||
sweep_at = e;
|
||||
@@ -2208,9 +2221,23 @@ static int idle(const Tex *e, uint64_t now) {
|
||||
return look_round - e->use_round >= IDLE_ROUNDS && now - e->use_frame >= STALE_FRAMES;
|
||||
}
|
||||
|
||||
// NX2NAVI_TEX_KEEP_TAKEN (default 1; 0: as before): an entry that comes back intact waits out GAP_TIMES the longest it
|
||||
// stayed released before the game took it back, as one whose content lives only in its image does, and not
|
||||
// STALE_FRAMES alone. Coming back intact is not free: the descriptor finds no entry, the frame samples its stand-in
|
||||
// while the entry is made and uploaded again, and the next frame has it. Kakariko's hazy air is drawn with ASTC
|
||||
// textures the game releases and takes back every few hundred frames; with the released entries at RELEASED_MAX the
|
||||
// sweep dropped about 30 of them as soon as their 120 presents were up, and the frame that needed them again came out
|
||||
// without the haze, darker and sharper, once every few seconds.
|
||||
static int keep_taken(void) {
|
||||
static int on = -1;
|
||||
if (on < 0) on = rt_knob("TEX_KEEP_TAKEN", "1") == 1;
|
||||
return on;
|
||||
}
|
||||
|
||||
static uint64_t stale_after(const Tex *e) {
|
||||
if (comes_back_intact(e) || e->overwritten) return STALE_FRAMES;
|
||||
uint64_t gap = (uint64_t)e->back_gap * GAP_TIMES;
|
||||
if (e->overwritten) return STALE_FRAMES;
|
||||
if (comes_back_intact(e)) return keep_taken() && gap > STALE_FRAMES ? gap : STALE_FRAMES;
|
||||
return gap > GPU_STALE_FRAMES ? gap : GPU_STALE_FRAMES;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user