Caches do not hold a game launch; shader pools per game; FEX caches built on the device
Description
The FEX code cache check and the shared shader cache check both ran before the game process started, with blocking HTTP calls. On a network that is connected but dead (captive portal, server hang, weak signal) or slow, they could hold a launch for minutes. This PR removes that and changes how both caches are filled.
Shared shader cache
- The pool key is the game only. It no longer includes the DXVK and vkd3d versions. Fossilize entries are content-addressed, so one pool per game is valid across versions. The versions are still sent with an upload as optional metadata. Old pool files in a container are removed on the next launch, recording sessions written before the update still upload, and the replay stamp changes once.
- Download as a step of the game install. For Steam it runs right after the cloud save step and shows "Preparing shaders" with a percentage on the install; for GOG, Epic and Amazon it runs just before the install is marked complete. The pool is staged in app storage, because a game has no container until its first launch. The step never fails an install, and pausing or cancelling the install cancels it. Staged pools are deleted on uninstall.
- Check at app start. About 10 seconds after app start, one background request asks which installed games have a pool and at which version. Nothing is downloaded then.
- At launch. A staged pool is moved into the container locally. Then:
- if the start check covered the game and the local pool is current, or the game has no pool: no network request;
- if the pool changed: it is downloaded and installed;
- if the check did not cover the game: the launch does the lookup itself.
- Limits. The lookup waits at most 3 seconds and is abandoned, not cancelled, after that (it can include an account token refresh that must finish). A download stops at once when cancelled (
Call.executeCancellable), fails after 15 s without data, and ends after 180 s in total. - Skip button. While a pool download or the replay runs, the booting splash shows a Skip button. It ends the step and the launch continues. A skipped replay is not marked as done, so it runs on the next launch.
FEX code caches
- Built on the device. The device compiles code caches from its own code maps with the offline compiler that ships in the FEX pack. The lookup and download of server-hosted caches before launch, with its 6-hour recheck stamp, are removed.
- When. Before the game starts, as the first pre-launch step, with a "Building code cache… (i/n)" status and the Skip button. Skip stops the build and starts the game; what was not built stays pending. A build also runs in the background after a session, so the next launch usually has nothing to do; a launch stops a background build that is still running and finishes its work.
- What is rebuilt. The compiler regenerates an image's whole cache, so an image is built when it has no valid cache, or when the blocks recorded since its last build reach 10% of what the cache was built from. A FEX version or codegen setting change deletes the caches before the next start.
- Bounds. One run is limited to 10 minutes, a container's caches to 512 MB, and one compile runs at a time.
- Settings. The single "FEX code caches" toggle becomes two: "Upload FEX code maps" (on by default; keeps the old toggle's stored value) and "Use FEX code caches (experimental)" (off by default; disabled while upload is off). With "use" off, a container's built caches are deleted at its next launch. The code map upload itself is unchanged.
Failures in any of these steps never fail a launch or an install.
Device test (Odin 3, modern debug build)
- App start: one check 10 s after start ("Checked 42 games, 3 have a pool"); no pool file changed.
- Launch with a newer pool (The Forest): 21.6 MB downloaded in about 7.3 s, replay in 0.7 s, old three-part-key files removed. A second launch in the same app session made no shader cache request and no replay.
- Skip during a pool download: the launch continued within 0.5 s and no
.partfile was left. - FEX build at launch (Brotato, FEX 2611-gn-6): 5 caches, 227.6 MB, in 10.7 s; the game started with them in place.
- A normal session afterwards recorded 809 new blocks (5.7%): no rebuild after exit and none at the next launch ("Nothing to build", at most 11 ms).
- Skip during the FEX build: the game process started 1.4 s after the tap; no partial cache was left; the build completed after the session.
- A launch 2.3 s after an exit stopped the background build in 0.8 s and built before the start.
- "Use" off: the caches were deleted at launch and the game started without them. The disabled toggle did not respond to taps.
Not verified: the pool download during an install (no small uninstalled game with a server pool was on the test device), Skip during a shader replay, a launch on a dead network, any launch-time or in-game gain from the FEX caches, a 32-bit game, and a container that is not an overlay prefix.
Recording
None. Screenshots of the Skip button and the settings are in the test notes.
Type of Change
- Bug fix
- Performance / stability improvement
- Compatibility improvements
- Other (requires prior approval)
Checklist
- If I have access to
#code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed. - This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
- I have attached a recording of the change.
- I have read and agree to the contribution guidelines in
CONTRIBUTING.md.