RenderGraph.inl.h 9.6 KB

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