[perf][MEDIUM] TLAS instance buffer is HOST_VISIBLE, read directly as AS build input #65
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics#65
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:95-96, 99-116Impact: Medium · Effort: Small · Genuinely per-frame for the TLAS
Depends on: #59 (GetMemoryType preferred/fallback) · Related: #89 (upload-strategy helper — direct branch only, see caveat 5), #58 (BAR-heap pressure), #60 (coherency gating)
Problem
The TLAS instance buffer is allocated
HOST_VISIBLE | HOST_COHERENT(system RAM) and read directly as AS build input, rebuilt/refit every frame. Worse: it is also a compute-shader write target fortransformOwnedByGpuelements (the compute shader writes the transform field in place; the CPU loop at lines 99-114 writes the other fields and deliberately skips the transform). So for GPU-owned transforms, both GPU accesses cross PCIe — the compute shader writes the transform over PCIe, and the AS build reads the whole instance over PCIe.This is an in-place co-write: CPU and GPU each own disjoint bytes of the same buffer. That is the crucial design constraint.
Proposed fix
Allocate the instance buffer
HOST_VISIBLE | DEVICE_LOCAL(BAR/VRAM), keeping it a single shared, persistently-mapped buffer. No staging, no copy, no extra barrier:The same upgrade benefits
metadataBuffer(line 96) — tracked separately in #75.Why NOT staging + DEVICE_LOCAL + vkCmdCopyBuffer
(The original proposal.) A "copy whole host buffer → device" clobbers the GPU-written transforms, because the buffer is co-written by the compute shader. Staging fights the existing in-place design. Rejected in favor of the single-buffer heap upgrade above.
Correctness caveats
HOST_VISIBLE|DEVICE_LOCALmemory type exists. Use prefer-but-require: try the combined type, fall back to plainHOST_VISIBLE(current behavior). This is theGetMemoryTypechange in #59 — this issue depends on #59.HOST_COHERENTfrom the request; the combined type may not be coherent. The existingFlushDevice(cmd, ...)at line 116 already covers host->build visibility — just gate any flush-skip on the chosen type's flags, not the requested ones (see #60). Never remove the barrier.primitiveCount × 64 B— ~6 MB even at 100k instances, so negligible, but it adds to the same scarce heap.vkQueueWaitIdlecovers this today; a frame-in-flight renderer (#40) must add explicit barriers.