You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current global VB/IB (PR #611) is a static packed buffer: all mesh geometry is uploaded at load time and lives in VRAM until explicitly removed. This does not scale to large scenes where total geometry exceeds the VRAM budget.
A virtual geometry streaming system replaces the static buffer with a fixed-size GPU-resident pool. Geometry pages are streamed into the pool on demand (driven by visibility and LOD) and evicted when cold. The total VRAM footprint stays within a configurable budget regardless of scene size.
Context
The global buffer design was chosen in PR #611 specifically to compose with this future system:
Phase 3 (this issue) — pool becomes a streaming arena; pages stream in/out based on visibility and budget
The free-list + deferred-compact design in Phase 1 is the correct foundation: a streaming system needs the same mechanics (free slots, fast reclaim, batch uploads). A simpler copy-on-remove design would require a full redesign at this phase.
ZEngine/ZEngine/Rendering/RenderResourceManager.h — current upload path
ZEngine/ZEngine/ECS/Components/MeshComponent.h — component that will carry StreamingState
Testing
cd Result.Darwin.arm64.Debug
# Unit tests for pool allocator and eviction policy
./ZEngine/tests/Debug/ZEngineTests --gtest_filter="GeometryPoolTest.*:StreamingManagerTest.*"# Integration: load a scene exceeding the VRAM budget, verify no crash,# verify visible meshes render, verify eviction stats are non-zero
Acceptance criteria
GeometryPool allocates and evicts pages within a fixed VRAM budget
GeometryStreamingManager uploads pages off the render thread
Render thread never stalls waiting for a streaming upload
Type
Overview
The current global VB/IB (PR #611) is a static packed buffer: all mesh geometry is uploaded at load time and lives in VRAM until explicitly removed. This does not scale to large scenes where total geometry exceeds the VRAM budget.
A virtual geometry streaming system replaces the static buffer with a fixed-size GPU-resident pool. Geometry pages are streamed into the pool on demand (driven by visibility and LOD) and evicted when cold. The total VRAM footprint stays within a configurable budget regardless of scene size.
Context
The global buffer design was chosen in PR #611 specifically to compose with this future system:
The free-list + deferred-compact design in Phase 1 is the correct foundation: a streaming system needs the same mechanics (free slots, fast reclaim, batch uploads). A simpler copy-on-remove design would require a full redesign at this phase.
Related:
ZEngine/docs/rendering-domain.md— rendering architecture overviewWhat needs to be done
1. Pool allocator for the VB/IB
Replace the current grow-to-fit buffer with a fixed-capacity ring/slab:
GeometryPoolstruct:capacity_vertices,capacity_indices, free-list of fixed-size pages (e.g. 64 KB vertex pages, 64 KB index pages)GeometryPageHandle(offset + size), not a raw offset2. Streaming manager
GeometryStreamingManager: background worker that services load/evict requestsStreamRequest { MeshUUID, LODLevel, Priority }fed by the visibility systemRRM::UpdateBufferinto the pool slotAssetManager3. Visibility-driven priority
ActorwithMeshComponentcarries aStreamingStateflag:Unloaded | Pending | Resident4. Render-side fallback
5. Budget management
streaming.max_geometry_mbin project config)GeometryPool::Stats()reports resident pages, eviction count, upload bandwidthResources
ZEngine/ZEngine/Rendering/RenderResourceManager.h— current upload pathZEngine/ZEngine/ECS/Components/MeshComponent.h— component that will carry StreamingStateTesting
Acceptance criteria
GeometryPoolallocates and evicts pages within a fixed VRAM budgetGeometryStreamingManageruploads pages off the render threadMeshComponent::StreamingStatereflects resident/pending/unloaded correctlyGeometryPool::Stats()reports budget usage and eviction countEstimated effort
2–3 weeks (pool allocator + streaming manager + render integration)