tlas build options
This commit is contained in:
parent
e3940d99c3
commit
00d14d67cb
3 changed files with 50 additions and 13 deletions
|
|
@ -188,7 +188,9 @@ void RenderingElement3D::BuildTLASBuild(WebGPUCommandEncoderRef /*cmd*/, std::ui
|
|||
tlas.builtInstanceCount = primitiveCount;
|
||||
}
|
||||
|
||||
void RenderingElement3D::BuildTLAS(WebGPUCommandEncoderRef cmd, std::uint32_t index) {
|
||||
void RenderingElement3D::BuildTLAS(WebGPUCommandEncoderRef cmd, std::uint32_t index, RTBuildPreference) {
|
||||
// `preference` is ignored — the software LBVH TLAS build has no
|
||||
// FAST_TRACE/FAST_BUILD equivalent. See the interface comment.
|
||||
BuildTLASUpload(cmd, index);
|
||||
BuildTLASBuild(cmd, index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,18 +47,33 @@ void RenderingElement3D::Remove(RenderingElement3D* e) {
|
|||
e->indexInElements = std::numeric_limits<std::uint32_t>::max();
|
||||
}
|
||||
|
||||
void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index) {
|
||||
void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index, RTBuildPreference preference) {
|
||||
auto& tlas = tlases[index];
|
||||
const std::uint32_t primitiveCount = static_cast<std::uint32_t>(elements.size());
|
||||
|
||||
// ALLOW_UPDATE is always set — BuildTLAS refits in place on later
|
||||
// frames. The FAST_TRACE/FAST_BUILD preference is layered on top; the
|
||||
// two preference bits are mutually exclusive, so exactly one is chosen.
|
||||
// Both bits are baked into the AS at BUILD time and must be identical on
|
||||
// every subsequent UPDATE, so a change in `preference` is treated as a
|
||||
// topology change below to force a fresh rebuild with the new flags.
|
||||
const VkBuildAccelerationStructureFlagsKHR buildFlags =
|
||||
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR
|
||||
| (preference == RTBuildPreference::FastBuild
|
||||
? VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR
|
||||
: VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR);
|
||||
|
||||
// Refit (UPDATE) is allowed when the count matches the count this AS
|
||||
// was last built for. A change forces a full rebuild because the AS
|
||||
// storage and instance buffer were sized for the old count. Refit is
|
||||
// dramatically cheaper at scale (millions of instances) — it walks the
|
||||
// existing BVH and updates AABBs rather than reconstructing topology.
|
||||
// was last built for and the build flags are unchanged. A change forces
|
||||
// a full rebuild because the AS storage and instance buffer were sized
|
||||
// for the old count (and a refit must inherit the original build flags).
|
||||
// Refit is dramatically cheaper at scale (millions of instances) — it
|
||||
// walks the existing BVH and updates AABBs rather than reconstructing
|
||||
// topology.
|
||||
const bool topologyChanged =
|
||||
tlas.accelerationStructure == VK_NULL_HANDLE
|
||||
|| primitiveCount != tlas.builtInstanceCount;
|
||||
|| primitiveCount != tlas.builtInstanceCount
|
||||
|| buildFlags != tlas.builtFlags;
|
||||
|
||||
{
|
||||
VkMemoryBarrier asBarrier {
|
||||
|
|
@ -118,10 +133,9 @@ void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index) {
|
|||
VkAccelerationStructureBuildGeometryInfoKHR tlasBuildGeometryInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
|
||||
.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,
|
||||
// ALLOW_UPDATE is required for any subsequent UPDATE-mode (refit)
|
||||
// build. Set it on every build so the AS we keep around can be
|
||||
// refit on later frames.
|
||||
.flags = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR,
|
||||
// ALLOW_UPDATE (required for any subsequent UPDATE-mode refit) plus
|
||||
// the caller's FAST_TRACE/FAST_BUILD preference — see buildFlags above.
|
||||
.flags = buildFlags,
|
||||
.mode = topologyChanged
|
||||
? VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR
|
||||
: VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR,
|
||||
|
|
@ -170,6 +184,7 @@ void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index) {
|
|||
tlas.address = Device::vkGetAccelerationStructureDeviceAddressKHR(Device::device, &addrInfo);
|
||||
|
||||
tlas.builtInstanceCount = primitiveCount;
|
||||
tlas.builtFlags = buildFlags;
|
||||
}
|
||||
|
||||
// For UPDATE mode, src == dst (in-place refit). For BUILD, src is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue