RenderGraph.h 21 KB

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