[perf] TLAS instance+metadata upload: O(n) rebuild + whole-buffer flush every frame (RenderingElement3D.cpp) #118
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics#118
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by an adversarially-verified performance audit (confirmed real after a skeptic pass).
This issue covers the per-frame TLAS instance+metadata upload end to end — both the O(n) host rebuild and the whole-buffer flush of those same buffers. They are one deliverable: the dirty range computed for the rebuild is exactly the range the flush should use. (Merged from the former #121.)
Locations:
implementations/Crafter.Graphics-RenderingElement3D.cpp:144-159(rebuild) and:161-173(flush)Severity: medium · Effort: moderate · Category: cpu + memory
Problem
:144-159): the TLAS host instance+metadata buffer is rebuilt with an O(n) loop every frame, unconditionally (outside thetopologyChangedblock), copying each 64 BVkAccelerationStructureInstanceKHR+ metadata with no dirty tracking — even on cheap refits. At the millions-of-instances target this dominates the CPU frame.:161-173): bothFlushDevicecalls resolve toVK_WHOLE_SIZE, flushing the full high-water capacity every frame regardless of dirty bytes (steady state never callsResize, so the span is capacity, notprimitiveCount*stride). Self-gates to a no-op on HOST_COHERENT memory, so cost only materializes on non-coherent BAR/VRAM.Fix
Add a dirty-set / generation counter to the rebuild so only changed host-authored fields are copied, then feed that same dirty range into the existing ranged
FlushDevice(offset, bytes)overload (VulkanBuffer.cppm:336) over[0, primitiveCount*stride)(or, ideally, just the dirty sub-ranges). One dirty-set drives both the copy and the flush.Constraint
transformOwnedByGpuelements have their transform written in-place by GPU compute, so only host-authored fields are dirty-trackable. (The AoS→SoA and branch-hoist suggestions on the rebuild were refuted: the loop is bandwidth-bound andVkAccelerationStructureInstanceKHRis a spec-frozen AoS struct read by device address.)[perf] TLAS rebuilds entire host instance+metadata buffer every frame (RenderingElement3D.cpp)to [perf] TLAS instance+metadata upload: O(n) rebuild + whole-buffer flush every frame (RenderingElement3D.cpp)