Skip to content

niivue: cap the chunked working set against combined-overlay mirror budgets #188

Description

@cdrake

Summary

The chunked working-set cap is computed once from the base volume's residency budget and then the same chunk indices are requested from every combined-overlay mirror. Combined overlays get a smaller budget (OVERLAY_RESIDENCY_FRACTION of the base budget, divided by overlay count), so the capped set can exceed what a mirror can hold. Because every capped chunk is stamped needed-this-frame, the same-frame eviction guard stops the mirror from shedding any of them, and it stays over budget.

Where

Both backends, in the frustum and slice working-set paths:

  • packages/niivue/src/gl/render.ts: _requestChunksInFrustum and _requestVisibleChunksInView call chunkIndicesForResidentBudget(entry.plan, ordered, entry.manager.budgetBytes, ...) and then for (const m of mirrors) m.requestUpload(ci).
  • packages/niivue/src/wgpu/render.ts: same structure.

The budget split is in _updateCombinedOverlayChunked.

Proposed fix

Cap against the tightest participating manager before mirroring: run chunkIndicesForResidentBudget for the base and for each mirror (each with its own budgetBytes and its own getChunk(ci)?.hasGradient pricing), and request the intersection, or the shortest prefix of ordered that fits all of them. Add a ChunkResidencyManager test with one mirror at a fraction of the base budget and assert the mirror never exceeds budgetBytes after a frame that touches every capped chunk.

Context

Pre-existing on main; surfaced by Copilot's review of #167, which changed only the per-chunk price (4 bytes/voxel for unlit chunks) and not the mirroring. The ratio between the capped set and a mirror's budget is unchanged by #167 because mirrors share the renderer's lighting state.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions