Skip to content

Cache texture LOD requests per mesh across frames - #125

Open
JohnGreenFC wants to merge 2 commits into
mainfrom
optimization-texture-lod-request-cache
Open

JohnGreenFC wants to merge 2 commits into
mainfrom
optimization-texture-lod-request-cache

Conversation

@JohnGreenFC

Copy link
Copy Markdown

Summary

Goal: stop re-deriving the same texture LOD requests for every visible mesh every frame. The requests a mesh issues depend only on its on-screen size and the textures bound by its materials, and for most meshes neither changes from one frame to the next, yet the full material walk ran each frame regardless. This change remembers the result of one walk together with the range of screen sizes over which it stays valid, and replays it until the mesh leaves that range or a texture changes.

1. The cache (Tr2ScreenSizeRequests, Tr2MeshBase::UseWithScreenSize).
Each mesh keeps one Tr2ScreenSizeRequests: the list of (texture, LOD) pairs its last material walk requested, plus a [minScreenSize, maxScreenSize) interval. On a hit (same geometry, mesh LOD, world radius and generation, and the screen size inside the interval) the mesh replays the requests directly on the textures and returns. On a miss it re-walks its material areas through UsedWithScreenSize, which fills the request list. A miss counter is kept (Trinity/Mesh/screenSizeRequestCacheMisses); misses are rare in practice.

2. The validity interval (TriTextureParameter::RequestLod).
A texture's requested LOD only changes when screen size divided by the material's UV density crosses a power of two of the texture resolution. While computing a request, each texture parameter narrows the interval to the band in which its own LOD stays the same (with a small epsilon on either side), so the interval is the intersection over all textures in the mesh. A parameter whose request cannot be bounded that way marks the entry invalid, so that mesh re-walks every frame as before.

3. Invalidation.
A global generation counter is bumped whenever a cached request could go stale: a texture parameter is initialised, assigned a new resource or path, a texture finishes loading or is destroyed, or an effect's loddable parameters are rebuilt or released. Any mesh whose cache was built under an older generation misses once and rebuilds.

Also removes an unused bounds computation in EveChildMesh::UpdateVisibility (an animated-bounds query whose result was never read). Toggle: meshScreenSizeRequestCache.

Linked issue (optional)

Testing

Windows, DX12, release build. Measured in the EVE Frontier client on the QA Megastructure route (1080p, low preset) against origin/main: about -0.3 ms frame mean with raytraced shadows and -0.4 ms with cascaded shadows (single flights, ~0.5 ms noise band). Smoke test of this branch alone: full route flown with raytraced shadows, no frames over 100 ms, no crash dumps. Not built on Mac.

AI assistance

AI testing, investigation and CL explanation

Remove unused bounds computation in EveChildMesh::UpdateVisibility.
Copilot AI balanced review requested due to automatic review settings October 16, 2026 12:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JohnGreenFC
JohnGreenFC marked this pull request as ready for review October 16, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants