RenderGraph.inl.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. #include <AnKi/Gr/RenderGraph.h>
  6. namespace anki
  7. {
  8. inline void RenderPassWorkContext::bindAccelerationStructure(U32 set, U32 binding, AccelerationStructureHandle handle)
  9. {
  10. m_commandBuffer->bindAccelerationStructure(set, binding, m_rgraph->getAs(handle));
  11. }
  12. inline void RenderPassWorkContext::getBufferState(BufferHandle handle, BufferPtr& buff) const
  13. {
  14. buff = m_rgraph->getBuffer(handle);
  15. }
  16. inline void RenderPassWorkContext::getRenderTargetState(RenderTargetHandle handle,
  17. const TextureSubresourceInfo& subresource, TexturePtr& tex,
  18. TextureUsageBit& usage) const
  19. {
  20. m_rgraph->getCrntUsage(handle, m_batchIdx, subresource, usage);
  21. tex = m_rgraph->getTexture(handle);
  22. }
  23. inline TexturePtr RenderPassWorkContext::getTexture(RenderTargetHandle handle) const
  24. {
  25. return m_rgraph->getTexture(handle);
  26. }
  27. inline void RenderPassDescriptionBase::fixSubresource(RenderPassDependency& dep) const
  28. {
  29. ANKI_ASSERT(dep.m_type == RenderPassDependency::Type::TEXTURE);
  30. TextureSubresourceInfo& subresource = dep.m_texture.m_subresource;
  31. const Bool wholeTexture = subresource.m_mipmapCount == MAX_U32;
  32. if(wholeTexture)
  33. {
  34. ANKI_ASSERT(subresource.m_firstFace == 0);
  35. ANKI_ASSERT(subresource.m_firstMipmap == 0);
  36. ANKI_ASSERT(subresource.m_firstLayer == 0);
  37. const RenderGraphDescription::RT& rt = m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx];
  38. if(rt.m_importedTex)
  39. {
  40. subresource.m_faceCount = textureTypeIsCube(rt.m_importedTex->getTextureType()) ? 6 : 1;
  41. subresource.m_mipmapCount = rt.m_importedTex->getMipmapCount();
  42. subresource.m_layerCount = rt.m_importedTex->getLayerCount();
  43. }
  44. else
  45. {
  46. subresource.m_faceCount = textureTypeIsCube(rt.m_initInfo.m_type) ? 6 : 1;
  47. subresource.m_mipmapCount = rt.m_initInfo.m_mipmapCount;
  48. subresource.m_layerCount = rt.m_initInfo.m_layerCount;
  49. }
  50. }
  51. }
  52. inline void RenderPassDescriptionBase::validateDep(const RenderPassDependency& dep)
  53. {
  54. // Validate dep
  55. if(dep.m_type == RenderPassDependency::Type::TEXTURE)
  56. {
  57. const TextureUsageBit usage = dep.m_texture.m_usage;
  58. (void)usage;
  59. if(m_type == Type::GRAPHICS)
  60. {
  61. ANKI_ASSERT(!(usage & TextureUsageBit::ALL_COMPUTE));
  62. }
  63. else
  64. {
  65. ANKI_ASSERT(!(usage & TextureUsageBit::ALL_GRAPHICS));
  66. }
  67. ANKI_ASSERT(!!(usage & TextureUsageBit::ALL_READ) || !!(usage & TextureUsageBit::ALL_WRITE));
  68. }
  69. else if(dep.m_type == RenderPassDependency::Type::BUFFER)
  70. {
  71. const BufferUsageBit usage = dep.m_buffer.m_usage;
  72. (void)usage;
  73. if(m_type == Type::GRAPHICS)
  74. {
  75. ANKI_ASSERT(!(usage & BufferUsageBit::ALL_COMPUTE));
  76. }
  77. else
  78. {
  79. ANKI_ASSERT(!(usage & BufferUsageBit::ALL_GRAPHICS));
  80. }
  81. ANKI_ASSERT(!!(usage & BufferUsageBit::ALL_READ) || !!(usage & BufferUsageBit::ALL_WRITE));
  82. }
  83. else
  84. {
  85. ANKI_ASSERT(dep.m_type == RenderPassDependency::Type::ACCELERATION_STRUCTURE);
  86. if(m_type == Type::GRAPHICS)
  87. {
  88. ANKI_ASSERT(!(dep.m_as.m_usage & ~AccelerationStructureUsageBit::ALL_GRAPHICS));
  89. }
  90. else
  91. {
  92. ANKI_ASSERT(!(dep.m_as.m_usage & AccelerationStructureUsageBit::ALL_GRAPHICS));
  93. }
  94. }
  95. }
  96. inline void RenderPassDescriptionBase::newDependency(const RenderPassDependency& dep)
  97. {
  98. validateDep(dep);
  99. if(dep.m_type == RenderPassDependency::Type::TEXTURE)
  100. {
  101. m_rtDeps.emplaceBack(m_alloc, dep);
  102. fixSubresource(m_rtDeps.getBack());
  103. if(!!(dep.m_texture.m_usage & TextureUsageBit::ALL_READ))
  104. {
  105. m_readRtMask.set(dep.m_texture.m_handle.m_idx);
  106. }
  107. if(!!(dep.m_texture.m_usage & TextureUsageBit::ALL_WRITE))
  108. {
  109. m_writeRtMask.set(dep.m_texture.m_handle.m_idx);
  110. }
  111. // Try to derive the usage by that dep
  112. m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx].m_usageDerivedByDeps |= dep.m_texture.m_usage;
  113. }
  114. else if(dep.m_type == RenderPassDependency::Type::BUFFER)
  115. {
  116. m_buffDeps.emplaceBack(m_alloc, dep);
  117. if(!!(dep.m_buffer.m_usage & BufferUsageBit::ALL_READ))
  118. {
  119. m_readBuffMask.set(dep.m_buffer.m_handle.m_idx);
  120. }
  121. if(!!(dep.m_buffer.m_usage & BufferUsageBit::ALL_WRITE))
  122. {
  123. m_writeBuffMask.set(dep.m_buffer.m_handle.m_idx);
  124. }
  125. }
  126. else
  127. {
  128. ANKI_ASSERT(dep.m_type == RenderPassDependency::Type::ACCELERATION_STRUCTURE);
  129. m_asDeps.emplaceBack(m_alloc, dep);
  130. if(!!(dep.m_as.m_usage & AccelerationStructureUsageBit::ALL_READ))
  131. {
  132. m_readAsMask.set(dep.m_as.m_handle.m_idx);
  133. }
  134. if(!!(dep.m_as.m_usage & AccelerationStructureUsageBit::ALL_WRITE))
  135. {
  136. m_writeAsMask.set(dep.m_as.m_handle.m_idx);
  137. }
  138. }
  139. }
  140. inline void GraphicsRenderPassDescription::setFramebufferInfo(
  141. const FramebufferDescription& fbInfo, std::initializer_list<RenderTargetHandle> colorRenderTargetHandles,
  142. RenderTargetHandle depthStencilRenderTargetHandle, U32 minx, U32 miny, U32 maxx, U32 maxy)
  143. {
  144. Array<RenderTargetHandle, MAX_COLOR_ATTACHMENTS> rts;
  145. U32 count = 0;
  146. for(const RenderTargetHandle& h : colorRenderTargetHandles)
  147. {
  148. rts[count++] = h;
  149. }
  150. setFramebufferInfo(fbInfo, ConstWeakArray<RenderTargetHandle>(&rts[0], count), depthStencilRenderTargetHandle, minx,
  151. miny, maxx, maxy);
  152. }
  153. inline void GraphicsRenderPassDescription::setFramebufferInfo(
  154. const FramebufferDescription& fbInfo, ConstWeakArray<RenderTargetHandle> colorRenderTargetHandles,
  155. RenderTargetHandle depthStencilRenderTargetHandle, U32 minx, U32 miny, U32 maxx, U32 maxy)
  156. {
  157. #if ANKI_ENABLE_ASSERTIONS
  158. ANKI_ASSERT(fbInfo.isBacked() && "Forgot call GraphicsRenderPassFramebufferInfo::bake");
  159. for(U32 i = 0; i < colorRenderTargetHandles.getSize(); ++i)
  160. {
  161. if(i >= fbInfo.m_colorAttachmentCount)
  162. {
  163. ANKI_ASSERT(!colorRenderTargetHandles[i].isValid());
  164. }
  165. else
  166. {
  167. ANKI_ASSERT(colorRenderTargetHandles[i].isValid());
  168. }
  169. }
  170. if(!fbInfo.m_depthStencilAttachment.m_aspect)
  171. {
  172. ANKI_ASSERT(!depthStencilRenderTargetHandle.isValid());
  173. }
  174. else
  175. {
  176. ANKI_ASSERT(depthStencilRenderTargetHandle.isValid());
  177. }
  178. #endif
  179. m_fbDescr = fbInfo;
  180. memcpy(m_rtHandles.getBegin(), colorRenderTargetHandles.getBegin(), colorRenderTargetHandles.getSizeInBytes());
  181. m_rtHandles[MAX_COLOR_ATTACHMENTS] = depthStencilRenderTargetHandle;
  182. m_fbRenderArea = {minx, miny, maxx, maxy};
  183. }
  184. inline RenderGraphDescription::~RenderGraphDescription()
  185. {
  186. for(RenderPassDescriptionBase* pass : m_passes)
  187. {
  188. m_alloc.deleteInstance(pass);
  189. }
  190. m_passes.destroy(m_alloc);
  191. m_renderTargets.destroy(m_alloc);
  192. m_buffers.destroy(m_alloc);
  193. m_as.destroy(m_alloc);
  194. }
  195. inline GraphicsRenderPassDescription& RenderGraphDescription::newGraphicsRenderPass(CString name)
  196. {
  197. GraphicsRenderPassDescription* pass = m_alloc.newInstance<GraphicsRenderPassDescription>(this);
  198. pass->m_alloc = m_alloc;
  199. pass->setName(name);
  200. m_passes.emplaceBack(m_alloc, pass);
  201. return *pass;
  202. }
  203. inline ComputeRenderPassDescription& RenderGraphDescription::newComputeRenderPass(CString name)
  204. {
  205. ComputeRenderPassDescription* pass = m_alloc.newInstance<ComputeRenderPassDescription>(this);
  206. pass->m_alloc = m_alloc;
  207. pass->setName(name);
  208. m_passes.emplaceBack(m_alloc, pass);
  209. return *pass;
  210. }
  211. inline RenderTargetHandle RenderGraphDescription::importRenderTarget(TexturePtr tex, TextureUsageBit usage)
  212. {
  213. for(const RT& rt : m_renderTargets)
  214. {
  215. (void)rt;
  216. ANKI_ASSERT(rt.m_importedTex != tex && "Already imported");
  217. }
  218. RT& rt = *m_renderTargets.emplaceBack(m_alloc);
  219. rt.m_importedTex = tex;
  220. rt.m_importedLastKnownUsage = usage;
  221. rt.m_usageDerivedByDeps = TextureUsageBit::NONE;
  222. rt.setName(tex->getName());
  223. RenderTargetHandle out;
  224. out.m_idx = m_renderTargets.getSize() - 1;
  225. return out;
  226. }
  227. inline RenderTargetHandle RenderGraphDescription::importRenderTarget(TexturePtr tex)
  228. {
  229. RenderTargetHandle out = importRenderTarget(tex, TextureUsageBit::NONE);
  230. m_renderTargets.getBack().m_importedAndUndefinedUsage = true;
  231. return out;
  232. }
  233. inline RenderTargetHandle RenderGraphDescription::newRenderTarget(const RenderTargetDescription& initInf)
  234. {
  235. ANKI_ASSERT(initInf.m_hash && "Forgot to call RenderTargetDescription::bake");
  236. ANKI_ASSERT(initInf.m_usage == TextureUsageBit::NONE && "Don't need to supply the usage. Render grap will find it");
  237. RT& rt = *m_renderTargets.emplaceBack(m_alloc);
  238. rt.m_initInfo = initInf;
  239. rt.m_hash = initInf.m_hash;
  240. rt.m_importedLastKnownUsage = TextureUsageBit::NONE;
  241. rt.m_usageDerivedByDeps = TextureUsageBit::NONE;
  242. rt.setName(initInf.getName());
  243. RenderTargetHandle out;
  244. out.m_idx = m_renderTargets.getSize() - 1;
  245. return out;
  246. }
  247. inline BufferHandle RenderGraphDescription::importBuffer(BufferPtr buff, BufferUsageBit usage, PtrSize offset,
  248. PtrSize range)
  249. {
  250. // Checks
  251. if(range == MAX_PTR_SIZE)
  252. {
  253. ANKI_ASSERT(offset < buff->getSize());
  254. }
  255. else
  256. {
  257. ANKI_ASSERT((offset + range) <= buff->getSize());
  258. }
  259. for(const Buffer& bb : m_buffers)
  260. {
  261. (void)bb;
  262. ANKI_ASSERT((bb.m_importedBuff != buff || !bufferRangeOverlaps(bb.m_offset, bb.m_range, offset, range))
  263. && "Range already imported");
  264. }
  265. Buffer& b = *m_buffers.emplaceBack(m_alloc);
  266. b.setName(buff->getName());
  267. b.m_usage = usage;
  268. b.m_importedBuff = buff;
  269. b.m_offset = offset;
  270. b.m_range = range;
  271. BufferHandle out;
  272. out.m_idx = m_buffers.getSize() - 1;
  273. return out;
  274. }
  275. inline AccelerationStructureHandle
  276. RenderGraphDescription::importAccelerationStructure(AccelerationStructurePtr as, AccelerationStructureUsageBit usage)
  277. {
  278. for(const AS& a : m_as)
  279. {
  280. (void)a;
  281. ANKI_ASSERT(a.m_importedAs != as && "Already imported");
  282. }
  283. AS& a = *m_as.emplaceBack(m_alloc);
  284. a.setName(as->getName());
  285. a.m_importedAs = as;
  286. a.m_usage = usage;
  287. AccelerationStructureHandle handle;
  288. handle.m_idx = m_as.getSize() - 1;
  289. return handle;
  290. }
  291. } // end namespace anki