mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
The cache kept the first eight sizes and formats for the whole run and refused every other one, so after a few window, resolution or DLSS mode changes the stand-in's blit of a new size was left out, while the old sizes' images stayed. A new size now takes a free entry or the one used longest ago, whose image goes through the deferred destruction after the tonemap pass drops its views of it (vk_tonemap_forget), before another image can take its handle. tests/scratch_lru_check.py checks the choice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.8 KiB
C
39 lines
1.8 KiB
C
// Which entry of a small cache of scratch images serves a request for an image of one size and format
|
|
// (vk_exec_draw.c fallback_scratch). Header only, so that tests/scratch_lru_check.c checks it without a device.
|
|
//
|
|
// The cache held its first SCRATCH_N images for the whole run and refused every other size: each scene size the
|
|
// stand-in of the game's upscaler blits through takes one, and after a run of window, resolution or DLSS mode
|
|
// changes the blit of a new size found no image and was left out. Now a request that matches no live entry takes a
|
|
// free one, else the one used longest ago, which the caller frees (deferred: a submission may still name it) before
|
|
// it makes the new image there. The images in use stay; one used in no frame for a while is what goes.
|
|
#pragma once
|
|
#include <stdint.h>
|
|
|
|
typedef struct {
|
|
uint32_t w, h, f; // the image's size and format (VkFormat)
|
|
uint64_t used; // the frame of its last request
|
|
int live; // holds an image
|
|
} ScrEntry;
|
|
|
|
// The entry for (w, h, f) among e[0..n-1]: a live match (*hit 1), else a free entry, else the live one used longest ago
|
|
// (*evict 1: its image is to be freed before the slot is reused). A hit's used becomes now; the caller fills a new
|
|
// entry once its image is made.
|
|
static inline int scr_pick(ScrEntry *e, int n, uint32_t w, uint32_t h, uint32_t f, uint64_t now, int *hit, int *evict) {
|
|
int free_at = -1, lru = -1;
|
|
*hit = *evict = 0;
|
|
for (int i = 0; i < n; i++) {
|
|
if (!e[i].live) {
|
|
if (free_at < 0) free_at = i;
|
|
continue;
|
|
}
|
|
if (e[i].w == w && e[i].h == h && e[i].f == f) {
|
|
e[i].used = now, *hit = 1;
|
|
return i;
|
|
}
|
|
if (lru < 0 || e[i].used < e[lru].used) lru = i;
|
|
}
|
|
if (free_at >= 0) return free_at;
|
|
*evict = 1;
|
|
return lru;
|
|
}
|