RenderGraph.inl.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // Copyright (C) 2009-2022, 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::bindAccelerationStructure(U32 set, U32 binding, AccelerationStructureHandle handle)
  8. {
  9. m_commandBuffer->bindAccelerationStructure(set, binding, m_rgraph->getAs(handle));
  10. }
  11. inline void RenderPassWorkContext::getBufferState(BufferHandle handle, BufferPtr& buff) const
  12. {
  13. buff = m_rgraph->getBuffer(handle);
  14. }
  15. inline void RenderPassWorkContext::getRenderTargetState(RenderTargetHandle handle,
  16. const TextureSubresourceInfo& subresource,
  17. TexturePtr& tex) const
  18. {
  19. TextureUsageBit usage;
  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. const RenderGraphDescription::RT& rt = m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx];
  33. if(wholeTexture)
  34. {
  35. ANKI_ASSERT(subresource.m_firstFace == 0);
  36. ANKI_ASSERT(subresource.m_firstMipmap == 0);
  37. ANKI_ASSERT(subresource.m_firstLayer == 0);
  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. ANKI_ASSERT(dep.m_texture.m_subresource.m_firstMipmap + dep.m_texture.m_subresource.m_mipmapCount
  52. <= ((rt.m_importedTex) ? rt.m_importedTex->getMipmapCount() : rt.m_initInfo.m_mipmapCount));
  53. }
  54. inline void RenderPassDescriptionBase::validateDep(const RenderPassDependency& dep)
  55. {
  56. // Validate dep
  57. if(dep.m_type == RenderPassDependency::Type::TEXTURE)
  58. {
  59. [[maybe_unused]] const TextureUsageBit usage = dep.m_texture.m_usage;
  60. if(m_type == Type::GRAPHICS)
  61. {
  62. ANKI_ASSERT(!(usage & TextureUsageBit::ALL_COMPUTE));
  63. }
  64. else
  65. {
  66. ANKI_ASSERT(!(usage & TextureUsageBit::ALL_GRAPHICS));
  67. }
  68. ANKI_ASSERT(!!(usage & TextureUsageBit::ALL_READ) || !!(usage & TextureUsageBit::ALL_WRITE));
  69. }
  70. else if(dep.m_type == RenderPassDependency::Type::BUFFER)
  71. {
  72. [[maybe_unused]] const BufferUsageBit usage = dep.m_buffer.m_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, RenderTargetHandle shadingRateRenderTargetHandle, U32 minx,
  143. U32 miny, U32 maxx, U32 maxy)
  144. {
  145. Array<RenderTargetHandle, MAX_COLOR_ATTACHMENTS> rts;
  146. U32 count = 0;
  147. for(const RenderTargetHandle& h : colorRenderTargetHandles)
  148. {
  149. rts[count++] = h;
  150. }
  151. setFramebufferInfo(fbInfo, ConstWeakArray<RenderTargetHandle>(&rts[0], count), depthStencilRenderTargetHandle,
  152. shadingRateRenderTargetHandle, minx, miny, maxx, maxy);
  153. }
  154. inline void GraphicsRenderPassDescription::setFramebufferInfo(
  155. const FramebufferDescription& fbInfo, ConstWeakArray<RenderTargetHandle> colorRenderTargetHandles,
  156. RenderTargetHandle depthStencilRenderTargetHandle, RenderTargetHandle shadingRateRenderTargetHandle, U32 minx,
  157. U32 miny, U32 maxx, U32 maxy)
  158. {
  159. #if ANKI_ENABLE_ASSERTIONS
  160. ANKI_ASSERT(fbInfo.isBacked() && "Forgot call GraphicsRenderPassFramebufferInfo::bake");
  161. for(U32 i = 0; i < colorRenderTargetHandles.getSize(); ++i)
  162. {
  163. if(i >= fbInfo.m_colorAttachmentCount)
  164. {
  165. ANKI_ASSERT(!colorRenderTargetHandles[i].isValid());
  166. }
  167. else
  168. {
  169. ANKI_ASSERT(colorRenderTargetHandles[i].isValid());
  170. }
  171. }
  172. if(!fbInfo.m_depthStencilAttachment.m_aspect)
  173. {
  174. ANKI_ASSERT(!depthStencilRenderTargetHandle.isValid());
  175. }
  176. else
  177. {
  178. ANKI_ASSERT(depthStencilRenderTargetHandle.isValid());
  179. }
  180. if(fbInfo.m_shadingRateAttachmentTexelWidth > 0 && fbInfo.m_shadingRateAttachmentTexelHeight > 0)
  181. {
  182. ANKI_ASSERT(shadingRateRenderTargetHandle.isValid());
  183. }
  184. else
  185. {
  186. ANKI_ASSERT(!shadingRateRenderTargetHandle.isValid());
  187. }
  188. #endif
  189. m_fbDescr = fbInfo;
  190. memcpy(m_rtHandles.getBegin(), colorRenderTargetHandles.getBegin(), colorRenderTargetHandles.getSizeInBytes());
  191. m_rtHandles[MAX_COLOR_ATTACHMENTS] = depthStencilRenderTargetHandle;
  192. m_rtHandles[MAX_COLOR_ATTACHMENTS + 1] = shadingRateRenderTargetHandle;
  193. m_fbRenderArea = {minx, miny, maxx, maxy};
  194. }
  195. inline RenderGraphDescription::~RenderGraphDescription()
  196. {
  197. for(RenderPassDescriptionBase* pass : m_passes)
  198. {
  199. m_alloc.deleteInstance(pass);
  200. }
  201. m_passes.destroy(m_alloc);
  202. m_renderTargets.destroy(m_alloc);
  203. m_buffers.destroy(m_alloc);
  204. m_as.destroy(m_alloc);
  205. }
  206. inline GraphicsRenderPassDescription& RenderGraphDescription::newGraphicsRenderPass(CString name)
  207. {
  208. GraphicsRenderPassDescription* pass = m_alloc.newInstance<GraphicsRenderPassDescription>(this);
  209. pass->m_alloc = m_alloc;
  210. pass->setName(name);
  211. m_passes.emplaceBack(m_alloc, pass);
  212. return *pass;
  213. }
  214. inline ComputeRenderPassDescription& RenderGraphDescription::newComputeRenderPass(CString name)
  215. {
  216. ComputeRenderPassDescription* pass = m_alloc.newInstance<ComputeRenderPassDescription>(this);
  217. pass->m_alloc = m_alloc;
  218. pass->setName(name);
  219. m_passes.emplaceBack(m_alloc, pass);
  220. return *pass;
  221. }
  222. inline RenderTargetHandle RenderGraphDescription::importRenderTarget(TexturePtr tex, TextureUsageBit usage)
  223. {
  224. for([[maybe_unused]] const RT& rt : m_renderTargets)
  225. {
  226. ANKI_ASSERT(rt.m_importedTex != tex && "Already imported");
  227. }
  228. RT& rt = *m_renderTargets.emplaceBack(m_alloc);
  229. rt.m_importedTex = tex;
  230. rt.m_importedLastKnownUsage = usage;
  231. rt.m_usageDerivedByDeps = TextureUsageBit::NONE;
  232. rt.setName(tex->getName());
  233. RenderTargetHandle out;
  234. out.m_idx = m_renderTargets.getSize() - 1;
  235. return out;
  236. }
  237. inline RenderTargetHandle RenderGraphDescription::importRenderTarget(TexturePtr tex)
  238. {
  239. RenderTargetHandle out = importRenderTarget(tex, TextureUsageBit::NONE);
  240. m_renderTargets.getBack().m_importedAndUndefinedUsage = true;
  241. return out;
  242. }
  243. inline RenderTargetHandle RenderGraphDescription::newRenderTarget(const RenderTargetDescription& initInf)
  244. {
  245. ANKI_ASSERT(initInf.m_hash && "Forgot to call RenderTargetDescription::bake");
  246. ANKI_ASSERT(initInf.m_usage == TextureUsageBit::NONE && "Don't need to supply the usage. Render grap will find it");
  247. RT& rt = *m_renderTargets.emplaceBack(m_alloc);
  248. rt.m_initInfo = initInf;
  249. rt.m_hash = initInf.m_hash;
  250. rt.m_importedLastKnownUsage = TextureUsageBit::NONE;
  251. rt.m_usageDerivedByDeps = TextureUsageBit::NONE;
  252. rt.setName(initInf.getName());
  253. RenderTargetHandle out;
  254. out.m_idx = m_renderTargets.getSize() - 1;
  255. return out;
  256. }
  257. inline BufferHandle RenderGraphDescription::importBuffer(BufferPtr buff, BufferUsageBit usage, PtrSize offset,
  258. PtrSize range)
  259. {
  260. // Checks
  261. if(range == MAX_PTR_SIZE)
  262. {
  263. ANKI_ASSERT(offset < buff->getSize());
  264. }
  265. else
  266. {
  267. ANKI_ASSERT((offset + range) <= buff->getSize());
  268. }
  269. for([[maybe_unused]] const Buffer& bb : m_buffers)
  270. {
  271. ANKI_ASSERT((bb.m_importedBuff != buff || !bufferRangeOverlaps(bb.m_offset, bb.m_range, offset, range))
  272. && "Range already imported");
  273. }
  274. Buffer& b = *m_buffers.emplaceBack(m_alloc);
  275. b.setName(buff->getName());
  276. b.m_usage = usage;
  277. b.m_importedBuff = buff;
  278. b.m_offset = offset;
  279. b.m_range = range;
  280. BufferHandle out;
  281. out.m_idx = m_buffers.getSize() - 1;
  282. return out;
  283. }
  284. inline AccelerationStructureHandle
  285. RenderGraphDescription::importAccelerationStructure(AccelerationStructurePtr as, AccelerationStructureUsageBit usage)
  286. {
  287. for([[maybe_unused]] const AS& a : m_as)
  288. {
  289. ANKI_ASSERT(a.m_importedAs != as && "Already imported");
  290. }
  291. AS& a = *m_as.emplaceBack(m_alloc);
  292. a.setName(as->getName());
  293. a.m_importedAs = as;
  294. a.m_usage = usage;
  295. AccelerationStructureHandle handle;
  296. handle.m_idx = m_as.getSize() - 1;
  297. return handle;
  298. }
  299. } // end namespace anki