| 3715 | } |
| 3716 | |
| 3717 | void Scene::buildTlas(RenderContext* pRenderContext, uint32_t rayTypeCount, bool perMeshHitEntry) |
| 3718 | { |
| 3719 | FALCOR_PROFILE(pRenderContext, "buildTlas"); |
| 3720 | |
| 3721 | TlasData tlas; |
| 3722 | auto it = mTlasCache.find(rayTypeCount); |
| 3723 | if (it != mTlasCache.end()) tlas = it->second; |
| 3724 | |
| 3725 | // Prepare instance descs. |
| 3726 | // Note if there are no instances, we'll build an empty TLAS. |
| 3727 | fillInstanceDesc(mInstanceDescs, rayTypeCount, perMeshHitEntry); |
| 3728 | |
| 3729 | RtAccelerationStructureBuildInputs inputs = {}; |
| 3730 | inputs.kind = RtAccelerationStructureKind::TopLevel; |
| 3731 | inputs.descCount = (uint32_t)mInstanceDescs.size(); |
| 3732 | inputs.flags = RtAccelerationStructureBuildFlags::None; |
| 3733 | |
| 3734 | // Add build flags for dynamic scenes if TLAS should be updating instead of rebuilt |
| 3735 | if ((mpAnimationController->hasAnimations() || mpAnimationController->hasAnimatedVertexCaches()) && mTlasUpdateMode == UpdateMode::Refit) |
| 3736 | { |
| 3737 | inputs.flags |= RtAccelerationStructureBuildFlags::AllowUpdate; |
| 3738 | |
| 3739 | // If TLAS has been built already and it was built with ALLOW_UPDATE |
| 3740 | if (tlas.pTlasObject != nullptr && tlas.updateMode == UpdateMode::Refit) inputs.flags |= RtAccelerationStructureBuildFlags::PerformUpdate; |
| 3741 | } |
| 3742 | |
| 3743 | tlas.updateMode = mTlasUpdateMode; |
| 3744 | |
| 3745 | // On first build for the scene, create scratch buffer and cache prebuild info. As long as INSTANCE_DESC count doesn't change, we can reuse these |
| 3746 | if (mpTlasScratch == nullptr) |
| 3747 | { |
| 3748 | // Prebuild |
| 3749 | mTlasPrebuildInfo = RtAccelerationStructure::getPrebuildInfo(mpDevice.get(), inputs); |
| 3750 | mpTlasScratch = mpDevice->createBuffer(mTlasPrebuildInfo.scratchDataSize, ResourceBindFlags::UnorderedAccess, MemoryType::DeviceLocal); |
| 3751 | mpTlasScratch->setName("Scene::mpTlasScratch"); |
| 3752 | |
| 3753 | // #SCENE This isn't guaranteed according to the spec, and the scratch buffer being stored should be sized differently depending on update mode |
| 3754 | FALCOR_ASSERT(mTlasPrebuildInfo.updateScratchDataSize <= mTlasPrebuildInfo.scratchDataSize); |
| 3755 | } |
| 3756 | |
| 3757 | // Setup GPU buffers |
| 3758 | RtAccelerationStructure::BuildDesc asDesc = {}; |
| 3759 | asDesc.inputs = inputs; |
| 3760 | |
| 3761 | // If first time building this TLAS |
| 3762 | if (tlas.pTlasObject == nullptr) |
| 3763 | { |
| 3764 | { |
| 3765 | // Allocate a new buffer for the TLAS only if the existing buffer isn't big enough. |
| 3766 | if (!tlas.pTlasBuffer || tlas.pTlasBuffer->getSize() < mTlasPrebuildInfo.resultDataMaxSize) |
| 3767 | { |
| 3768 | tlas.pTlasBuffer = mpDevice->createBuffer(mTlasPrebuildInfo.resultDataMaxSize, ResourceBindFlags::AccelerationStructure, MemoryType::DeviceLocal); |
| 3769 | tlas.pTlasBuffer->setName("Scene TLAS buffer"); |
| 3770 | } |
| 3771 | } |
| 3772 | |
| 3773 | RtAccelerationStructure::Desc asCreateDesc = {}; |
| 3774 | asCreateDesc.setKind(RtAccelerationStructureKind::TopLevel); |
nothing calls this directly
no test coverage detected