SpiecsEngine
 
Loading...
Searching...
No Matches
VulkanRayTracing.cpp
Go to the documentation of this file.
1/**
2* @file VulkanRayTracing.cpp.
3* @brief The VulkanRayTracing Class Implementation.
4* @author Spices.
5*/
6
7#include "Pchheader.h"
11#include "VulkanDevice.h"
12#include "Core/Library/MemoryLibrary.h"
13
14namespace Spices {
15
17 : VulkanObject(vulkanState)
18 {}
19
21 {
23
24 if (m_tlas.accel)
25 {
26 return m_tlas.accel->Get();
27 }
28
29 return nullptr;
30 }
31
33 const std::vector<BlasInput>& input ,
34 VkBuildAccelerationStructureFlagsKHR flags
35 )
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
44 /**
45 * @brief Preparing the information for the acceleration build commands..
46 */
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
71 /**
72 * @brief Get ASBuildSize.
73 */
74 m_VulkanState.m_VkFunc.vkGetAccelerationStructureBuildSizesKHR(
75 m_VulkanState.m_Device,
76 VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
77 &buildAs[idx].buildInfo,
78 maxPrimCount.data(),
79 &buildAs[idx].sizeInfo
80 );
81
82 /**
83 * @brief Extra info.
84 */
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
90 /**
91 * @brief Allocate the scratch buffers holding the temporary data of the acceleration structure builder.
92 */
93 VulkanBuffer scratchBuffer(
94 m_VulkanState,
95 "ScratchBuffer",
96 maxScratchSize,
97 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
98 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ,
99 VMA_MEMORY_PROPERTY_DEDICATED_MEMORY_BIT
100 );
101
102 const VkDeviceAddress scratchAddress = scratchBuffer.GetAddress();
103
104 /**
105 * @brief Allocate a query pool for storing the needed size for every BLAS compaction.
106 */
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
112 /**
113 * @brief Create Query Pool.
114 */
115 queryPool = std::make_shared<VulkanQueryPool>(m_VulkanState, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, nbBlas);
116 }
117
118 /**
119 * @brief Batching creation / compaction of BLAS to allow staying in restricted amount of memory.
120 */
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
130 /**
131 * @brief Over the limit or last BLAS element.
132 */
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
146 /**
147 * @brief Reset.
148 */
149 batchSize = 0;
150 indices.clear();
151 }
152 }
153 }
154
155 void VulkanRayTracing::UpdateBlas(uint32_t blasIdx, const BlasInput& blas, VkBuildAccelerationStructureFlagsKHR flags) const
156 {
158
159 // Preparing all build information, acceleration is filled later
160 VkAccelerationStructureBuildGeometryInfoKHR buildInfos{};
161 buildInfos.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
162 buildInfos.flags = flags;
163 buildInfos.geometryCount = static_cast<uint32_t>(blas.asGeometry.size());
164 buildInfos.pGeometries = blas.asGeometry.data();
165 buildInfos.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR; // UPDATE
166 buildInfos.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
167 //buildInfos.srcAccelerationStructure = m_blas[blasIdx].accel; // UPDATE
168 //buildInfos.dstAccelerationStructure = m_blas[blasIdx].accel;
169
170 // Find size to build on the device
171 std::vector<uint32_t> maxPrimCount(blas.asBuildOffsetInfo.size());
172
173 for (auto tt = 0; tt < blas.asBuildOffsetInfo.size(); tt++)
174 {
175 maxPrimCount[tt] = blas.asBuildOffsetInfo[tt].primitiveCount; // Number of primitives/triangles
176 }
177
178 VkAccelerationStructureBuildSizesInfoKHR sizeInfo{};
179 sizeInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
180
181 m_VulkanState.m_VkFunc.vkGetAccelerationStructureBuildSizesKHR(
182 m_VulkanState.m_Device,
183 VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
184 &buildInfos,
185 maxPrimCount.data(),
186 &sizeInfo
187 );
188
189 // Allocate the scratch buffer and setting the scratch info
190 VulkanBuffer scratchBuffer(
191 m_VulkanState,
192 "ScratchBuffer",
193 sizeInfo.buildScratchSize,
194 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
195 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
196 0
197 );
198
199 VkBufferDeviceAddressInfo bufferInfo{};
200 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
201 bufferInfo.buffer = scratchBuffer.Get();
202 buildInfos.scratchData.deviceAddress = vkGetBufferDeviceAddress(m_VulkanState.m_Device, &bufferInfo);
203
204 std::vector<const VkAccelerationStructureBuildRangeInfoKHR*> pBuildOffset(blas.asBuildOffsetInfo.size());
205 for (size_t i = 0; i < blas.asBuildOffsetInfo.size(); i++)
206 {
207 pBuildOffset[i] = &blas.asBuildOffsetInfo[i];
208 }
209
210 // Update the instance buffer on the device side and build the TLAS
211 VulkanCommandBuffer::CustomGraphicCmd(m_VulkanState, [&](const VkCommandBuffer& commandBuffer) {
212 // Update the acceleration structure. Note the VK_TRUE parameter to trigger the update,
213 // and the existing BLAS being passed and updated in place
214 m_VulkanState.m_VkFunc.vkCmdBuildAccelerationStructuresKHR(commandBuffer, 1, &buildInfos, pBuildOffset.data());
215 });
216 }
217
219 const std::vector<VkAccelerationStructureInstanceKHR>& instances ,
220 VkBuildAccelerationStructureFlagsKHR flags ,
221 bool update
222 )
223 {
225
226 BuildTLAS(instances, flags, update, false);
227 }
228
230 VkCommandBuffer cmdBuf ,
231 uint32_t countInstance ,
232 VkDeviceAddress instBufferAddr ,
233 std::unique_ptr<VulkanBuffer>& scratchBuffer ,
234 VkBuildAccelerationStructureFlagsKHR flags ,
235 bool update ,
236 bool motion
237 )
238 {
240
241 /**
242 * @brief Wraps a device pointer to the above uploaded instances.
243 */
244 VkAccelerationStructureGeometryInstancesDataKHR instancesVk{};
245 instancesVk.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
246 instancesVk.data.deviceAddress = instBufferAddr;
247
248 /**
249 * @brief Put the above into a VkAccelerationStructureGeometryKHR.We need to put the instances struct in a union and label it as instance data.
250 */
251 VkAccelerationStructureGeometryKHR topASGeometry{};
252 topASGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
253 topASGeometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
254 topASGeometry.geometry.instances = instancesVk;
255
256 /**
257 * @brief Find sizes.
258 */
259 VkAccelerationStructureBuildGeometryInfoKHR buildInfo{};
260 buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
261 buildInfo.flags = flags;
262 buildInfo.geometryCount = 1;
263 buildInfo.pGeometries = &topASGeometry;
264 buildInfo.mode = update ? VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR : VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
265 buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
266 buildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
267
268 VkAccelerationStructureBuildSizesInfoKHR sizeInfo{};
269 sizeInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
270
271 m_VulkanState.m_VkFunc.vkGetAccelerationStructureBuildSizesKHR(
272 m_VulkanState.m_Device,
273 VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
274 &buildInfo,
275 &countInstance,
276 &sizeInfo
277 );
278
279#ifdef VK_NV_ray_tracing_motion_blur
280
281 VkAccelerationStructureMotionInfoNV motionInfo{};
282 motionInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MOTION_INFO_NV;
283 motionInfo.maxInstances = countInstance;
284
285#endif
286
287 /**
288 * @brief Create TLAS.
289 */
290 if (update == false)
291 {
292 VkAccelerationStructureCreateInfoKHR createInfo{};
293 createInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
294 createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
295 createInfo.size = sizeInfo.accelerationStructureSize;
296
297#ifdef VK_NV_ray_tracing_motion_blur
298
299 if (motion)
300 {
301 createInfo.createFlags = VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV;
302 createInfo.pNext = &motionInfo;
303 }
304
305#endif
306
307 m_tlas = CreateAcceleration(createInfo);
308 }
309
310 /**
311 * @brief Allocate the scratch memory.
312 */
313 scratchBuffer = std::make_unique<VulkanBuffer>(
314 m_VulkanState,
315 "ScratchBuffer",
316 sizeInfo.buildScratchSize,
317 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
318 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
319 VMA_MEMORY_PROPERTY_DEDICATED_MEMORY_BIT
320 );
321
322 VkDeviceAddress scratchAddress = scratchBuffer->GetAddress();
323
324 /**
325 * @brief Update build information.
326 */
327 buildInfo.srcAccelerationStructure = update ? m_tlas.accel->Get() : VK_NULL_HANDLE;
328 buildInfo.dstAccelerationStructure = m_tlas.accel->Get();
329 buildInfo.scratchData.deviceAddress = scratchAddress;
330
331 /**
332 * @brief Build Offsets info : n instances.
333 */
334 VkAccelerationStructureBuildRangeInfoKHR buildOffsetInfo{};
335 buildOffsetInfo.primitiveCount = countInstance;
336 buildOffsetInfo.primitiveOffset = 0;
337 buildOffsetInfo.firstVertex = 0;
338 buildOffsetInfo.transformOffset = 0;
339
340 const VkAccelerationStructureBuildRangeInfoKHR* pBuildOffsetInfo = &buildOffsetInfo;
341
342 /**
343 * @brief Build the TLAS.
344 */
345 m_VulkanState.m_VkFunc.vkCmdBuildAccelerationStructuresKHR(cmdBuf, 1, &buildInfo, &pBuildOffsetInfo);
346 }
347
349 {
351
352 if (!m_HitGroups)
353 {
354 m_HitGroups = std::make_shared<std::unordered_map<std::string, uint32_t>>();
355 }
356
357 return m_HitGroups;
358 }
359
360 void VulkanRayTracing::CreateRTShaderBindingTable(uint32_t rgenCount, uint32_t missCount, VkPipeline pipeline)
361 {
363
364 const uint32_t hitCount = static_cast<uint32_t>(m_HitGroups->size());
365
366 const auto handleCount = rgenCount + missCount + hitCount;
367 const uint32_t handleSize = VulkanDevice::GetRTPipelineProperties().shaderGroupHandleSize;
368
369 /**
370 * @brief The SBT(buffer) need to have starting groups to be aligned and handles in the group to be aligned.
371 */
372 const uint32_t handleSizeAligned = MemoryLibrary::align_up(handleSize, VulkanDevice::GetRTPipelineProperties().shaderGroupHandleAlignment);
373
374 m_RgenRegion.stride = MemoryLibrary::align_up(handleSizeAligned, VulkanDevice::GetRTPipelineProperties().shaderGroupBaseAlignment);
375 m_RgenRegion.size = m_RgenRegion.stride; // The size member of pRayGenShaderBindingTable must be equal to its stride member
376
377 m_MissRegion.stride = handleSizeAligned;
378 m_MissRegion.size = MemoryLibrary::align_up(missCount * handleSizeAligned, VulkanDevice::GetRTPipelineProperties().shaderGroupBaseAlignment);
379
380 m_HitRegion.stride = handleSizeAligned;
381 m_HitRegion.size = MemoryLibrary::align_up(hitCount * handleSizeAligned, VulkanDevice::GetRTPipelineProperties().shaderGroupBaseAlignment);
382
383 /**
384 * @brief Get the shader group handles.
385 */
386 const uint32_t dataSize = handleCount * handleSize;
387 std::vector<uint8_t> handles(dataSize);
388 VK_CHECK(m_VulkanState
389 .m_VkFunc
390 .vkGetRayTracingShaderGroupHandlesKHR(
391 m_VulkanState.m_Device ,
392 pipeline ,
393 0 ,
394 handleCount ,
395 dataSize ,
396 handles.data()
397 ))
398
399 /**
400 * @brief Allocate a buffer for storing the SBT.
401 */
402 VkDeviceSize sbtSize = m_RgenRegion.size + m_MissRegion.size + m_HitRegion.size + m_CallRegion.size;
403
404 m_RTSBTBuffer = std::make_unique<VulkanBuffer>(
405 m_VulkanState ,
406 "SBTBuffer" ,
407 sbtSize ,
408 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
409 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
410 VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR ,
411 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
412 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
413 );
414
415 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_BUFFER, (uint64_t)m_RTSBTBuffer->Get(), m_VulkanState.m_Device, "SBT Buffer")
416
417 m_RgenRegion.deviceAddress = m_RTSBTBuffer->GetAddress();
418 m_MissRegion.deviceAddress = m_RTSBTBuffer->GetAddress() + m_RgenRegion.size;
419 m_HitRegion.deviceAddress = m_RTSBTBuffer->GetAddress() + m_RgenRegion.size + m_MissRegion.size;
420
421 /**
422 * @brief Helper to retrieve the handle data.
423 */
424 auto getHandle = [&](int i) { return handles.data() + i * handleSize; };
425
426 /**
427 * @brief Map the SBT buffer and write in the handles.
428 */
429 uint64_t offset = 0;
430 uint32_t handleIdx = 0 ;
431
432 /**
433 * @brief Ray Generation.
434 */
435 for (uint32_t c = 0; c < rgenCount; c++)
436 {
437 m_RTSBTBuffer->WriteToBuffer(getHandle(handleIdx++), handleSize, offset);
438 m_RgenRegion.stride;
439 }
440
441 /**
442 * @brief Miss.
443 */
444 offset = m_RgenRegion.size;
445 for (uint32_t c = 0; c < missCount; c++)
446 {
447 m_RTSBTBuffer->WriteToBuffer(getHandle(handleIdx++), handleSize, offset);
448 offset += m_MissRegion.stride;
449 }
450
451 /**
452 * @brief Closest Hit.
453 */
454 offset = m_RgenRegion.size + m_MissRegion.size;
455 for (uint32_t c = 0; c < hitCount; c++)
456 {
457 m_RTSBTBuffer->WriteToBuffer(getHandle(handleIdx++), handleSize, offset);
458 offset += m_HitRegion.stride;
459 }
460 }
461
463 {
465
466 return m_MeshDesc;
467 }
468
470 VkCommandBuffer cmdBuf ,
471 const std::vector<uint32_t>& indices ,
472 std::vector<BuildAccelerationStructure>& buildAs ,
473 VkDeviceAddress scratchAddress ,
474 std::shared_ptr<VulkanQueryPool> queryPool
475 ) const
476 {
478
479 /**
480 * @brief Querying the compaction size.
481 */
482 if (queryPool)
483 {
484 queryPool->Reset(cmdBuf);
485 }
486
487 uint32_t queryCnt{ 0 };
488
489 /**
490 * @brief creating all the BLAS defined by the index chunk.
491 */
492 for (const auto& idx : indices)
493 {
494 /**
495 * @brief Actual allocation of buffer and acceleration structure.
496 */
497 VkAccelerationStructureCreateInfoKHR createInfo{};
498 createInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
499 createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
500 createInfo.size = buildAs[idx].sizeInfo.accelerationStructureSize; // Will be used to allocate memory.
501
502 *buildAs[idx].as = CreateAcceleration(createInfo);
503
504 /**
505 * @brief BuildInfo #2 part.
506 */
507 buildAs[idx].buildInfo.dstAccelerationStructure = buildAs[idx].as->accel->Get(); // Setting where the build lands
508 buildAs[idx].buildInfo.scratchData.deviceAddress = scratchAddress; // All build are using the same scratch buffer
509
510 /**
511 * @brief Building the bottom - level - acceleration - structure.
512 */
513 m_VulkanState.m_VkFunc.vkCmdBuildAccelerationStructuresKHR(cmdBuf, 1, &buildAs[idx].buildInfo, &buildAs[idx].rangeInfo);
514
515 /**
516 * @brief Since the scratch buffer is reused across builds, we need a barrier to ensure one build
517 * is finished before starting the next one.
518 */
519 VkMemoryBarrier barrier{};
520 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
521 barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
522 barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
523
524 vkCmdPipelineBarrier(
525 cmdBuf,
526 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
527 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
528 0,
529 1,
530 &barrier,
531 0,
532 nullptr,
533 0,
534 nullptr
535 );
536
537 /**
538 * @brief Add the size query only if needed.
539 */
540 if (queryPool)
541 {
542 /**
543 * @brief Add a query to find the 'real' amount of memory needed, use for compaction.
544 */
545 m_VulkanState.m_VkFunc.vkCmdWriteAccelerationStructuresPropertiesKHR(
546 cmdBuf,
547 1,
548 &buildAs[idx].buildInfo.dstAccelerationStructure,
549 VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR,
550 queryPool->Get(),
551 queryCnt++
552 );
553 }
554 }
555 }
556
558 VkCommandBuffer cmdBuf ,
559 const std::vector<uint32_t>& indices ,
560 std::vector<BuildAccelerationStructure>& buildAs ,
561 std::shared_ptr<VulkanQueryPool> queryPool
562 )
563 const
564 {
566
567 uint32_t queryCtn = 0;
568
569 /**
570 * @brief Get the compacted size result back.
571 */
572 std::vector<VkDeviceSize> compactSizes(static_cast<uint32_t>(indices.size()));
573
574 /**
575 * @brief Get Query Pool results.
576 */
577 queryPool->QueryResults(compactSizes.data());
578
579 for (const auto idx : indices)
580 {
581 buildAs[idx].cleanupAS = *buildAs[idx].as; // previous AS to destroy
582 buildAs[idx].sizeInfo.accelerationStructureSize = compactSizes[queryCtn++]; // new reduced size
583
584 /**
585 * @brief Creating a compact version of the AS.
586 */
587 VkAccelerationStructureCreateInfoKHR asCreateInfo{};
588 asCreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
589 asCreateInfo.size = buildAs[idx].sizeInfo.accelerationStructureSize;
590 asCreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
591 *buildAs[idx].as = CreateAcceleration(asCreateInfo);
592
593 /**
594 * @brief Copy the original BLAS to a compact version.
595 */
596 VkCopyAccelerationStructureInfoKHR copyInfo{};
597 copyInfo.sType = VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR;
598 copyInfo.src = buildAs[idx].buildInfo.dstAccelerationStructure;
599 copyInfo.dst = buildAs[idx].as->accel->Get();
600 copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR;
601
602 m_VulkanState.m_VkFunc.vkCmdCopyAccelerationStructureKHR(cmdBuf, &copyInfo);
603 }
604 }
605
606 AccelKHR VulkanRayTracing::CreateAcceleration(VkAccelerationStructureCreateInfoKHR& accel) const
607 {
609
610 AccelKHR resultAccel;
611
612 /**
613 * @brief Allocating the buffer to hold the acceleration structure.
614 */
615 resultAccel.buffer = std::make_shared<VulkanBuffer>(
616 m_VulkanState,
617 "AccelBuffer",
618 accel.size,
619 VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR |
620 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
621 0
622 );
623
624 /**
625 * @brief Setting the buffer.
626 */
627 accel.buffer = resultAccel.buffer->Get();
628
629 /**
630 * @brief Create the acceleration structure.
631 */
632 resultAccel.accel = std::make_shared<VulkanAccelerationStructure>(m_VulkanState, accel);
633
634 return resultAccel;
635 }
636
637}
#define SPICES_PROFILE_ZONE
#define VK_CHECK(expr)
Vulkan Check macro. Verify Vulkan API Effectiveness.
Definition VulkanUtils.h:68
This Class is a Wrapper of VulkanBuffer.
VulkanCommandBuffer Class. This class defines the VulkanCommandBuffer behaves. This class is just a w...
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
VulkanObject(VulkanState &vulkanState)
Constructor Function. Init member variables.
VulkanObject Class. This class defines the basic behaves of VulkanObject. When we create an new Vulka...
This Class is a Wrapper of VulkanQueryPool.
void 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....
VulkanRayTracing(VulkanState &vulkanState)
Constructor Function.
void CmdCreateTLAS(VkCommandBuffer cmdBuf, uint32_t countInstance, VkDeviceAddress instBufferAddr, std::unique_ptr< VulkanBuffer > &scratchBuffer, VkBuildAccelerationStructureFlagsKHR flags, bool update, bool motion)
Low level of Tlas creation. Creating the TLAS, called by buildTlas.
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....
const VkAccelerationStructureKHR GetAccelerationStructure() const
Get AccelerationStructure.
Attribute< uint64_t > & GetMeshDesc()
Get Mesh Description.
void BuildTLAS(const std::vector< VkAccelerationStructureInstanceKHR > &instances, VkBuildAccelerationStructureFlagsKHR flags=VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, bool update=false)
Creating the top-level acceleration structure from the vector of Instance. The resulting TLAS will be...
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....
AccelKHR CreateAcceleration(VkAccelerationStructureCreateInfoKHR &accel) const
Create Acceleration.
std::shared_ptr< std::unordered_map< std::string, uint32_t > > GetHitGroups()
Get Scene hit groups.
void UpdateBlas(uint32_t blasIdx, const BlasInput &blas, VkBuildAccelerationStructureFlagsKHR flags) const
Update part of BLAS.
void CreateRTShaderBindingTable(uint32_t rgenCount, uint32_t missCount, VkPipeline pipeline)
Create Shader Binding Table.
Wrapper of Scene RayTracing (KHR/VK) Features and Data.
AccelStructure Wrapper.
Definition Attribute.h:17
MeshResource's item template.
Definition Attribute.h:28
This struct contains all Vulkan object in used global.
Definition VulkanUtils.h:74