ifcviewer: upload per-instance world AABBs to a GPU SSBO

Scaffolding for Phase 3E (GPU compute cull).  After finalizeModel /
applyCachedModel, pack each InstanceCpu's world AABB + mesh_id +
reflection bit into a std430-friendly 32 B record and push it to a
per-model aabb_ssbo.  No consumer yet — the CPU cull still drives
rendering — but the next commits will point a compute shader at this
buffer and have it produce the visible list + indirect commands
directly on the GPU.

Cost: 32 B per instance, ~18 MB for the 569 k-instance test scene.
One-shot upload at finalize time; streaming-time appends aren't
mirrored (the CPU cull doesn't need the SSBO, and finalizeModel
rebuilds the whole thing in one go).
This commit is contained in:
Dion Moult
2026-04-16 20:51:26 +10:00
parent 0a752e09eb
commit 2f88778c9f
2 changed files with 62 additions and 0 deletions
+14
View File
@@ -94,6 +94,14 @@ struct ModelGpuData {
std::vector<BvhItem> bvh_items;
ModelBvh bvh;
// Per-instance world AABB on the GPU, 1:1 with `instances`.
// Populated at finalize / applyCachedModel. Consumed by the upcoming
// GPU-compute cull (Phase 3E); the CPU cull still reads from bvh_items.
// Layout: struct { vec3 min; uint mesh_id; vec3 max; uint flags; } = 32 B.
// `flags` bit 0 = reflected (for winding-bucket selection).
GLuint aabb_ssbo = 0;
size_t aabb_ssbo_capacity = 0; // bytes
// Dynamic visible-instance index buffer (std430, binding = 1).
// Re-uploaded each frame from visible_flat_.
GLuint visible_ssbo = 0;
@@ -215,6 +223,12 @@ private:
bool growModelSsbo(ModelGpuData& m, size_t needed_total);
ModelGpuData& getOrCreateModel(uint32_t model_id);
// (Re)build the per-instance world AABB SSBO from m.instances +
// m.instance_reflected. One-shot upload called after finalizeModel /
// applyCachedModel once instances are settled. Consumed by the GPU
// compute cull (Phase 3E, in progress).
void uploadInstanceAabbs(ModelGpuData& m);
// Frustum-cull m's instances (BVH if available, else linear scan),
// build the per-mesh DrawElementsIndirectCommand array + flat visible
// list, and upload both to m.indirect_buffer / m.visible_ssbo.