mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Keep NVIDIA's shader disk cache beside the exe with a limit that holds the prepared set.
NVIDIA's Linux driver compiles into a disk cache in ~/.cache/nvidia, shared with every program, and a process adds at most 1 GiB to it (__GL_SHADER_DISK_CACHE_SIZE); a start that finds more than that in several files deletes the later ones. nx2navi.exe --prepare-shaders builds the 42,142 variants of game 1.1.1 in one process, about 1.5 GB: on the default limit it stored about 30,700 of them, and the first start after the preparation compiled the rest (and the pipelines built from them) again. Unless the environment sets them, the game now points __GL_SHADER_DISK_CACHE_PATH at nvidia-cache beside the exe (made here, the driver only makes GLCache inside it) and __GL_SHADER_DISK_CACHE_SIZE at 8 GiB before its first Vulkan call, as it does for Mesa's cache. The docs name both. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
chrg6
parent
03cb703e8f
commit
c9942578e1
@@ -96,6 +96,11 @@ processor can fill memory and swap until the kernel stops processes of the deskt
|
||||
On NVIDIA, start the game with `NX2NAVI_SHADOW=0` if the 3D world stays black while the HUD draws (issue #72). The
|
||||
profile, logs and settings are in the `--out` folder as on Windows.
|
||||
|
||||
On NVIDIA the driver keeps the shaders it compiled in `nvidia-cache` beside `ocarina`, not in `~/.cache/nvidia`, where
|
||||
one run adds at most 1 GiB while the preparation at the end of the build makes about 1.5 GB. The game sets the folder
|
||||
and a limit of 8 GiB itself (`__GL_SHADER_DISK_CACHE_PATH` and `__GL_SHADER_DISK_CACHE_SIZE` in the environment take
|
||||
precedence). Deleting the folder costs one slow start; `./ocarina --warm-shaders` fills it again.
|
||||
|
||||
`tools/make_appimage.py` packs this kit into one `NX2navi-Linux-<version>-x86_64.AppImage` with its own Python, for
|
||||
players without a source checkout: it checks for the packages above, installs zbic with pip on its first run, picks
|
||||
`--jobs` from the memory, builds into `~/Games/Ocarina` (or the folder given after the dump) and writes `play.sh`
|
||||
|
||||
@@ -209,6 +209,14 @@ The probes open a window, so from an SSH session they need the desktop session's
|
||||
skipped: no graphics+compute+present queue family`: on Wayland `XDG_RUNTIME_DIR=/run/user/$(id -u)
|
||||
WAYLAND_DISPLAY=wayland-1 SDL_VIDEODRIVER=wayland` (the socket name is in `$XDG_RUNTIME_DIR`), on X11 `DISPLAY=:0`.
|
||||
|
||||
NVIDIA's Linux driver compiles into a disk cache of its own. A process adds at most `__GL_SHADER_DISK_CACHE_SIZE` to it
|
||||
(1 GiB by default; at a start the files after the first are deleted while the folder is over that size), and the default
|
||||
folder, `~/.cache/nvidia`, is shared with every program. `--prepare-shaders` of game 1.1.1 builds 42,142 variants, about
|
||||
1.5 GB: on the default limit about 30,700 of them were stored and the rest compiled again at their first draw in play.
|
||||
`runtime/vk_device.c` therefore points `__GL_SHADER_DISK_CACHE_PATH` at `nvidia-cache` beside `ocarina` and the size at
|
||||
8 GiB before the first Vulkan call, each unless the environment sets it, as it does `MESA_SHADER_CACHE_DIR` for RADV. The
|
||||
folder can be deleted; `ocarina --warm-shaders` fills it again.
|
||||
|
||||
Memory: on Windows the GPU imports guest memory and `GetWriteWatch` tracks the CPU's writes to it. On Linux,
|
||||
re-protecting imported memory invalidates the driver's userptr buffer on every submit (about 1.3 ms per 16 MiB on
|
||||
amdgpu), and importing pins the pages, which drops their write protection. Each CPU-visible pool therefore gets a
|
||||
|
||||
@@ -202,7 +202,9 @@ bin/ nx2navi_xlate, hactool, ninja, libSDL3.so.0
|
||||
- The setup's temp folder is `.setup-temp` inside the install folder (`--temp` changes it): the AppImage is mounted
|
||||
read-only, and a Steam Deck's `/home` is often too full for the generated C while the game goes to the SD card.
|
||||
- The game keeps Mesa's shader cache in `mesa-cache` beside `nx2navi` unless `MESA_SHADER_CACHE_DIR` is set, for the
|
||||
same reason: RADV fills its default folder in `~/.cache` up to 1 GB.
|
||||
same reason: RADV fills its default folder in `~/.cache` up to 1 GB. NVIDIA's driver cache goes to `nvidia-cache`
|
||||
beside it with a limit of 8 GiB unless `__GL_SHADER_DISK_CACHE_PATH` or `__GL_SHADER_DISK_CACHE_SIZE` is set: the
|
||||
default limit of 1 GiB is smaller than what the shader preparation builds.
|
||||
- The window follows `LANG` for English or Russian, cancels through SIGTERM to the CLI's process group (the CLI handles
|
||||
it as Ctrl+Break on Windows) and opens the finished folder with `xdg-open`.
|
||||
- Requirements beyond Windows': Linux 6.7 or later (the write watch, `docs/building.md`) and glibc 2.34.
|
||||
|
||||
@@ -72,9 +72,37 @@ static void mesa_cache_beside_exe(void) {
|
||||
plat_setenv("MESA_SHADER_CACHE_DIR", dir);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
// NVIDIA's Linux driver keeps the pipelines it compiles in a disk cache of its own, by default in ~/.cache/nvidia,
|
||||
// shared with every program. One process adds at most __GL_SHADER_DISK_CACHE_SIZE to it (1 GiB unless set), and a start
|
||||
// that finds more than that in several files deletes the later ones. nx2navi.exe --prepare-shaders builds the 42,142
|
||||
// variants of game 1.1.1 into it in one process: with the default limit it stored about 30,700 of them and the rest
|
||||
// were compiled again by the first start after it. So unless the environment sets them, the cache goes to nvidia-cache
|
||||
// beside the exe, which nothing else writes, with a limit of NV_CACHE_BYTES. The driver makes GLCache inside that
|
||||
// folder but not the folder, so it is made here.
|
||||
#define NV_CACHE_BYTES "8589934592" // 8 GiB
|
||||
static void nvidia_cache_beside_exe(void) {
|
||||
char dir[PLAT_PATH_MAX * 2], size[32];
|
||||
if (!plat_getenv("__GL_SHADER_DISK_CACHE_PATH", dir, sizeof dir)) {
|
||||
int len = plat_exe_path(dir, sizeof dir - 16);
|
||||
char *cut = len ? plat_last_sep(dir) : NULL;
|
||||
if (cut) {
|
||||
strcpy(cut + 1, "nvidia-cache");
|
||||
plat_fs_mkdir(dir); // already there is fine
|
||||
plat_setenv("__GL_SHADER_DISK_CACHE_PATH", dir);
|
||||
}
|
||||
}
|
||||
if (!plat_getenv("__GL_SHADER_DISK_CACHE_SIZE", size, sizeof size))
|
||||
plat_setenv("__GL_SHADER_DISK_CACHE_SIZE", NV_CACHE_BYTES);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int create_instance(void) {
|
||||
vk_dlssg_early(); // DLSS Frame Generation: Streamline before any Vulkan call of the process (its slInit asks so)
|
||||
mesa_cache_beside_exe();
|
||||
#ifdef __linux__
|
||||
nvidia_cache_beside_exe();
|
||||
#endif
|
||||
const char *ext[12];
|
||||
uint32_t n_ext = (uint32_t)gfx_window_vk_extensions(ext, 7);
|
||||
const char *layers[] = {"VK_LAYER_KHRONOS_validation"};
|
||||
|
||||
Reference in New Issue
Block a user