feat: add GPU LOD culling and indirect compaction#927
Conversation
SummaryThis PR implements Phase 3 of the LOD roadmap: a Vulkan compute pass that frustum/distance culls LOD candidates and compacts visible terrain/water instances into indirect draw streams. It wires the new Metadata
PR Description & ScopeThe change adds:
This matches the issue acceptance criteria: GPU culling, CPU fallback, validation mode, separate terrain/water streams, and compact MDI output. IssuesHigh
Medium
Low
SOLID Score6.5 / 10
Final AssessmentThe PR is architecturally sound and matches the feature scope, but the missing Machine Readable Verdictrequest_changes |
📋 SummaryThis PR implements Phase 3 of the LOD GPU culling roadmap: a Vulkan compute pass that frustum/distance-culls LOD candidates and compacts visible terrain/water instances into indirect draw streams. It wires the new Linked issue: Closes #918. The previous automated review identified five code issues (two High, two Medium, one Low). All of them have been fixed in the current head. However, a new Critical Vulkan buffer-usage bug was introduced in the latest revision that must be fixed before merge. 📌 Review Metadata
🔴 Critical Issues (Must Fix - Blocks Merge)✅ All previously reported critical issues have been resolved. (No critical issues were reported in the previous review.) New Critical Issue[CRITICAL] self.counters[i] = try ctx.resources.createBuffer(MAX_LOD_LEVELS * 2 * @sizeOf(u32), .storage);In self.counters[i] = try ctx.resources.createBuffer(MAX_LOD_LEVELS * 2 * @sizeOf(u32), .indirect);
|
| Principle | Score | Notes |
|---|---|---|
| Single Responsibility | 8 | Culling backend is isolated; render graph prepass is cleanly separated. |
| Open/Closed | 8 | New ILODCullingSystem extends RHI without modifying existing draw paths. |
| Liskov Substitution | 8 | CPU fallback preserves the existing renderer interface contract. |
| Interface Segregation | 8 | The ILODCullingSystem VTable is narrow and focused. |
| Dependency Inversion | 8 | World code depends on the RHI interface, not Vulkan directly. |
| Average | 8.0 | Strong architecture; minor tightness around GPU/CPU fallback sharing one projection. |
🎯 Final Assessment
Overall Confidence Score: 75%
Confidence Breakdown:
- Code Quality: 80%
- Completeness: 85%
- Risk Level: 60% (the missing
INDIRECT_BUFFER_BITis a concrete correctness risk) - Test Coverage: 70% (unit tests cover CPU validation and ABI; no GPU-driven integration test for the actual count-buffer submission)
Merge Readiness:
- All critical issues resolved
- SOLID average score >= 6.0
- Overall confidence >= 80% (blocked by critical issue)
- No security concerns
- Tests present and passing (
nix develop --command zig build testpassed)
Verdict:
MERGE WITH FIXES
The count-buffer usage bug is a one-line fix; once resolved, the PR is architecturally sound and ready to merge.
{
"reviewed_sha": "5c5765008960434c14f56aacd1852bca7e1f0a1d",
"critical_issues": 1,
"high_priority_issues": 0,
"medium_priority_issues": 1,
"overall_confidence_score": 75,
"recommendation": "MERGE WITH FIXES"
}
📋 SummaryPR #927 closes #918 (LOD GPU roadmap Phase 3). The implementation adds a dedicated Vulkan compute prepass for LOD distance/frustum culling, compacts visible terrain and water instances into indirect command streams, and adds CPU fallback thresholds plus an opt-in CPU/GPU validation mode. I verified the issue acceptance criteria are met:
All issues reported in the two prior automated reviews have been resolved. 📌 Review Metadata
🔴 Critical Issues (Must Fix - Blocks Merge)✅ All previously reported critical issues have been resolved. No new critical issues identified.
|
| Principle | Score | Notes |
|---|---|---|
| Single Responsibility | 8 | Culling backend is isolated in lod_culling_system.zig; render-graph prepass is separate; CPU fallback remains in lod_renderer.zig. |
| Open/Closed | 8 | New ILODCullingSystem extends the RHI without modifying existing draw paths. |
| Liskov Substitution | 8 | CPU fallback preserves the existing renderer interface contract. |
| Interface Segregation | 8 | ILODCullingSystem VTable is narrow and focused. |
| Dependency Inversion | 8 | World code depends on the RHI interface, not Vulkan directly. |
| Average | 8.0 | Strong architecture; minor test-suite completeness gap noted. |
🎯 Final Assessment
Overall Confidence Score: 90%
Confidence Breakdown:
- Code Quality: 90%
- Completeness: 90%
- Risk Level: 80%
- Test Coverage: 85%
Merge Readiness:
- All critical issues resolved
- SOLID average score >= 6.0
- Overall confidence >= 60%
- No security concerns
- Tests present and passing
Verdict:
MERGE
All previously reported issues are fixed, the new GPU culling path is cleanly isolated behind the RHI, tests and ReleaseFast build pass, and the implementation satisfies the #918 acceptance criteria.
{
"reviewed_sha": "726ed63d6c9ed8a720153a9ded5b374d91dbefab",
"critical_issues": 0,
"high_priority_issues": 0,
"medium_priority_issues": 0,
"overall_confidence_score": 90,
"recommendation": "MERGE"
}


Summary
Optional depth-pyramid occlusion remains deferred until the compute + MDI path is benchmarked and stable.
Closes #918
Verification
nix develop --command zig build testnix develop --command zig buildnix develop --command zig build -Doptimize=ReleaseFastZIGCRAFT_LOD_GPU_CULLING=1 ZIGCRAFT_LOD_GPU_CULLING_THRESHOLD=1 ZIGCRAFT_LOD_GPU_CULLING_VALIDATE=1 nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=5zig-out/lod-gpu-culling-smoke.json(1,383 frames, 276.59 average FPS); benchmark reported the medium-preset GPU-memory SLO breach at 2647.64 MB > 2400 MB