SpiecsEngine
 
Loading...
Searching...
No Matches

◆ BuildBLAS()

void Spices::VulkanRayTracing::BuildBLAS ( const std::vector< BlasInput > & input,
VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR )

Create all the BLAS from the vector of BlasInput. There will be one BLAS per input-vector entry. There will be as many BLAS as input.size(). The resulting BLAS (along with the inputs used to build) are stored in m_blas, and can be referenced by index. if flag has the 'Compact' flag, the BLAS will be compacted.

Parameters
[in]inputBlasInput.
[in]flagsVkBuildAccelerationStructureFlagsKHR.

Preparing the information for the acceleration build commands..

Get ASBuildSize.

Extra info.

Allocate the scratch buffers holding the temporary data of the acceleration structure builder.

Allocate a query pool for storing the needed size for every BLAS compaction.

Create Query Pool.

Batching creation / compaction of BLAS to allow staying in restricted amount of memory.

Over the limit or last BLAS element.

Reset.

Preparing the information for the acceleration build commands..

Get ASBuildSize.

Extra info.

Allocate the scratch buffers holding the temporary data of the acceleration structure builder.

Allocate a query pool for storing the needed size for every BLAS compaction.

Create Query Pool.

Batching creation / compaction of BLAS to allow staying in restricted amount of memory.

Over the limit or last BLAS element.

Reset.

Definition at line 32 of file VulkanRayTracing.cpp.

36 {
38
39 const auto nbBlas = static_cast<uint32_t>(input.size());
40 VkDeviceSize asTotalSize = 0;
41 uint32_t nbCompactions = 0;
42 VkDeviceSize maxScratchSize = 0;
43
47 std::vector<BuildAccelerationStructure> buildAs(nbBlas);
48 for (uint32_t idx = 0; idx < nbBlas; idx++)
49 {
50 /*
51 * @brief Filling partially the VkAccelerationStructureBuildGeometryInfoKHR for querying the build sizes.
52 * Other information will be filled in the createBlas (see #2)
53 */
54 buildAs[idx].buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
55 buildAs[idx].buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
56 buildAs[idx].buildInfo.flags = input[idx].flags | flags;
57 buildAs[idx].buildInfo.geometryCount = static_cast<uint32_t>(input[idx].asGeometry.size());
58 buildAs[idx].buildInfo.pGeometries = input[idx].asGeometry.data();
59 buildAs[idx].rangeInfo = input[idx].asBuildOffsetInfo.data(); /*@brief Build range information.*/
60 buildAs[idx].as = input[idx].accel;
61
62 /*
63 * @brief Finding sizes to create acceleration structures and scratch.
64 */
65 std::vector<uint32_t> maxPrimCount(input[idx].asBuildOffsetInfo.size());
66 for (auto tt = 0; tt < input[idx].asBuildOffsetInfo.size(); tt++)
67 {
68 maxPrimCount[tt] = input[idx].asBuildOffsetInfo[tt].primitiveCount; /*@brief Number of primitives / triangles*/
69 }
70
74 m_VulkanState.m_VkFunc.vkGetAccelerationStructureBuildSizesKHR(
76 VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
77 &buildAs[idx].buildInfo,
78 maxPrimCount.data(),
79 &buildAs[idx].sizeInfo
80 );
81
85 asTotalSize += buildAs[idx].sizeInfo.accelerationStructureSize;
86 maxScratchSize = std::max(maxScratchSize, buildAs[idx].sizeInfo.buildScratchSize);
87 nbCompactions += hasFlag(buildAs[idx].buildInfo.flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR);
88 }
89
93 VulkanBuffer scratchBuffer(
95 "ScratchBuffer",
96 maxScratchSize,
97 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
98 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ,
100 );
101
102 const VkDeviceAddress scratchAddress = scratchBuffer.GetAddress();
103
107 std::shared_ptr<VulkanQueryPool> queryPool = nullptr;
108 if (nbCompactions > 0) // Is compaction requested?
109 {
110 assert(nbCompactions == nbBlas); // Don't allow mix of on/off compaction
111
115 queryPool = std::make_shared<VulkanQueryPool>(m_VulkanState, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, nbBlas);
116 }
117
121 std::vector<uint32_t> indices; // Indices of the BLAS to create
122 VkDeviceSize batchSize = 0;
123 constexpr VkDeviceSize batchLimit = 256'000'000; // 256 MB
124
125 for (uint32_t idx = 0; idx < nbBlas; idx++)
126 {
127 indices.push_back(idx);
128 batchSize += buildAs[idx].sizeInfo.accelerationStructureSize;
129
133 if (batchSize >= batchLimit || idx == nbBlas - 1)
134 {
135 VulkanCommandBuffer::CustomGraphicCmd(m_VulkanState, [&](const VkCommandBuffer& commandBuffer) {
136 CmdCreateBLAS(commandBuffer, indices, buildAs, scratchAddress, queryPool);
137 });
138
139 if (queryPool)
140 {
141 VulkanCommandBuffer::CustomGraphicCmd(m_VulkanState, [&](const VkCommandBuffer& commandBuffer) {
142 CmdCompactBLAS(commandBuffer, indices, buildAs, queryPool);
143 });
144 }
145
149 batchSize = 0;
150 indices.clear();
151 }
152 }
153 }
#define SPICES_PROFILE_ZONE
static void CustomGraphicCmd(VulkanState &vulkanState, T func)
Create a new command buffer and record custom cmd, submit to graphic queue, execute it immediately.
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
void CmdCreateBLAS(VkCommandBuffer cmdBuf, const std::vector< uint32_t > &indices, std::vector< BuildAccelerationStructure > &buildAs, VkDeviceAddress scratchAddress, std::shared_ptr< VulkanQueryPool > queryPool) const
Creating the bottom level acceleration structure for all indices of buildAs vector....
bool hasFlag(VkFlags item, VkFlags flag)
Is item in flags.
void CmdCompactBLAS(VkCommandBuffer cmdBuf, const std::vector< uint32_t > &indices, std::vector< BuildAccelerationStructure > &buildAs, std::shared_ptr< VulkanQueryPool > queryPool) const
Create and replace a new acceleration structure and buffer based on the size retrieved by the Query....
@ VMA_MEMORY_PROPERTY_DEDICATED_MEMORY_BIT
VkMemoryPropertyFlagBits.
VulkanFunctions m_VkFunc
Definition VulkanUtils.h:98