Vixen
dd8b0a81
csharp
public sealed class PageResidency

One page-residency service: requests in, bytes in the pool, least-recently-used out.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

Improvement 6 of docs/plan/22-virtualized-geometry.md, and the reason it is built in phase 2 rather than phase 7. Geometry pages want this; so do texture mip tails (docs/plan/08) and the virtual shadow map's pages (phase 7). Building it with one consumer in view is how it becomes geometry-shaped and the other two grow their own — and then there are three budgets to tune, which means there is no budget at all.

The budget is a hard ceiling, and that is the criterion the phase is judged on. A scene four times over budget has to hold the budget, which means a request that cannot be satisfied without evicting something is either satisfied by evicting something or not satisfied. It is never satisfied by going over — the point of a pool is that its size is known in advance, and a manager that treats its budget as a target is a manager that reports a number nobody can plan against.

Requests are demand-driven and serviced newest first; the remainder stays queued. What asks for a page is the traversal, per frame, from what it actually wanted to draw — so a request from three frames ago is about a camera that has moved, and Service reads the queue from the newest end and stops at its load budget. What it does not do is throw the rest away, because a stack is only ever read from the top: an old request costs nothing until the queue has drained, and the frame that drains it is by definition a frame with I/O to spare. Dropping it instead would lose every page whose only asker asks once, which is the failure mode pinning exists to rule out and is not worth reintroducing for requests.

What a queue may not do is grow without bound, so it is capped at MaxPendingRequests and the oldest go first — and a camera that jumped has a queue about somewhere it is not, which is ClearRequests' business. The service cannot see a cut; whoever moved the camera can.

Pinned pages are never evicted and never counted against the request queue. A mesh's root page is pinned, which is what makes an object draw at its coarsest level rather than not at all — the guarantee the whole degradation story rests on. Pinned bytes do count against the budget, because they are bytes — and a pinned working set larger than the budget is a pool that cannot hold what it has been promised, which Pin refuses by name with PageBudgetException rather than discovering one page at a time in a frame that reports nothing.

Fields and properties (13)

  • public long Budget

    How many bytes may be resident at once.

  • public long ResidentBytes

    How many are.

  • public int ResidentPages

    How many pages are.

  • public int PinnedPages

    How many are pinned, and therefore cannot be evicted to make room.

  • public long Loads

    How many pages have been loaded since this was created.

  • public long Evictions

    How many have been evicted.

  • public long Rejections

    How many requests were dropped because nothing could be evicted to make room.

  • public long PinRefusals

    How many times a pinned page was queued and could not be given a slot.

  • public long StaleRequests

    How many queued requests were dropped for being older than the queue's cap.

  • public int MaxPendingRequests

    How many requests may wait before the oldest are dropped.

  • public ILogger? Logger

    Where refusals are reported, or null for a service nobody is watching.

  • public int Loading

    How many pages are on their way and not yet in a slot.

  • public int PendingRequests

    How many requests are waiting.

Methods (11)

  • public PageResidency(IPageStore store, long budget)

    Creates a service over a pool.

  • public bool IsResident(PageKey key)

    Whether a page's bytes are in the pool.

  • public bool TryGetPlacement(PageKey key, out PagePlacement placement)

    Where a resident page is, if it is.

  • public void Touch(PageKey key)

    Says a page was used this frame, so it is not the one evicted next.

  • public void Request(PageKey key)

    Asks for a page, if it is not already resident or on its way.

  • public void Pin(PageKey key)

    Pins a page, so it is loaded and then never evicted.

  • public void Unpin(PageKey key)

    Unpins a page, making it evictable again.

  • public bool Drop(PageKey key)

    Gives a page's slot back now: unpinned, unqueued, evicted if it was resident.

  • public int Service(int maxLoads = 8)

    Services the queue: places what has arrived, and starts what there is room for.

  • public void ClearRequests()

    Drops every request that has not been started, without touching what is resident.

  • public void Dispose()

    Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Used by (19)

  • ArenaThirdPersonShooter
  • ThirdPersonShooterGameThirdPersonShooter
  • VirtualGeometryGameVirtualGeometry
  • FoliageStreamerVixen.Rendering.Terrain
  • GpuClusterVisibilityVixen.Rendering
  • MeshletStreamingTestsVixen.Rendering.Tests
  • PageResidencyTestsVixen.Rendering.Tests
  • StreamingGridVixen.Rendering
  • StreamingGridTestsVixen.Rendering.Tests
  • TerrainStreamerVixen.Rendering.Terrain
  • TextureStreamerVixen.Engine.Renderer
  • VirtualGeometryContentTestsVixen.Rendering.Tests
  • VirtualGeometryDeviceTestsVixen.Graphics.Golden.Tests
  • VirtualGeometryFrameTestsVixen.Rendering.Tests
  • VirtualGeometryGoldenTestsVixen.Graphics.Golden.Tests
  • VirtualGeometrySystemVixen.Rendering
  • VirtualShadowAtlasVixen.Rendering
  • VirtualShadowPageTestsVixen.Rendering.Tests
  • VirtualShadowRendererTestsVixen.Rendering.Tests