RenderGraph.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Gr/GrObject.h>
  7. #include <AnKi/Gr/Enums.h>
  8. #include <AnKi/Gr/TextureView.h>
  9. #include <AnKi/Gr/Buffer.h>
  10. #include <AnKi/Gr/GrManager.h>
  11. #include <AnKi/Gr/Framebuffer.h>
  12. #include <AnKi/Gr/TimestampQuery.h>
  13. #include <AnKi/Gr/CommandBuffer.h>
  14. #include <AnKi/Gr/AccelerationStructure.h>
  15. #include <AnKi/Util/HashMap.h>
  16. #include <AnKi/Util/BitSet.h>
  17. #include <AnKi/Util/WeakArray.h>
  18. #include <AnKi/Util/Function.h>
  19. namespace anki
  20. {
  21. // Forward
  22. class RenderGraph;
  23. class RenderGraphDescription;
  24. /// @addtogroup graphics
  25. /// @{
  26. /// @name RenderGraph constants
  27. /// @{
  28. constexpr U32 MAX_RENDER_GRAPH_PASSES = 128;
  29. constexpr U32 MAX_RENDER_GRAPH_RENDER_TARGETS = 64; ///< Max imported or not render targets in RenderGraph.
  30. constexpr U32 MAX_RENDER_GRAPH_BUFFERS = 64;
  31. constexpr U32 MAX_RENDER_GRAPH_ACCELERATION_STRUCTURES = 32;
  32. /// @}
  33. /// Render target handle used in the RenderGraph.
  34. /// @memberof RenderGraphDescription
  35. class RenderGraphGrObjectHandle
  36. {
  37. friend class RenderPassDependency;
  38. friend class RenderGraphDescription;
  39. friend class RenderGraph;
  40. friend class RenderPassDescriptionBase;
  41. public:
  42. Bool operator==(const RenderGraphGrObjectHandle& b) const
  43. {
  44. return m_idx == b.m_idx;
  45. }
  46. Bool operator!=(const RenderGraphGrObjectHandle& b) const
  47. {
  48. return m_idx != b.m_idx;
  49. }
  50. Bool isValid() const
  51. {
  52. return m_idx != MAX_U32;
  53. }
  54. private:
  55. U32 m_idx = MAX_U32;
  56. };
  57. /// Render target (TexturePtr) handle.
  58. /// @memberof RenderGraphDescription
  59. class RenderTargetHandle : public RenderGraphGrObjectHandle
  60. {
  61. };
  62. /// BufferPtr handle.
  63. /// @memberof RenderGraphDescription
  64. class BufferHandle : public RenderGraphGrObjectHandle
  65. {
  66. };
  67. /// AccelerationStructurePtr handle.
  68. /// @memberof RenderGraphDescription
  69. class AccelerationStructureHandle : public RenderGraphGrObjectHandle
  70. {
  71. };
  72. /// Describes the render target.
  73. /// @memberof RenderGraphDescription
  74. class RenderTargetDescription : public TextureInitInfo
  75. {
  76. friend class RenderGraphDescription;
  77. public:
  78. RenderTargetDescription()
  79. {
  80. }
  81. RenderTargetDescription(CString name)
  82. : TextureInitInfo(name)
  83. {
  84. }
  85. /// Create an internal hash.
  86. void bake()
  87. {
  88. ANKI_ASSERT(m_hash == 0);
  89. ANKI_ASSERT(m_usage == TextureUsageBit::NONE && "No need to supply the usage. RenderGraph will find out");
  90. m_hash = computeHash();
  91. }
  92. private:
  93. U64 m_hash = 0;
  94. };
  95. /// The only parameter of RenderPassWorkCallback.
  96. /// @memberof RenderGraph
  97. class RenderPassWorkContext
  98. {
  99. friend class RenderGraph;
  100. public:
  101. CommandBufferPtr m_commandBuffer;
  102. U32 m_currentSecondLevelCommandBufferIndex ANKI_DEBUG_CODE(= 0);
  103. U32 m_secondLevelCommandBufferCount ANKI_DEBUG_CODE(= 0);
  104. void getBufferState(BufferHandle handle, BufferPtr& buff) const;
  105. void getRenderTargetState(RenderTargetHandle handle, const TextureSubresourceInfo& subresource,
  106. TexturePtr& tex) const;
  107. /// Convenience method.
  108. void bindTextureAndSampler(U32 set, U32 binding, RenderTargetHandle handle,
  109. const TextureSubresourceInfo& subresource, const SamplerPtr& sampler)
  110. {
  111. TexturePtr tex;
  112. getRenderTargetState(handle, subresource, tex);
  113. TextureViewInitInfo viewInit(tex, subresource, "TmpRenderGraph");
  114. TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
  115. m_commandBuffer->bindTextureAndSampler(set, binding, view, sampler);
  116. }
  117. /// Convenience method.
  118. void bindTexture(U32 set, U32 binding, RenderTargetHandle handle, const TextureSubresourceInfo& subresource)
  119. {
  120. TexturePtr tex;
  121. getRenderTargetState(handle, subresource, tex);
  122. TextureViewInitInfo viewInit(tex, subresource, "TmpRenderGraph");
  123. TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
  124. m_commandBuffer->bindTexture(set, binding, view);
  125. }
  126. /// Convenience method to bind the whole texture as color.
  127. void bindColorTextureAndSampler(U32 set, U32 binding, RenderTargetHandle handle, const SamplerPtr& sampler)
  128. {
  129. TexturePtr tex = getTexture(handle);
  130. TextureViewInitInfo viewInit(tex); // Use the whole texture
  131. getRenderTargetState(handle, viewInit, tex);
  132. TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
  133. m_commandBuffer->bindTextureAndSampler(set, binding, view, sampler);
  134. }
  135. /// Convenience method to bind the whole texture as color.
  136. void bindColorTexture(U32 set, U32 binding, RenderTargetHandle handle, U32 arrayIdx = 0)
  137. {
  138. TexturePtr tex = getTexture(handle);
  139. TextureViewInitInfo viewInit(tex); // Use the whole texture
  140. getRenderTargetState(handle, viewInit, tex);
  141. TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
  142. m_commandBuffer->bindTexture(set, binding, view, arrayIdx);
  143. }
  144. /// Convenience method.
  145. void bindImage(U32 set, U32 binding, RenderTargetHandle handle, const TextureSubresourceInfo& subresource,
  146. U32 arrayIdx = 0)
  147. {
  148. TexturePtr tex;
  149. getRenderTargetState(handle, subresource, tex);
  150. TextureViewInitInfo viewInit(tex, subresource, "TmpRenderGraph");
  151. TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
  152. m_commandBuffer->bindImage(set, binding, view, arrayIdx);
  153. }
  154. /// Convenience method to bind the whole image.
  155. void bindImage(U32 set, U32 binding, RenderTargetHandle handle, U32 arrayIdx = 0)
  156. {
  157. TexturePtr tex;
  158. #if ANKI_ENABLE_ASSERTIONS
  159. tex = getTexture(handle);
  160. ANKI_ASSERT(tex->getLayerCount() == 1 && tex->getMipmapCount() == 1
  161. && tex->getDepthStencilAspect() == DepthStencilAspectBit::NONE);
  162. #endif
  163. const TextureSubresourceInfo subresource;
  164. getRenderTargetState(handle, subresource, tex);
  165. TextureViewInitInfo viewInit(tex, subresource, "TmpRenderGraph");
  166. TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
  167. m_commandBuffer->bindImage(set, binding, view, arrayIdx);
  168. }
  169. /// Convenience method.
  170. void bindStorageBuffer(U32 set, U32 binding, BufferHandle handle)
  171. {
  172. BufferPtr buff;
  173. getBufferState(handle, buff);
  174. m_commandBuffer->bindStorageBuffer(set, binding, buff, 0, MAX_PTR_SIZE);
  175. }
  176. /// Convenience method.
  177. void bindUniformBuffer(U32 set, U32 binding, BufferHandle handle)
  178. {
  179. BufferPtr buff;
  180. getBufferState(handle, buff);
  181. m_commandBuffer->bindUniformBuffer(set, binding, buff, 0, MAX_PTR_SIZE);
  182. }
  183. /// Convenience method.
  184. void bindAccelerationStructure(U32 set, U32 binding, AccelerationStructureHandle handle);
  185. private:
  186. const RenderGraph* m_rgraph ANKI_DEBUG_CODE(= nullptr);
  187. U32 m_passIdx ANKI_DEBUG_CODE(= MAX_U32);
  188. U32 m_batchIdx ANKI_DEBUG_CODE(= MAX_U32);
  189. TexturePtr getTexture(RenderTargetHandle handle) const;
  190. };
  191. /// RenderGraph pass dependency.
  192. /// @memberof RenderGraphDescription
  193. class RenderPassDependency
  194. {
  195. friend class RenderGraph;
  196. friend class RenderPassDescriptionBase;
  197. public:
  198. /// Dependency to a texture subresource.
  199. RenderPassDependency(RenderTargetHandle handle, TextureUsageBit usage, const TextureSubresourceInfo& subresource)
  200. : m_texture({handle, usage, subresource})
  201. , m_type(Type::TEXTURE)
  202. {
  203. ANKI_ASSERT(handle.isValid());
  204. }
  205. /// Dependency to the whole texture.
  206. RenderPassDependency(RenderTargetHandle handle, TextureUsageBit usage,
  207. DepthStencilAspectBit aspect = DepthStencilAspectBit::NONE)
  208. : m_texture({handle, usage, TextureSubresourceInfo()})
  209. , m_type(Type::TEXTURE)
  210. {
  211. ANKI_ASSERT(handle.isValid());
  212. m_texture.m_subresource.m_mipmapCount = MAX_U32; // Mark it as "whole texture"
  213. m_texture.m_subresource.m_depthStencilAspect = aspect;
  214. }
  215. RenderPassDependency(BufferHandle handle, BufferUsageBit usage)
  216. : m_buffer({handle, usage})
  217. , m_type(Type::BUFFER)
  218. {
  219. ANKI_ASSERT(handle.isValid());
  220. }
  221. RenderPassDependency(AccelerationStructureHandle handle, AccelerationStructureUsageBit usage)
  222. : m_as({handle, usage})
  223. , m_type(Type::ACCELERATION_STRUCTURE)
  224. {
  225. ANKI_ASSERT(handle.isValid());
  226. }
  227. private:
  228. class TextureInfo
  229. {
  230. public:
  231. RenderTargetHandle m_handle;
  232. TextureUsageBit m_usage;
  233. TextureSubresourceInfo m_subresource;
  234. };
  235. class BufferInfo
  236. {
  237. public:
  238. BufferHandle m_handle;
  239. BufferUsageBit m_usage;
  240. };
  241. class ASInfo
  242. {
  243. public:
  244. AccelerationStructureHandle m_handle;
  245. AccelerationStructureUsageBit m_usage;
  246. };
  247. union
  248. {
  249. TextureInfo m_texture;
  250. BufferInfo m_buffer;
  251. ASInfo m_as;
  252. };
  253. enum class Type : U8
  254. {
  255. BUFFER,
  256. TEXTURE,
  257. ACCELERATION_STRUCTURE
  258. };
  259. Type m_type;
  260. };
  261. /// The base of compute/transfer and graphics renderpasses for RenderGraph.
  262. /// @memberof RenderGraphDescription
  263. class RenderPassDescriptionBase
  264. {
  265. friend class RenderGraph;
  266. friend class RenderGraphDescription;
  267. public:
  268. virtual ~RenderPassDescriptionBase()
  269. {
  270. m_name.destroy(m_alloc); // To avoid the assertion
  271. m_rtDeps.destroy(m_alloc);
  272. m_buffDeps.destroy(m_alloc);
  273. m_asDeps.destroy(m_alloc);
  274. m_callback.destroy(m_alloc);
  275. }
  276. template<typename TFunc>
  277. void setWork(U32 secondLeveCmdbCount, TFunc func)
  278. {
  279. ANKI_ASSERT(m_type == Type::GRAPHICS || secondLeveCmdbCount == 0);
  280. m_callback.init(m_alloc, func);
  281. m_secondLevelCmdbsCount = secondLeveCmdbCount;
  282. }
  283. template<typename TFunc>
  284. void setWork(TFunc func)
  285. {
  286. setWork(0, func);
  287. }
  288. /// Add a new consumer or producer dependency.
  289. void newDependency(const RenderPassDependency& dep);
  290. protected:
  291. enum class Type : U8
  292. {
  293. GRAPHICS,
  294. NO_GRAPHICS
  295. };
  296. Type m_type;
  297. StackAllocator<U8> m_alloc;
  298. RenderGraphDescription* m_descr;
  299. Function<void(RenderPassWorkContext&)> m_callback;
  300. U32 m_secondLevelCmdbsCount = 0;
  301. DynamicArray<RenderPassDependency> m_rtDeps;
  302. DynamicArray<RenderPassDependency> m_buffDeps;
  303. DynamicArray<RenderPassDependency> m_asDeps;
  304. BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_readRtMask{false};
  305. BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_writeRtMask{false};
  306. BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_readBuffMask{false};
  307. BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_writeBuffMask{false};
  308. BitSet<MAX_RENDER_GRAPH_ACCELERATION_STRUCTURES, U32> m_readAsMask{false};
  309. BitSet<MAX_RENDER_GRAPH_ACCELERATION_STRUCTURES, U32> m_writeAsMask{false};
  310. String m_name;
  311. RenderPassDescriptionBase(Type t, RenderGraphDescription* descr)
  312. : m_type(t)
  313. , m_descr(descr)
  314. {
  315. ANKI_ASSERT(descr);
  316. }
  317. void setName(CString name)
  318. {
  319. m_name.create(m_alloc, (name.isEmpty()) ? "N/A" : name);
  320. }
  321. void fixSubresource(RenderPassDependency& dep) const;
  322. void validateDep(const RenderPassDependency& dep);
  323. };
  324. /// Framebuffer attachment info.
  325. class FramebufferDescriptionAttachment
  326. {
  327. public:
  328. TextureSurfaceInfo m_surface;
  329. AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::CLEAR;
  330. AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::STORE;
  331. ClearValue m_clearValue;
  332. AttachmentLoadOperation m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
  333. AttachmentStoreOperation m_stencilStoreOperation = AttachmentStoreOperation::STORE;
  334. DepthStencilAspectBit m_aspect = DepthStencilAspectBit::NONE; ///< Relevant only for depth stencil textures.
  335. };
  336. /// Describes a framebuffer.
  337. /// @memberof RenderGraphDescription
  338. class FramebufferDescription
  339. {
  340. friend class GraphicsRenderPassDescription;
  341. friend class RenderGraph;
  342. public:
  343. Array<FramebufferDescriptionAttachment, MAX_COLOR_ATTACHMENTS> m_colorAttachments;
  344. U32 m_colorAttachmentCount = 0;
  345. FramebufferDescriptionAttachment m_depthStencilAttachment;
  346. /// Calculate the hash for the framebuffer.
  347. void bake();
  348. Bool isBacked() const
  349. {
  350. return m_hash != 0;
  351. }
  352. private:
  353. U64 m_hash = 0;
  354. };
  355. /// A graphics render pass for RenderGraph.
  356. /// @memberof RenderGraphDescription
  357. class GraphicsRenderPassDescription : public RenderPassDescriptionBase
  358. {
  359. friend class RenderGraphDescription;
  360. friend class RenderGraph;
  361. template<typename, typename>
  362. friend class GenericPoolAllocator;
  363. public:
  364. void setFramebufferInfo(const FramebufferDescription& fbInfo,
  365. ConstWeakArray<RenderTargetHandle> colorRenderTargetHandles,
  366. RenderTargetHandle depthStencilRenderTargetHandle, U32 minx = 0, U32 miny = 0,
  367. U32 maxx = MAX_U32, U32 maxy = MAX_U32);
  368. void setFramebufferInfo(const FramebufferDescription& fbInfo,
  369. std::initializer_list<RenderTargetHandle> colorRenderTargetHandles,
  370. RenderTargetHandle depthStencilRenderTargetHandle, U32 minx = 0, U32 miny = 0,
  371. U32 maxx = MAX_U32, U32 maxy = MAX_U32);
  372. private:
  373. Array<RenderTargetHandle, MAX_COLOR_ATTACHMENTS + 1> m_rtHandles;
  374. FramebufferDescription m_fbDescr;
  375. Array<U32, 4> m_fbRenderArea = {};
  376. GraphicsRenderPassDescription(RenderGraphDescription* descr)
  377. : RenderPassDescriptionBase(Type::GRAPHICS, descr)
  378. {
  379. memset(&m_rtHandles[0], 0xFF, sizeof(m_rtHandles));
  380. }
  381. Bool hasFramebuffer() const
  382. {
  383. return m_fbDescr.m_hash != 0;
  384. }
  385. };
  386. /// A compute render pass for RenderGraph.
  387. /// @memberof RenderGraphDescription
  388. class ComputeRenderPassDescription : public RenderPassDescriptionBase
  389. {
  390. friend class RenderGraphDescription;
  391. template<typename, typename>
  392. friend class GenericPoolAllocator;
  393. private:
  394. ComputeRenderPassDescription(RenderGraphDescription* descr)
  395. : RenderPassDescriptionBase(Type::NO_GRAPHICS, descr)
  396. {
  397. }
  398. };
  399. /// Builds the description of the frame's render passes and their interactions.
  400. /// @memberof RenderGraph
  401. class RenderGraphDescription
  402. {
  403. friend class RenderGraph;
  404. friend class RenderPassDescriptionBase;
  405. public:
  406. RenderGraphDescription(const StackAllocator<U8>& alloc)
  407. : m_alloc(alloc)
  408. {
  409. }
  410. ~RenderGraphDescription();
  411. /// Create a new graphics render pass.
  412. GraphicsRenderPassDescription& newGraphicsRenderPass(CString name);
  413. /// Create a new compute render pass.
  414. ComputeRenderPassDescription& newComputeRenderPass(CString name);
  415. /// Import an existing render target and let the render graph know about it's up-to-date usage.
  416. RenderTargetHandle importRenderTarget(TexturePtr tex, TextureUsageBit usage);
  417. /// Import an existing render target and let the render graph find it's current usage by looking at the previous
  418. /// frame.
  419. RenderTargetHandle importRenderTarget(TexturePtr tex);
  420. /// Get or create a new render target.
  421. RenderTargetHandle newRenderTarget(const RenderTargetDescription& initInf);
  422. /// Import a buffer.
  423. BufferHandle importBuffer(BufferPtr buff, BufferUsageBit usage, PtrSize offset = 0, PtrSize range = MAX_PTR_SIZE);
  424. /// Import an AS.
  425. AccelerationStructureHandle importAccelerationStructure(AccelerationStructurePtr as,
  426. AccelerationStructureUsageBit usage);
  427. /// Gather statistics.
  428. void setStatisticsEnabled(Bool gather)
  429. {
  430. m_gatherStatistics = gather;
  431. }
  432. private:
  433. class Resource
  434. {
  435. public:
  436. Array<char, MAX_GR_OBJECT_NAME_LENGTH + 1> m_name;
  437. void setName(CString name)
  438. {
  439. const U len = name.getLength();
  440. ANKI_ASSERT(len <= MAX_GR_OBJECT_NAME_LENGTH);
  441. strcpy(&m_name[0], (len) ? &name[0] : "unnamed");
  442. }
  443. };
  444. class RT : public Resource
  445. {
  446. public:
  447. TextureInitInfo m_initInfo;
  448. U64 m_hash = 0;
  449. TexturePtr m_importedTex;
  450. TextureUsageBit m_importedLastKnownUsage = TextureUsageBit::NONE;
  451. /// Derived by the deps of this RT and will be used to set its usage.
  452. TextureUsageBit m_usageDerivedByDeps = TextureUsageBit::NONE;
  453. Bool m_importedAndUndefinedUsage = false;
  454. };
  455. class Buffer : public Resource
  456. {
  457. public:
  458. BufferUsageBit m_usage;
  459. BufferPtr m_importedBuff;
  460. PtrSize m_offset;
  461. PtrSize m_range;
  462. };
  463. class AS : public Resource
  464. {
  465. public:
  466. AccelerationStructurePtr m_importedAs;
  467. AccelerationStructureUsageBit m_usage;
  468. };
  469. StackAllocator<U8> m_alloc;
  470. DynamicArray<RenderPassDescriptionBase*> m_passes;
  471. DynamicArray<RT> m_renderTargets;
  472. DynamicArray<Buffer> m_buffers;
  473. DynamicArray<AS> m_as;
  474. Bool m_gatherStatistics = false;
  475. /// Return true if 2 buffer ranges overlap.
  476. static Bool bufferRangeOverlaps(PtrSize offsetA, PtrSize rangeA, PtrSize offsetB, PtrSize rangeB)
  477. {
  478. ANKI_ASSERT(rangeA > 0 && rangeB > 0);
  479. if(rangeA == MAX_PTR_SIZE || rangeB == MAX_PTR_SIZE)
  480. {
  481. return true;
  482. }
  483. else if(offsetA <= offsetB)
  484. {
  485. return offsetA + rangeA >= offsetB;
  486. }
  487. else
  488. {
  489. return offsetB + rangeB >= offsetA;
  490. }
  491. }
  492. };
  493. /// Statistics.
  494. /// @memberof RenderGraph
  495. class RenderGraphStatistics
  496. {
  497. public:
  498. Second m_gpuTime; ///< Time spent in the GPU.
  499. Second m_cpuStartTime; ///< Time the work was submited from the CPU (almost)
  500. };
  501. /// Accepts a descriptor of the frame's render passes and sets the dependencies between them.
  502. ///
  503. /// The idea for the RenderGraph is to automate:
  504. /// - Synchronization (barriers, events etc) between passes.
  505. /// - Command buffer creation for primary and secondary command buffers.
  506. /// - Framebuffer creation.
  507. /// - Render target creation (optional since textures can be imported as well).
  508. ///
  509. /// It accepts a description of the frame's render passes (compute and graphics), compiles that description to calculate
  510. /// dependencies and then populates command buffers with the help of multiple RenderPassWorkCallback.
  511. class RenderGraph final : public GrObject
  512. {
  513. ANKI_GR_OBJECT
  514. friend class RenderPassWorkContext;
  515. public:
  516. static const GrObjectType CLASS_TYPE = GrObjectType::RENDER_GRAPH;
  517. /// @name 1st step methods
  518. /// @{
  519. void compileNewGraph(const RenderGraphDescription& descr, StackAllocator<U8>& alloc);
  520. /// @}
  521. /// @name 2nd step methods
  522. /// @{
  523. /// Will call a number of RenderPassWorkCallback that populate 2nd level command buffers.
  524. void runSecondLevel(U32 threadIdx);
  525. /// @}
  526. /// @name 3rd step methods
  527. /// @{
  528. /// Will call a number of RenderPassWorkCallback that populate 1st level command buffers.
  529. void run() const;
  530. /// @}
  531. /// @name 3rd step methods
  532. /// @{
  533. void flush();
  534. /// @}
  535. /// @name 4th step methods
  536. /// @{
  537. /// Reset the graph for a new frame. All previously created RenderGraphHandle are invalid after that call.
  538. void reset();
  539. /// @}
  540. /// @name 5th step methods [OPTIONAL]
  541. /// @{
  542. /// Get some statistics.
  543. void getStatistics(RenderGraphStatistics& statistics) const;
  544. /// @}
  545. private:
  546. static constexpr U PERIODIC_CLEANUP_EVERY = 60; ///< How many frames between cleanups.
  547. // Forward declarations of internal classes.
  548. class BakeContext;
  549. class Pass;
  550. class Batch;
  551. class RT;
  552. class Buffer;
  553. class AS;
  554. class TextureBarrier;
  555. class BufferBarrier;
  556. class ASBarrier;
  557. /// Render targets of the same type+size+format.
  558. class RenderTargetCacheEntry
  559. {
  560. public:
  561. DynamicArray<TexturePtr> m_textures;
  562. U32 m_texturesInUse = 0;
  563. };
  564. /// Info on imported render targets that are kept between runs.
  565. class ImportedRenderTargetInfo
  566. {
  567. public:
  568. DynamicArray<TextureUsageBit> m_surfOrVolLastUsages; ///< Last TextureUsageBit of the imported RT.
  569. };
  570. HashMap<U64, RenderTargetCacheEntry> m_renderTargetCache; ///< Non-imported render targets.
  571. HashMap<U64, FramebufferPtr> m_fbCache; ///< Framebuffer cache.
  572. HashMap<U64, ImportedRenderTargetInfo> m_importedRenderTargets;
  573. BakeContext* m_ctx = nullptr;
  574. U64 m_version = 0;
  575. static constexpr U MAX_TIMESTAMPS_BUFFERED = MAX_FRAMES_IN_FLIGHT + 1;
  576. class
  577. {
  578. public:
  579. Array<TimestampQueryPtr, MAX_TIMESTAMPS_BUFFERED * 2> m_timestamps;
  580. Array<Second, MAX_TIMESTAMPS_BUFFERED> m_cpuStartTimes;
  581. U8 m_nextTimestamp = 0;
  582. } m_statistics;
  583. RenderGraph(GrManager* manager, CString name);
  584. ~RenderGraph();
  585. static ANKI_USE_RESULT RenderGraph* newInstance(GrManager* manager);
  586. BakeContext* newContext(const RenderGraphDescription& descr, StackAllocator<U8>& alloc);
  587. void initRenderPassesAndSetDeps(const RenderGraphDescription& descr, StackAllocator<U8>& alloc);
  588. void initBatches();
  589. void initGraphicsPasses(const RenderGraphDescription& descr, StackAllocator<U8>& alloc);
  590. void setBatchBarriers(const RenderGraphDescription& descr);
  591. TexturePtr getOrCreateRenderTarget(const TextureInitInfo& initInf, U64 hash);
  592. FramebufferPtr getOrCreateFramebuffer(const FramebufferDescription& fbDescr, const RenderTargetHandle* rtHandles,
  593. CString name, Bool& drawsToPresentableTex);
  594. /// Every N number of frames clean unused cached items.
  595. void periodicCleanup();
  596. ANKI_HOT static Bool passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b);
  597. static Bool overlappingTextureSubresource(const TextureSubresourceInfo& suba, const TextureSubresourceInfo& subb);
  598. static Bool passHasUnmetDependencies(const BakeContext& ctx, U32 passIdx);
  599. void setTextureBarrier(Batch& batch, const RenderPassDependency& consumer);
  600. template<typename TFunc>
  601. static void iterateSurfsOrVolumes(const TexturePtr& tex, const TextureSubresourceInfo& subresource, TFunc func);
  602. void getCrntUsage(RenderTargetHandle handle, U32 batchIdx, const TextureSubresourceInfo& subresource,
  603. TextureUsageBit& usage) const;
  604. /// @name Dump the dependency graph into a file.
  605. /// @{
  606. ANKI_USE_RESULT Error dumpDependencyDotFile(const RenderGraphDescription& descr, const BakeContext& ctx,
  607. CString path) const;
  608. static StringAuto textureUsageToStr(StackAllocator<U8>& alloc, TextureUsageBit usage);
  609. static StringAuto bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageBit usage);
  610. static StringAuto asUsageToStr(StackAllocator<U8>& alloc, AccelerationStructureUsageBit usage);
  611. /// @}
  612. TexturePtr getTexture(RenderTargetHandle handle) const;
  613. BufferPtr getBuffer(BufferHandle handle) const;
  614. AccelerationStructurePtr getAs(AccelerationStructureHandle handle) const;
  615. };
  616. /// @}
  617. } // end namespace anki
  618. #include <AnKi/Gr/RenderGraph.inl.h>