RenderGraph.h 21 KB

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