fix(host): room in the drivers' shader caches for the prepared pipelines (Linux) #2033

Merged
hckrman101 merged 1 commit from driver-cache-room into main 2026-11-11 00:48:10 +00:00
hckrman101 commented 2026-11-11 00:37:06 +00:00 (Migrated from github.com)

The preparation builds its predicted pipelines into the driver's own shader cache only. On Linux, NVIDIA's cache is capped at 1 GiB by default, and a full preparation needs about 1.8 GB. So the driver throws away close to half of what the preparation just built, and play compiles it again. This raises the cap for the game process.

What changes

  • Linux (host/hos_main.c): the game process gets __GL_SHADER_DISK_CACHE_SIZE=10737418240 (NVIDIA) and MESA_SHADER_CACHE_MAX_SIZE=10G (Mesa: RADV, ANV) before anything loads Vulkan. Mesa's default is also 1 GiB.
    • Both use setenv(..., 0), so a value the player set, or one from hookshot_env.txt, is kept.
    • The setting covers this process only, not the system.
  • Windows: the NVIDIA driver reads its cache size from the control panel, and a program can't set it. The readme's troubleshooting table gets a row: set Shader Cache Size to Unlimited (or 10 GB).
  • Test: tests/test_driver_cache_room.py checks that both variables are set without overwriting, that the NVIDIA size is at least 4 GiB, and that this happens before the window (SDL) can load Vulkan.

Why the pipelines go missing

predict_run builds the predicted pipelines with driver_cache_only, so they are kept only in the driver's cache, not in mkw_vk_pipelines.bin. That is deliberate: our own cache file is read in whole at every start. It means the driver cache has to be big enough to hold them.

Numbers

Setup: RTX 3090, Linux, NVIDIA driver, OoT 1.1.1, a full preparation from an empty driver cache. That is 43,414 predicted pipelines plus 1,261 listed ones and 9,925 compute pipelines.

Run Predicted pipelines built Noted + compute pipelines Driver cache afterwards
Default cap, first preparation 320 s 226 s 1026 MB (at the cap)
Default cap, second preparation 72.6 s (whole run 96 s) 5.8 s 1820 MB
10 GiB, first preparation 408 s (on a busier PC) 124 s 1818 MB
10 GiB, second preparation 7.9 s (whole run 28.1 s) 1.2 s 1818 MB (nothing added)
  • With room to grow, one preparation writes about 1.8 GB.
  • With the default cap it stopped at 1026 MB: roughly 790 MB of it, about 45%, was thrown away.
  • The second preparation under the default cap is not near zero (72.6 s) because it builds again what was dropped. Without this change, play would build those instead.
  • With 10 GiB, the second preparation found everything in the driver's cache: 7.9 s for the 43,414 predicted pipelines, against 72.6 s under the default cap. The cache did not grow, because nothing had to be built again. Peak memory was 3.3 GB.

Not tested

  • Windows: only the readme row.
  • AMD and Intel on Mesa: the variable is set, but the effect was not measured.
The preparation builds its predicted pipelines into the driver's own shader cache only. On Linux, NVIDIA's cache is capped at 1 GiB by default, and a full preparation needs about 1.8 GB. So the driver throws away close to half of what the preparation just built, and play compiles it again. This raises the cap for the game process. ## What changes - **Linux (`host/hos_main.c`):** the game process gets `__GL_SHADER_DISK_CACHE_SIZE=10737418240` (NVIDIA) and `MESA_SHADER_CACHE_MAX_SIZE=10G` (Mesa: RADV, ANV) before anything loads Vulkan. Mesa's default is also 1 GiB. - Both use `setenv(..., 0)`, so a value the player set, or one from `hookshot_env.txt`, is kept. - The setting covers this process only, not the system. - **Windows:** the NVIDIA driver reads its cache size from the control panel, and a program can't set it. The readme's troubleshooting table gets a row: set **Shader Cache Size** to **Unlimited** (or 10 GB). - **Test:** `tests/test_driver_cache_room.py` checks that both variables are set without overwriting, that the NVIDIA size is at least 4 GiB, and that this happens before the window (SDL) can load Vulkan. ## Why the pipelines go missing `predict_run` builds the predicted pipelines with `driver_cache_only`, so they are kept only in the driver's cache, not in `mkw_vk_pipelines.bin`. That is deliberate: our own cache file is read in whole at every start. It means the driver cache has to be big enough to hold them. ## Numbers Setup: RTX 3090, Linux, NVIDIA driver, OoT 1.1.1, a full preparation from an empty driver cache. That is 43,414 predicted pipelines plus 1,261 listed ones and 9,925 compute pipelines. | Run | Predicted pipelines built | Noted + compute pipelines | Driver cache afterwards | |---|---|---|---| | Default cap, first preparation | 320 s | 226 s | **1026 MB (at the cap)** | | Default cap, second preparation | 72.6 s (whole run 96 s) | 5.8 s | 1820 MB | | 10 GiB, first preparation | 408 s (on a busier PC) | 124 s | **1818 MB** | | **10 GiB, second preparation** | **7.9 s** (whole run 28.1 s) | 1.2 s | 1818 MB (nothing added) | - With room to grow, one preparation writes about 1.8 GB. - With the default cap it stopped at 1026 MB: roughly 790 MB of it, about 45%, was thrown away. - The second preparation under the default cap is not near zero (72.6 s) because it builds again what was dropped. Without this change, play would build those instead. - With 10 GiB, the second preparation found everything in the driver's cache: 7.9 s for the 43,414 predicted pipelines, against 72.6 s under the default cap. The cache did not grow, because nothing had to be built again. Peak memory was 3.3 GB. ## Not tested - Windows: only the readme row. - AMD and Intel on Mesa: the variable is set, but the effect was not measured.
Arkex-ai commented 2026-11-11 01:00:16 +00:00 (Migrated from github.com)

Heads-up: the Windows display startup fixture now fails to compile because its extracted startup block calls driver_cache_room() without a declaration. I reproduced it with Windows LLVM on main f8efe057 and on both #1954 and #2035. The Windows source job shows the same error. The missing declaration is in the fixture; the Windows build is separate.

Heads-up: the Windows display startup fixture now fails to compile because its extracted startup block calls `driver_cache_room()` without a declaration. I reproduced it with Windows LLVM on main `f8efe057` and on both #1954 and #2035. The [Windows source job](https://github.com/NotRexed/Hookshot/actions/runs/42934657700/job/130241620605) shows the same error. The missing declaration is in the fixture; the Windows build is separate.
Commenting is not possible because the repository is archived.
No description provided.