[perf] TLAS metadataBuffer is HOST_VISIBLE, CPU-written + shader-read every frame #75
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics#75
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?
Subsystem: RenderingElement3D / RT
Location:
implementations/Crafter.Graphics-RenderingElement3D.cpp:96(write at:113)Impact: Low-Medium · Effort: Small · Per-frame CPU-write + shader-read
Depends on: #59 · Related: #89 (upload-strategy helper — direct branch only, see caveat 4), #65 (sibling buffer), #60
Problem
metadataBufferis allocatedHOST_VISIBLE | HOST_COHERENT(system RAM). It is CPU-written every frame (line 113:tlas.metadataBuffer.value[i] = elements[i]->userMetadata) and read by ray shaders (as aSTORAGE_BUFFERvia device address) every frame. So like the instance buffer (#65), every per-frame shader read traverses PCIe. Originally noted only as a footnote in #65 — promoting to its own item since it is not an AS build input and has its own fix.Proposed fix
Prefer
HOST_VISIBLE | DEVICE_LOCAL, keeping the single persistently-mapped buffer. CPU writes go to write-combined BAR (write-only, sequential — fine); shader reads hit local VRAM.Correctness caveats
HOST_VISIBLE|DEVICE_LOCALtype exists, regardless of buffer size. When it exists, allocate it directly (capacity is a non-issue at this size).HOST_VISIBLE(current behavior) — NOT staging. This buffer is rewritten by the CPU every frame, so a per-frame stage+copy would defeat the purpose (and add a copy/barrier per frame). Same reasoning as #65 caveat 5: only #89's direct branch is valid here; its staged branch is wrong for a per-frame-rewritten buffer. If routed through #89, pass a flag forbidding the staged strategy.HOST_COHERENTfrom the request; gate any flush-skip on the chosen type's flags (#60). The host-write -> shader-read ordering still needs the existing flush/barrier.