RenderGraph.inl.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Gr/RenderGraph.h>
  6. namespace anki {
  7. inline void RenderPassWorkContext::bindSrv(U32 reg, U32 space, AccelerationStructureHandle handle)
  8. {
  9. m_commandBuffer->bindSrv(reg, space, m_rgraph->getAs(handle));
  10. }
  11. inline void RenderPassWorkContext::getBufferState(BufferHandle handle, Buffer*& buff, PtrSize& offset, PtrSize& range) const
  12. {
  13. m_rgraph->getCachedBuffer(handle, buff, offset, range);
  14. }
  15. inline void RenderPassWorkContext::getRenderTargetState(RenderTargetHandle handle, const TextureSubresourceDesc& subresource, Texture*& tex) const
  16. {
  17. TextureUsageBit usage;
  18. m_rgraph->getCrntUsage(handle, m_batchIdx, subresource, usage);
  19. tex = &m_rgraph->getTexture(handle);
  20. }
  21. inline Texture& RenderPassWorkContext::getTexture(RenderTargetHandle handle) const
  22. {
  23. return m_rgraph->getTexture(handle);
  24. }
  25. inline void RenderPassBase::validateDep(const RenderPassDependency& dep)
  26. {
  27. // Validate dep
  28. if(dep.m_type == RenderPassDependency::Type::kTexture)
  29. {
  30. [[maybe_unused]] const TextureUsageBit usage = dep.m_texture.m_usage;
  31. if(m_type == Type::kGraphics)
  32. {
  33. ANKI_ASSERT(!(usage & TextureUsageBit::kAllCompute));
  34. }
  35. else
  36. {
  37. ANKI_ASSERT(!(usage & TextureUsageBit::kAllGraphics));
  38. }
  39. ANKI_ASSERT(!!(usage & TextureUsageBit::kAllRead) || !!(usage & TextureUsageBit::kAllWrite));
  40. }
  41. else if(dep.m_type == RenderPassDependency::Type::kBuffer)
  42. {
  43. [[maybe_unused]] const BufferUsageBit usage = dep.m_buffer.m_usage;
  44. if(m_type == Type::kGraphics)
  45. {
  46. ANKI_ASSERT(!(usage & BufferUsageBit::kAllCompute));
  47. }
  48. else
  49. {
  50. ANKI_ASSERT(!(usage & BufferUsageBit::kAllGraphics));
  51. }
  52. ANKI_ASSERT(!!(usage & BufferUsageBit::kAllRead) || !!(usage & BufferUsageBit::kAllWrite));
  53. }
  54. else
  55. {
  56. ANKI_ASSERT(dep.m_type == RenderPassDependency::Type::kAccelerationStructure);
  57. if(m_type == Type::kGraphics)
  58. {
  59. ANKI_ASSERT(!(dep.m_as.m_usage & ~AccelerationStructureUsageBit::kAllGraphics));
  60. }
  61. else
  62. {
  63. ANKI_ASSERT(!(dep.m_as.m_usage & AccelerationStructureUsageBit::kAllGraphics));
  64. }
  65. }
  66. }
  67. template<RenderPassDependency::Type kType>
  68. inline void RenderPassBase::newDependency(const RenderPassDependency& dep)
  69. {
  70. ANKI_ASSERT(kType == dep.m_type);
  71. validateDep(dep);
  72. if(kType == RenderPassDependency::Type::kTexture)
  73. {
  74. RenderPassDependency& newDep = *m_rtDeps.emplaceBack(dep);
  75. // Sanitize a bit
  76. const RenderGraphBuilder::RT& rt = m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx];
  77. if(newDep.m_texture.m_subresource.m_depthStencilAspect == DepthStencilAspectBit::kNone)
  78. {
  79. if(rt.m_importedTex.isCreated() && !!rt.m_importedTex->getDepthStencilAspect())
  80. {
  81. newDep.m_texture.m_subresource.m_depthStencilAspect = rt.m_importedTex->getDepthStencilAspect();
  82. }
  83. else if(!rt.m_importedTex.isCreated() && getFormatInfo(rt.m_initInfo.m_format).isDepthStencil())
  84. {
  85. newDep.m_texture.m_subresource.m_depthStencilAspect = getFormatInfo(rt.m_initInfo.m_format).m_depthStencil;
  86. }
  87. }
  88. if(!!(dep.m_texture.m_usage & TextureUsageBit::kAllRead))
  89. {
  90. m_readRtMask.set(dep.m_texture.m_handle.m_idx);
  91. }
  92. if(!!(dep.m_texture.m_usage & TextureUsageBit::kAllWrite))
  93. {
  94. m_writeRtMask.set(dep.m_texture.m_handle.m_idx);
  95. }
  96. // Try to derive the usage by that dep
  97. m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx].m_usageDerivedByDeps |= dep.m_texture.m_usage;
  98. // Checks
  99. #if ANKI_ASSERTIONS_ENABLED
  100. if((!rt.m_importedTex.isCreated() && !!getFormatInfo(rt.m_initInfo.m_format).m_depthStencil)
  101. || (rt.m_importedTex.isCreated() && !!rt.m_importedTex->getDepthStencilAspect()))
  102. {
  103. ANKI_ASSERT(!!m_rtDeps.getBack().m_texture.m_subresource.m_depthStencilAspect
  104. && "Dependencies of depth/stencil resources should have a valid DS aspect");
  105. }
  106. #endif
  107. }
  108. else if(kType == RenderPassDependency::Type::kBuffer)
  109. {
  110. ANKI_ASSERT(!!(m_descr->m_buffers[dep.m_buffer.m_handle.m_idx].m_importedBuff->getBufferUsage() & dep.m_buffer.m_usage));
  111. m_buffDeps.emplaceBack(dep);
  112. if(!!(dep.m_buffer.m_usage & BufferUsageBit::kAllRead))
  113. {
  114. m_readBuffMask.set(dep.m_buffer.m_handle.m_idx);
  115. }
  116. if(!!(dep.m_buffer.m_usage & BufferUsageBit::kAllWrite))
  117. {
  118. m_writeBuffMask.set(dep.m_buffer.m_handle.m_idx);
  119. }
  120. }
  121. else
  122. {
  123. ANKI_ASSERT(kType == RenderPassDependency::Type::kAccelerationStructure);
  124. m_asDeps.emplaceBack(dep);
  125. if(!!(dep.m_as.m_usage & AccelerationStructureUsageBit::kAllRead))
  126. {
  127. m_readAsMask.set(dep.m_as.m_handle.m_idx);
  128. }
  129. if(!!(dep.m_as.m_usage & AccelerationStructureUsageBit::kAllWrite))
  130. {
  131. m_writeAsMask.set(dep.m_as.m_handle.m_idx);
  132. }
  133. }
  134. }
  135. inline void GraphicsRenderPass::setRenderpassInfo(ConstWeakArray<GraphicsRenderPassTargetDesc> colorRts,
  136. const GraphicsRenderPassTargetDesc* depthStencilRt, const RenderTargetHandle* vrsRt,
  137. U8 vrsRtTexelSizeX, U8 vrsRtTexelSizeY)
  138. {
  139. m_colorRtCount = U8(colorRts.getSize());
  140. for(U32 i = 0; i < m_colorRtCount; ++i)
  141. {
  142. m_rts[i].m_handle = colorRts[i].m_handle;
  143. ANKI_ASSERT(!colorRts[i].m_subresource.m_depthStencilAspect);
  144. m_rts[i].m_subresource = colorRts[i].m_subresource;
  145. m_rts[i].m_loadOperation = colorRts[i].m_loadOperation;
  146. m_rts[i].m_storeOperation = colorRts[i].m_storeOperation;
  147. m_rts[i].m_clearValue = colorRts[i].m_clearValue;
  148. }
  149. if(depthStencilRt)
  150. {
  151. m_rts[kMaxColorRenderTargets].m_handle = depthStencilRt->m_handle;
  152. ANKI_ASSERT(!!depthStencilRt->m_subresource.m_depthStencilAspect);
  153. m_rts[kMaxColorRenderTargets].m_subresource = depthStencilRt->m_subresource;
  154. m_rts[kMaxColorRenderTargets].m_loadOperation = depthStencilRt->m_loadOperation;
  155. m_rts[kMaxColorRenderTargets].m_storeOperation = depthStencilRt->m_storeOperation;
  156. m_rts[kMaxColorRenderTargets].m_stencilLoadOperation = depthStencilRt->m_stencilLoadOperation;
  157. m_rts[kMaxColorRenderTargets].m_stencilStoreOperation = depthStencilRt->m_stencilStoreOperation;
  158. m_rts[kMaxColorRenderTargets].m_clearValue = depthStencilRt->m_clearValue;
  159. }
  160. if(vrsRt)
  161. {
  162. m_rts[kMaxColorRenderTargets + 1].m_handle = *vrsRt;
  163. m_vrsRtTexelSizeX = vrsRtTexelSizeX;
  164. m_vrsRtTexelSizeY = vrsRtTexelSizeY;
  165. }
  166. m_hasRenderpass = true;
  167. }
  168. inline RenderGraphBuilder::~RenderGraphBuilder()
  169. {
  170. for(RenderPassBase* pass : m_passes)
  171. {
  172. deleteInstance(*m_pool, pass);
  173. }
  174. }
  175. inline GraphicsRenderPass& RenderGraphBuilder::newGraphicsRenderPass(CString name)
  176. {
  177. GraphicsRenderPass* pass = newInstance<GraphicsRenderPass>(*m_pool, this, m_pool);
  178. pass->setName(name);
  179. m_passes.emplaceBack(pass);
  180. return *pass;
  181. }
  182. inline NonGraphicsRenderPass& RenderGraphBuilder::newNonGraphicsRenderPass(CString name)
  183. {
  184. NonGraphicsRenderPass* pass = newInstance<NonGraphicsRenderPass>(*m_pool, this, m_pool);
  185. pass->setName(name);
  186. m_passes.emplaceBack(pass);
  187. return *pass;
  188. }
  189. inline RenderTargetHandle RenderGraphBuilder::importRenderTarget(Texture* tex, TextureUsageBit usage)
  190. {
  191. for([[maybe_unused]] const RT& rt : m_renderTargets)
  192. {
  193. ANKI_ASSERT(rt.m_importedTex.tryGet() != tex && "Already imported");
  194. }
  195. RT& rt = *m_renderTargets.emplaceBack();
  196. rt.m_importedTex.reset(tex);
  197. rt.m_importedLastKnownUsage = usage;
  198. rt.m_usageDerivedByDeps = TextureUsageBit::kNone;
  199. rt.setName(tex->getName());
  200. RenderTargetHandle out;
  201. out.m_idx = m_renderTargets.getSize() - 1;
  202. return out;
  203. }
  204. inline RenderTargetHandle RenderGraphBuilder::importRenderTarget(Texture* tex)
  205. {
  206. RenderTargetHandle out = importRenderTarget(tex, TextureUsageBit::kNone);
  207. m_renderTargets.getBack().m_importedAndUndefinedUsage = true;
  208. return out;
  209. }
  210. inline RenderTargetHandle RenderGraphBuilder::newRenderTarget(const RenderTargetDesc& initInf)
  211. {
  212. ANKI_ASSERT(initInf.m_hash && "Forgot to call RenderTargetDesc::bake");
  213. ANKI_ASSERT(initInf.m_usage == TextureUsageBit::kNone && "Don't need to supply the usage. Render grap will find it");
  214. for([[maybe_unused]] auto it : m_renderTargets)
  215. {
  216. ANKI_ASSERT(it.m_hash != initInf.m_hash && "There is another RT descriptor with the same hash. Rendergraph's RT recycler will get confused");
  217. }
  218. RT& rt = *m_renderTargets.emplaceBack();
  219. rt.m_initInfo = initInf;
  220. rt.m_hash = initInf.m_hash;
  221. rt.m_importedLastKnownUsage = TextureUsageBit::kNone;
  222. rt.m_usageDerivedByDeps = TextureUsageBit::kNone;
  223. rt.setName(initInf.getName());
  224. RenderTargetHandle out;
  225. out.m_idx = m_renderTargets.getSize() - 1;
  226. return out;
  227. }
  228. inline BufferHandle RenderGraphBuilder::importBuffer(const BufferView& buff, BufferUsageBit crntUsage)
  229. {
  230. ANKI_ASSERT(buff.isValid());
  231. for([[maybe_unused]] const BufferRsrc& bb : m_buffers)
  232. {
  233. ANKI_ASSERT(!buff.overlaps(BufferView(bb.m_importedBuff.get(), bb.m_offset, bb.m_range)) && "Range already imported");
  234. }
  235. BufferRsrc& b = *m_buffers.emplaceBack();
  236. b.setName(buff.getBuffer().getName());
  237. b.m_usage = crntUsage;
  238. b.m_importedBuff.reset(&buff.getBuffer());
  239. b.m_offset = buff.getOffset();
  240. b.m_range = buff.getRange();
  241. BufferHandle out;
  242. out.m_idx = m_buffers.getSize() - 1;
  243. return out;
  244. }
  245. inline AccelerationStructureHandle RenderGraphBuilder::importAccelerationStructure(AccelerationStructure* as, AccelerationStructureUsageBit crntUsage)
  246. {
  247. for([[maybe_unused]] const AS& a : m_as)
  248. {
  249. ANKI_ASSERT(a.m_importedAs.get() != as && "Already imported");
  250. }
  251. AS& a = *m_as.emplaceBack();
  252. a.setName(as->getName());
  253. a.m_importedAs.reset(as);
  254. a.m_usage = crntUsage;
  255. AccelerationStructureHandle handle;
  256. handle.m_idx = m_as.getSize() - 1;
  257. return handle;
  258. }
  259. } // end namespace anki