SpiecsEngine
 
Loading...
Searching...
No Matches
VulkanRayTracing.h
Go to the documentation of this file.
1/**
2* @file VulkanRayTracing.h.
3* @brief The VulkanRayTracing Class Definitions.
4* @author Spices.
5*/
6
7#pragma once
8#include "Core/Core.h"
9#include "VulkanUtils.h"
11#include "VulkanBuffer.h"
12#include "Resources/Mesh/Attribute.h"
13#include "../../../assets/Shaders/src/Header/ShaderCommon.h"
14
15namespace Spices {
16
17 /**
18 * @brief Forward Declare.
19 */
20 class VulkanQueryPool;
21
23 {
24 std::array<uint64_t, SpicesShader::MESH_BUFFER_MAXNUM> descs;
25 };
26
27 /**
28 * @brief Wrapper of Scene RayTracing (KHR/VK) Features and Data.
29 */
31 {
32 public:
33
34 /**
35 * @brief Blas Input data.
36 */
37 struct BlasInput
38 {
39 // Data used to build acceleration structure geometry
44 };
45
46 /**
47 * @brief AccelerationStructure Build Info and result.
48 */
50 {
54 AccelKHR* as; // result acceleration structure
56 };
57
58 public:
59
60 /**
61 * @brief Constructor Function.
62 * @param[in] vulkanState VulkanState.
63 */
64 VulkanRayTracing(VulkanState& vulkanState);
65
66 /**
67 * @brief Destructor Function.
68 */
69 virtual ~VulkanRayTracing() override = default;
70
71 /**
72 * @brief Get AccelerationStructure.
73 * @return Returns AccelerationStructure.
74 */
76
77 /**
78 * @brief Create all the BLAS from the vector of BlasInput.
79 * There will be one BLAS per input-vector entry.
80 * There will be as many BLAS as input.size().
81 * The resulting BLAS (along with the inputs used to build) are stored in m_blas,
82 * and can be referenced by index.
83 * if flag has the 'Compact' flag, the BLAS will be compacted.
84 * @param[in] input BlasInput.
85 * @param[in] flags VkBuildAccelerationStructureFlagsKHR.
86 */
87 void BuildBLAS(
88 const std::vector<BlasInput>& input ,
89 VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR
90 );
91
92 /**
93 * @brief Update part of BLAS.
94 * @param[in] blasIdx index of BLAS.
95 * @param[in] blas specific BlasInput.
96 * @param[in] flags VkBuildAccelerationStructureFlagsKHR.
97 */
98 void UpdateBlas(uint32_t blasIdx, const BlasInput& blas, VkBuildAccelerationStructureFlagsKHR flags) const;
99
100 /******************************************TLAS*******************************************/
101
102 /**
103 * @brief Creating the top-level acceleration structure from the vector of Instance.
104 * The resulting TLAS will be stored in m_tlas.
105 * update is to rebuild the Tlas with updated matrices.
106 * @param[in] instances Scene MeshPack Instances data.
107 * @param[in] flags VkBuildAccelerationStructureFlagsKHR.
108 * @param[in] update True if want update rather than create new one.
109 */
110 void BuildTLAS(
111 const std::vector<VkAccelerationStructureInstanceKHR>& instances ,
112 VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
113 bool update = false
114 );
115
116 /**
117 * @brief Build TLAS from an array of VkAccelerationStructureInstanceKHR.
118 * The resulting TLAS will be stored in m_tlas.
119 * update is to rebuild the Tlas with updated matrices, flag must have the 'allow_update'
120 * @param[in] instances Scene MeshPack Instances data.
121 * @param[in] flags VkBuildAccelerationStructureFlagsKHR.
122 * @param[in] update True if want update rather than create new one.
123 * @param[in] motion True if with VkAccelerationStructureMotionInstanceNV.
124 */
125 template<class T>
126 void BuildTLAS(
127 const std::vector<T>& instances ,
128 VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
129 bool update = false,
130 bool motion = false
131 );
132
133 /**
134 * @brief Low level of Tlas creation.
135 * Creating the TLAS, called by buildTlas.
136 * @param[in] cmdBuf VkCommandBuffer.
137 * @param[in] countInstance number of instances.
138 * @param[in] instBufferAddr Buffer address of instances.
139 * @param[in] scratchBuffer ScratchBuffer Buffer.
140 * @param[in] flags Build creation flag.
141 * @param[in] update Update == animation.
142 * @param[in] motion Motion Blur.
143 */
144 void CmdCreateTLAS(
145 VkCommandBuffer cmdBuf ,
146 uint32_t countInstance ,
147 VkDeviceAddress instBufferAddr ,
148 std::unique_ptr<VulkanBuffer>& scratchBuffer ,
149 VkBuildAccelerationStructureFlagsKHR flags ,
150 bool update ,
151 bool motion
152 );
153
154 /*****************************************************************************************/
155
156 /**********************************Hit Groups*********************************************/
157
158 /**
159 * @brief Set Scene hit groups.
160 * @param[in] groups hit groups.
161 */
162 void SetHitGroups(std::shared_ptr<std::unordered_map<std::string, uint32_t>> groups) { m_HitGroups = groups; }
163
164 /**
165 * @brief Get Scene hit groups.
166 * @return Returns Scene hit groups.
167 */
169
170 /*****************************************************************************************/
171
172 /*****************************Shader Binding Table****************************************/
173
174 /**
175 * @brief Create Shader Binding Table.
176 * @param[in] rgenCount Ray Generation shader count in raytracing material.
177 * @param[in] missCount Ray Missing shader count in raytracing material.
178 * @param[in] pipeline RayTracing Pipeline.
179 */
180 void CreateRTShaderBindingTable(uint32_t rgenCount, uint32_t missCount, VkPipeline pipeline);
181
182 /**
183 * @brief Get SBT RgenRegion.
184 * @return Returns SBT RgenRegion.
185 */
187
188 /**
189 * @brief Get SBT MissRegion.
190 * @return Returns SBT MissRegion.
191 */
193
194 /**
195 * @brief Get SBT HitRegion.
196 * @return Returns SBT HitRegion.
197 */
199
200 /**
201 * @brief Get SBT CallRegion.
202 * @return Returns SBT CallRegion.
203 */
205
206 /*****************************************************************************************/
207
208 /**************************************Mesh Description***********************************/
209
210 /**
211 * @brief Get Mesh Description.
212 * @return Returns Mesh Description.
213 */
214 Attribute<uint64_t>& GetMeshDesc();
215
216 /*****************************************************************************************/
217
218 private:
219
220 /**
221 * @brief Creating the bottom level acceleration structure for all indices of `buildAs` vector.
222 * The array of BuildAccelerationStructure was created in buildBlas and the vector of
223 * indices limits the number of BLAS to create at once. This limits the amount of
224 * memory needed when compacting the BLAS.
225 * @param[in] cmdBuf VkCommandBuffer.
226 * @param[in] indices BLAS indices.
227 * @param[in] buildAs BuildAccelerationStructure.
228 * @param[in] scratchAddress .
229 * @param[in] queryPool Query AccelerationStructure data.
230 */
231 void CmdCreateBLAS(
232 VkCommandBuffer cmdBuf ,
233 const std::vector<uint32_t>& indices ,
234 std::vector<BuildAccelerationStructure>& buildAs ,
235 VkDeviceAddress scratchAddress ,
236 std::shared_ptr<VulkanQueryPool> queryPool
237 ) const;
238
239 /**
240 * @brief Create and replace a new acceleration structure and buffer based on the size retrieved by the Query.
241 * We have to wait until all BLAS are built, to make a copy in the more suitable memory space.
242 * This is the reason why we used m_cmdPool.submitAndWait(cmdBuf) before calling this function.
243 * @param[in] cmdBuf VkCommandBuffer.
244 * @param[in] indices BLAS indices.
245 * @param[in] buildAs BuildAccelerationStructure.
246 * @param[in] queryPool Query AccelerationStructure data.
247 */
248 void CmdCompactBLAS(
249 VkCommandBuffer cmdBuf ,
250 const std::vector<uint32_t>& indices ,
251 std::vector<BuildAccelerationStructure>& buildAs ,
252 std::shared_ptr<VulkanQueryPool> queryPool
253 ) const;
254
255 /**
256 * @brief Is item in flags.
257 * @param[in] item VkFlags.
258 * @param[in] flag VkFlags.
259 * @return Returns true if item in flags.
260 */
261 bool hasFlag(VkFlags item, VkFlags flag) { return (item & flag) == flag; }
262
263 /**
264 * @brief Create Acceleration.
265 * @param[in] accel VkAccelerationStructureCreateInfoKHR.
266 * @return Returns created Acceleration.
267 */
268 AccelKHR CreateAcceleration(VkAccelerationStructureCreateInfoKHR& accel) const;
269
270 private:
271
272 /**
273 * @brief Top-level acceleration structure.
274 */
276
277 /**********************************Hit Groups*********************************************/
278
279 /**
280 * @brief Scene ray hit shader groups.
281 */
283
284 /*****************************************************************************************/
285
286 /*****************************Shader Binding Table****************************************/
287
288 /**
289 * @brief Shader Binding Table Buffer.
290 */
292
293 /**
294 * @brief Ray Generation Region.
295 */
297
298 /**
299 * @brief Ray Missing Region.
300 */
302
303 /**
304 * @brief Ray Hit Region.
305 */
307
308 /**
309 * @brief Ray Callable Region.
310 */
312
313 /*****************************************************************************************/
314
315 /**************************************Mesh Description***********************************/
316
317 /**
318 * @brief Scene Mesh Description Buffer
319 */
321
322 /*****************************************************************************************/
323 };
324
325 template<class T>
327 const std::vector<T>& instances ,
328 VkBuildAccelerationStructureFlagsKHR flags ,
329 bool update ,
330 bool motion
331 )
332 {
334
335 /**
336 * @brief Cannot call buildTlas twice except to update.
337 */
338 assert(m_tlas.accel == VK_NULL_HANDLE || update);
339 const uint32_t countInstance = static_cast<uint32_t>(instances.size());
340
341 /**
342 * @brief Create a buffer holding the actual instance data (matrices++) for use by the AS builder.
343 */
344 VulkanBuffer instancesBuffer(
345 m_VulkanState ,
346 "TLASInstancesBuffer" ,
347 sizeof(T) * instances.size() ,
348 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
349 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
350 VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR ,
351 0
352 );
353
354 VulkanBuffer stagingBuffer(
355 m_VulkanState ,
356 "StagingBuffer" ,
357 sizeof(T) * instances.size() ,
358 VK_BUFFER_USAGE_TRANSFER_SRC_BIT ,
359 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
360 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
361 );
362
363 stagingBuffer.WriteToBuffer(instances.data());
364
365 instancesBuffer.CopyBuffer(stagingBuffer.Get(), instancesBuffer.Get(), sizeof(T) * instances.size());
366
367 const VkDeviceAddress instBufferAddr = instancesBuffer.GetAddress();
368
369 /**
370 * @brief Command buffer to create the TLAS.
371 */
372 std::unique_ptr<VulkanBuffer> scratchBuffer = nullptr;
373 VulkanCommandBuffer::CustomGraphicCmd(m_VulkanState, [&](const VkCommandBuffer& commandBuffer) {
374
375 /**
376 * @brief Make sure the copy of the instance buffer are copied before triggering the acceleration structure build.
377 */
378 VkMemoryBarrier barrier{};
379 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
380 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
381 barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
382
383 vkCmdPipelineBarrier(
384 commandBuffer ,
385 VK_PIPELINE_STAGE_TRANSFER_BIT ,
386 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR ,
387 0 ,
388 1 ,
389 &barrier ,
390 0 ,
391 nullptr ,
392 0 ,
393 nullptr
394 );
395
396 CmdCreateTLAS(
397 commandBuffer ,
398 countInstance ,
399 instBufferAddr ,
400 scratchBuffer ,
401 flags ,
402 update ,
403 motion
404 );
405 });
406 }
407}
#define SPICES_PROFILE_ZONEN(...)
#define SPICES_PROFILE_ZONE
static FrameInfo & Get()
Get FrameInfo.
Definition FrameInfo.cpp:14
RendererType m_RendererType
The renderer type of current world.
Definition FrameInfo.h:99
FrameInfo Class. This class defines the FrameInfo data.
Definition FrameInfo.h:32
Material Class. This class contains a branch of parameter and shader, also descriptor.
Definition Material.h:62
MeshComponent Class. This class defines the specific behaves of MeshComponent.
virtual void CreateDescriptorSet() override
The interface is inherited from Renderer. Create specific descriptor set for sub pass.
static std::shared_ptr< VulkanRayTracing > m_VulkanRayTracing
In Used VulkanRayTracing.
void CreateTopLevelAS(FrameInfo &frameInfo, std::shared_ptr< std::vector< uint32_t > > view, std::shared_ptr< VulkanRayTracing > rayTracingInstance, bool update=false)
Create TopLevelAS.
static VkAccelerationStructureKHR GetAccelerationStructure()
Get RayTracing AccelerationStructure.
void SetHitGroupsCache(std::shared_ptr< std::unordered_map< std::string, uint32_t > > cache)
Set HitGroupsCache.
virtual void CreatePipeline(std::shared_ptr< Material > material, VkPipelineLayout &layout, std::shared_ptr< RendererSubPass > subPass) override
The interface is inherited from Renderer. Create Material Specific Pipeline.
virtual void Render(TimeStep &ts, FrameInfo &frameInfo) override
The interface is inherited from Renderer.
RayTracingRenderer(const std::string &rendererName, VulkanState &vulkanState, const std::shared_ptr< VulkanDescriptorPool > &descriptorPool, const std::shared_ptr< VulkanDevice > &device, const std::shared_ptr< RendererResourcePool > &rendererResourcePool)
Constructor Function. Init member variables.
virtual void OnMeshAddedWorld() override
virtual ~RayTracingRenderer() override
Destructor Function.
std::shared_ptr< std::unordered_map< std::string, uint32_t > > GetHitGroupsCache()
Get HitGroupsCache.
std::shared_ptr< std::unordered_map< std::string, uint32_t > > m_HitGroupsCache
Hit groups cached data.
void CreateRTShaderBindingTable(std::shared_ptr< VulkanRayTracing > rayTracingInstance)
Create Shader Binding Table.
virtual void CreateRendererPass() override
The interface is inherited from Renderer. Create specific render pass.
void CreateBottomLevelAS(FrameInfo &frameInfo, std::shared_ptr< std::vector< uint32_t > > view, std::shared_ptr< VulkanRayTracing > rayTracingInstance)
Create BottomLevelAS with all MeshComponents.
void UpdateTopLevelAS(FrameInfo &frameInfo, std::shared_ptr< VulkanRayTracing > rayTracingInstance, bool update=true)
Update TopLevelAS.
RayTracingRenderer Class. This class defines the ray tracing behaves.
RendererResourcePool Class. This class is a pool of all framebuffer's attachment.
This Class Combines some data relative to sub pass. Usually as a member variable of RendererPass.
virtual void EndRenderPass() override
End this Renderer's RenderPass.
void TraceRays() const
Call vkCmdTraceRaysKHR here.
virtual void BeginRenderPass() override
Begin this Renderer's RenderPass.
This class helps to bind pipeline and bind buffer. Specific for RayTracing Renderer....
Definition Renderer.h:1558
RendererPassBuilder & EndSubPass()
End recording a sub pass.
void Build() const
Build the RendererPass.
RendererPassBuilder & AddSubPass(const std::string &subPassName, Querier::StatisticsFlags flags=Querier::ALL)
Add a new SubPass to Renderer Pass.
virtual void OnMeshAddedWorld()
Definition Renderer.cpp:86
Renderer(const std::string &rendererName, VulkanState &vulkanState, const std::shared_ptr< VulkanDescriptorPool > &DescriptorPool, const std::shared_ptr< VulkanDevice > &device, const std::shared_ptr< RendererResourcePool > &rendererResourcePool, bool isLoadDefaultMaterial=true)
Constructor Function. Init member variables.
Definition Renderer.cpp:16
void GetDirectionalLight(FrameInfo &frameInfo, std::array< SpicesShader::DirectionalLight, SpicesShader::DIRECTIONALLIGHT_BUFFER_MAXNUM > &dLightBuffer)
Get DirectionalLightComponent's render data in World.
Definition Renderer.cpp:371
void GetPointLight(FrameInfo &frameInfo, std::array< SpicesShader::PointLight, SpicesShader::POINTLIGHT_BUFFER_MAXNUM > &pLightBuffer)
Get PointLightComponent's render data in World.
Definition Renderer.cpp:445
Renderer Class. This class defines the basic behaves of renderer. When we add an new Renderer,...
Definition Renderer.h:57
SkyBoxComponent Class. This class defines the specific behaves of SkyBoxComponent.
This Class handles our engine time step during frames. Global Unique.
Definition TimeStep.h:22
TransformComponent Class. This class defines the specific behaves of TransformComponent.
This Class is a Wrapper of VulkanBuffer.
VulkanCommandBuffer Class. This class defines the VulkanCommandBuffer behaves. This class is just a w...
VulkanDescriptorPool Class. This class is the wrapper of VkDescriptorPool.
VulkanInstance Class. This class defines the VulkanDevice behave. This class is just a wrapper of vkd...
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
VulkanObject Class. This class defines the basic behaves of VulkanObject. When we create an new Vulka...
This Class is a Wrapper of VulkanQueryPool.
VkStridedDeviceAddressRegionKHR m_MissRegion
Ray Missing Region.
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....
VkStridedDeviceAddressRegionKHR & GetCallRegion()
Get SBT CallRegion.
void BuildTLAS(const std::vector< T > &instances, VkBuildAccelerationStructureFlagsKHR flags=VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, bool update=false, bool motion=false)
Build TLAS from an array of VkAccelerationStructureInstanceKHR. The resulting TLAS will be stored in ...
std::unique_ptr< VulkanBuffer > m_RTSBTBuffer
Shader Binding Table Buffer.
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.
VkStridedDeviceAddressRegionKHR & GetMissRegion()
Get SBT MissRegion.
std::shared_ptr< std::unordered_map< std::string, uint32_t > > m_HitGroups
Scene ray hit shader groups.
VkStridedDeviceAddressRegionKHR m_HitRegion
Ray Hit Region.
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.
const VkAccelerationStructureKHR GetAccelerationStructure() const
Get AccelerationStructure.
VkStridedDeviceAddressRegionKHR m_CallRegion
Ray Callable Region.
AccelKHR m_tlas
Top-level acceleration structure.
VkStridedDeviceAddressRegionKHR m_RgenRegion
Ray Generation Region.
VkStridedDeviceAddressRegionKHR & GetRgenRegion()
Get SBT RgenRegion.
Attribute< uint64_t > & GetMeshDesc()
Get Mesh Description.
void SetHitGroups(std::shared_ptr< std::unordered_map< std::string, uint32_t > > groups)
Set Scene hit groups.
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.
virtual ~VulkanRayTracing() override=default
Destructor Function.
VkStridedDeviceAddressRegionKHR & GetHitRegion()
Get SBT HitRegion.
std::shared_ptr< std::unordered_map< std::string, uint32_t > > GetHitGroups()
Get Scene hit groups.
Attribute< uint64_t > m_MeshDesc
Scene Mesh Description Buffer.
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.
@ NeedUpdateTLAS
Definition World.h:49
World Class. This class defines the basic behaves of World. When we create an new world,...
Definition World.h:41
RendererType
Definition FrameInfo.h:22
AccelStructure Wrapper.
Definition Attribute.h:17
MeshResource's item template.
Definition Attribute.h:28
std::array< uint64_t, SpicesShader::MESH_BUFFER_MAXNUM > descs
std::array< SpicesShader::DirectionalLight, SpicesShader::DIRECTIONALLIGHT_BUFFER_MAXNUM > lights
std::array< SpicesShader::PointLight, SpicesShader::POINTLIGHT_BUFFER_MAXNUM > lights
std::vector< VkAccelerationStructureGeometryKHR > asGeometry
std::vector< VkAccelerationStructureBuildRangeInfoKHR > asBuildOffsetInfo
VkBuildAccelerationStructureFlagsKHR flags
const VkAccelerationStructureBuildRangeInfoKHR * rangeInfo
VkAccelerationStructureBuildGeometryInfoKHR buildInfo
VkAccelerationStructureBuildSizesInfoKHR sizeInfo
AccelerationStructure Build Info and result.
This struct contains all Vulkan object in used global.
Definition VulkanUtils.h:74