mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 13:52:23 +00:00
Cull: skip cullAndUploadVisible + HiZ on still frames
render() was re-running the full cull every 16 ms timer tick even when nothing had changed — the camera matrices, scene state, and therefore visible set were all identical to the previous frame's. The GPU was still happy to redraw from the cached indirect buffer, but the CPU was burning 21 ms/frame rebuilding the same visible list. Detect the no-op case by comparing view/proj against last_cull_view_ / last_cull_proj_ and checking a scene-dirty flag (have_cached_cull_) that every mutator on models_gpu_ invalidates — finalizeModel, applyCachedModel, applyLodExtension, hide/show/remove/reset, and uploadInstanceChunk. When the check passes we skip both cullAndUploadVisible and buildHizPyramid (the depth buffer is bit-identical, so re-reading it produces the same pyramid). Per-model visible_objects / visible_triangles stats now live on ModelGpuData so the stats line reports correct numbers on skipped frames instead of reading from a stale indirect_scratch_. Measured on a 569k-object overview: still frames go 22 fps → 62 fps; orbiting goes 23 fps → ~30-50 fps depending on how hard you move the mouse (the cull only pays its full cost on the ~25 % of frames where the camera actually moved). The stats line gains a "skipped N/M" field so you can see the ratio live. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,13 @@ struct ModelGpuData {
|
||||
std::vector<uint8_t> instance_reflected;
|
||||
uint32_t ssbo_instance_count = 0;
|
||||
|
||||
// Stats snapshot from the last cullAndUploadVisible call. Cached so we
|
||||
// can report the same numbers on skipped-cull frames (see
|
||||
// have_cached_cull_ on ViewportWindow) without iterating the per-model
|
||||
// scratch array again.
|
||||
uint32_t cached_visible_objects = 0;
|
||||
uint32_t cached_visible_triangles = 0;
|
||||
|
||||
// Per-instance world AABB + BVH (built at finalize). The BVH is the
|
||||
// same ordering as `instances`; bvh_items[i] corresponds to instances[i].
|
||||
std::vector<BvhItem> bvh_items;
|
||||
@@ -268,6 +275,15 @@ private:
|
||||
uint64_t cull_traverse_ns_ = 0;
|
||||
uint64_t cull_emit_ns_ = 0;
|
||||
uint64_t cull_upload_ns_ = 0;
|
||||
uint32_t cull_skipped_frames_ = 0;
|
||||
|
||||
// Skip cullAndUploadVisible + buildHizPyramid when the camera and scene
|
||||
// haven't changed since the last cull. The existing per-model
|
||||
// indirect_buffer / visible_ssbo are still correct and just get
|
||||
// redrawn. Invalidated by any function that mutates models_gpu_.
|
||||
QMatrix4x4 last_cull_view_;
|
||||
QMatrix4x4 last_cull_proj_;
|
||||
bool have_cached_cull_ = false;
|
||||
|
||||
// Per-frame stats
|
||||
uint32_t visible_triangles_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user