CommandBuffer.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  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. #pragma once
  6. #include <AnKi/Gr/GrObject.h>
  7. #include <AnKi/Gr/Framebuffer.h>
  8. #include <AnKi/Util/Functions.h>
  9. #include <AnKi/Util/WeakArray.h>
  10. namespace anki {
  11. /// @addtogroup graphics
  12. /// @{
  13. /// The draw indirect structure for index drawing, also the parameters of a regular drawcall
  14. class DrawElementsIndirectInfo
  15. {
  16. public:
  17. U32 m_count = MAX_U32;
  18. U32 m_instanceCount = 1;
  19. U32 m_firstIndex = 0;
  20. U32 m_baseVertex = 0;
  21. U32 m_baseInstance = 0;
  22. DrawElementsIndirectInfo() = default;
  23. DrawElementsIndirectInfo(const DrawElementsIndirectInfo&) = default;
  24. DrawElementsIndirectInfo(U32 count, U32 instanceCount, U32 firstIndex, U32 baseVertex, U32 baseInstance)
  25. : m_count(count)
  26. , m_instanceCount(instanceCount)
  27. , m_firstIndex(firstIndex)
  28. , m_baseVertex(baseVertex)
  29. , m_baseInstance(baseInstance)
  30. {
  31. }
  32. Bool operator==(const DrawElementsIndirectInfo& b) const
  33. {
  34. return m_count == b.m_count && m_instanceCount == b.m_instanceCount && m_firstIndex == b.m_firstIndex
  35. && m_baseVertex == b.m_baseVertex && m_baseInstance == b.m_baseInstance;
  36. }
  37. Bool operator!=(const DrawElementsIndirectInfo& b) const
  38. {
  39. return !(operator==(b));
  40. }
  41. };
  42. /// The draw indirect structure for arrays drawing, also the parameters of a regular drawcall
  43. class DrawArraysIndirectInfo
  44. {
  45. public:
  46. U32 m_count = MAX_U32;
  47. U32 m_instanceCount = 1;
  48. U32 m_first = 0;
  49. U32 m_baseInstance = 0;
  50. DrawArraysIndirectInfo() = default;
  51. DrawArraysIndirectInfo(const DrawArraysIndirectInfo&) = default;
  52. DrawArraysIndirectInfo(U32 count, U32 instanceCount, U32 first, U32 baseInstance)
  53. : m_count(count)
  54. , m_instanceCount(instanceCount)
  55. , m_first(first)
  56. , m_baseInstance(baseInstance)
  57. {
  58. }
  59. Bool operator==(const DrawArraysIndirectInfo& b) const
  60. {
  61. return m_count == b.m_count && m_instanceCount == b.m_instanceCount && m_first == b.m_first
  62. && m_baseInstance == b.m_baseInstance;
  63. }
  64. Bool operator!=(const DrawArraysIndirectInfo& b) const
  65. {
  66. return !(operator==(b));
  67. }
  68. };
  69. /// Command buffer initialization flags.
  70. enum class CommandBufferFlag : U8
  71. {
  72. NONE = 0,
  73. SECOND_LEVEL = 1 << 0,
  74. /// It will contain a handfull of commands.
  75. SMALL_BATCH = 1 << 3,
  76. /// Will contain graphics, compute and transfer work.
  77. GENERAL_WORK = 1 << 4,
  78. /// Will contain only compute work. It binds to async compute queues.
  79. COMPUTE_WORK = 1 << 5,
  80. };
  81. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(CommandBufferFlag)
  82. /// Command buffer init info.
  83. class CommandBufferInitInfo : public GrBaseInitInfo
  84. {
  85. public:
  86. FramebufferPtr m_framebuffer; ///< For second level command buffers.
  87. Array<TextureUsageBit, MAX_COLOR_ATTACHMENTS> m_colorAttachmentUsages = {};
  88. TextureUsageBit m_depthStencilAttachmentUsage = TextureUsageBit::NONE;
  89. CommandBufferFlag m_flags = CommandBufferFlag::NONE;
  90. CommandBufferInitInfo(CString name = {})
  91. : GrBaseInitInfo(name)
  92. {
  93. }
  94. };
  95. /// Command buffer.
  96. class CommandBuffer : public GrObject
  97. {
  98. ANKI_GR_OBJECT
  99. public:
  100. static const GrObjectType CLASS_TYPE = GrObjectType::COMMAND_BUFFER;
  101. /// Finalize and submit if it's primary command buffer and just finalize if it's second level.
  102. /// @param[in] waitFences Optionally wait for some fences.
  103. /// @param[out] signalFence Optionaly create fence that will be signaled when the submission is done.
  104. void flush(ConstWeakArray<FencePtr> waitFences = {}, FencePtr* signalFence = nullptr);
  105. /// @name State manipulation
  106. /// @{
  107. /// Bind vertex buffer.
  108. void bindVertexBuffer(U32 binding, const BufferPtr& buff, PtrSize offset, PtrSize stride,
  109. VertexStepRate stepRate = VertexStepRate::VERTEX);
  110. /// Setup a vertex attribute.
  111. void setVertexAttribute(U32 location, U32 buffBinding, Format fmt, PtrSize relativeOffset);
  112. /// Bind index buffer.
  113. void bindIndexBuffer(const BufferPtr& buff, PtrSize offset, IndexType type);
  114. /// Enable primitive restart.
  115. void setPrimitiveRestart(Bool enable);
  116. /// Set the viewport.
  117. void setViewport(U32 minx, U32 miny, U32 width, U32 height);
  118. /// Set the scissor rect. To disable the scissor just set a rect bigger than the viewport. By default it's disabled.
  119. void setScissor(U32 minx, U32 miny, U32 width, U32 height);
  120. /// Set fill mode.
  121. void setFillMode(FillMode mode);
  122. /// Set cull mode.
  123. /// By default it's FaceSelectionBit::BACK.
  124. void setCullMode(FaceSelectionBit mode);
  125. /// Set depth offset and units. Set zeros to both to disable it.
  126. void setPolygonOffset(F32 factor, F32 units);
  127. /// Set stencil operations. To disable stencil test put StencilOperation::KEEP to all operations.
  128. void setStencilOperations(FaceSelectionBit face, StencilOperation stencilFail,
  129. StencilOperation stencilPassDepthFail, StencilOperation stencilPassDepthPass);
  130. /// Set stencil compare operation.
  131. void setStencilCompareOperation(FaceSelectionBit face, CompareOperation comp);
  132. /// Set the stencil compare mask.
  133. void setStencilCompareMask(FaceSelectionBit face, U32 mask);
  134. /// Set the stencil write mask.
  135. void setStencilWriteMask(FaceSelectionBit face, U32 mask);
  136. /// Set the stencil reference.
  137. void setStencilReference(FaceSelectionBit face, U32 ref);
  138. /// Enable/disable depth write. To disable depth testing set depth write to false and depth compare operation to
  139. /// always.
  140. void setDepthWrite(Bool enable);
  141. /// Set depth compare operation. By default it's less.
  142. void setDepthCompareOperation(CompareOperation op);
  143. /// Enable/disable alpha to coverage.
  144. void setAlphaToCoverage(Bool enable);
  145. /// Set color channel write mask.
  146. void setColorChannelWriteMask(U32 attachment, ColorBit mask);
  147. /// Set blend factors seperate.
  148. /// By default the values of srcRgb, dstRgb, srcA and dstA are BlendFactor::ONE, BlendFactor::ZERO,
  149. /// BlendFactor::ONE, BlendFactor::ZERO respectively.
  150. void setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA);
  151. /// Set blend factors.
  152. void setBlendFactors(U32 attachment, BlendFactor src, BlendFactor dst)
  153. {
  154. setBlendFactors(attachment, src, dst, src, dst);
  155. }
  156. /// Set the blend operation seperate.
  157. /// By default the values of funcRgb and funcA are BlendOperation::ADD, BlendOperation::ADD respectively.
  158. void setBlendOperation(U32 attachment, BlendOperation funcRgb, BlendOperation funcA);
  159. /// Set the blend operation.
  160. void setBlendOperation(U32 attachment, BlendOperation func)
  161. {
  162. setBlendOperation(attachment, func, func);
  163. }
  164. /// Set the rasterizatin order. By default it's RasterizationOrder::ORDERED.
  165. void setRasterizationOrder(RasterizationOrder order);
  166. /// Set the line width. By default it's undefined.
  167. void setLineWidth(F32 lineWidth);
  168. /// Bind texture and sample.
  169. /// @param set The set to bind to.
  170. /// @param binding The binding to bind to.
  171. /// @param texView The texture view to bind.
  172. /// @param sampler The sampler to override the default sampler of the tex.
  173. /// @param arrayIdx The array index if the binding is an array.
  174. void bindTextureAndSampler(U32 set, U32 binding, const TextureViewPtr& texView, const SamplerPtr& sampler,
  175. U32 arrayIdx = 0);
  176. /// Bind sampler.
  177. /// @param set The set to bind to.
  178. /// @param binding The binding to bind to.
  179. /// @param sampler The sampler to override the default sampler of the tex.
  180. /// @param arrayIdx The array index if the binding is an array.
  181. void bindSampler(U32 set, U32 binding, const SamplerPtr& sampler, U32 arrayIdx = 0);
  182. /// Bind a texture.
  183. /// @param set The set to bind to.
  184. /// @param binding The binding to bind to.
  185. /// @param texView The texture view to bind.
  186. /// @param arrayIdx The array index if the binding is an array.
  187. void bindTexture(U32 set, U32 binding, const TextureViewPtr& texView, U32 arrayIdx = 0);
  188. /// Bind uniform buffer.
  189. /// @param set The set to bind to.
  190. /// @param binding The binding to bind to.
  191. /// @param[in,out] buff The buffer to bind.
  192. /// @param offset The base of the binding.
  193. /// @param range The bytes to bind starting from the offset. If it's MAX_PTR_SIZE then map from offset to the end
  194. /// of the buffer.
  195. /// @param arrayIdx The array index if the binding is an array.
  196. void bindUniformBuffer(U32 set, U32 binding, const BufferPtr& buff, PtrSize offset, PtrSize range,
  197. U32 arrayIdx = 0);
  198. /// Bind storage buffer.
  199. /// @param set The set to bind to.
  200. /// @param binding The binding to bind to.
  201. /// @param[in,out] buff The buffer to bind.
  202. /// @param offset The base of the binding.
  203. /// @param range The bytes to bind starting from the offset. If it's MAX_PTR_SIZE then map from offset to the end
  204. /// of the buffer.
  205. /// @param arrayIdx The array index if the binding is an array.
  206. void bindStorageBuffer(U32 set, U32 binding, const BufferPtr& buff, PtrSize offset, PtrSize range,
  207. U32 arrayIdx = 0);
  208. /// Bind load/store image.
  209. /// @param set The set to bind to.
  210. /// @param binding The binding to bind to.
  211. /// @param img The view to bind.
  212. /// @param arrayIdx The array index if the binding is an array.
  213. void bindImage(U32 set, U32 binding, const TextureViewPtr& img, U32 arrayIdx = 0);
  214. /// Bind texture buffer.
  215. /// @param set The set to bind to.
  216. /// @param binding The binding to bind to.
  217. /// @param[in,out] buff The buffer to bind.
  218. /// @param offset The base of the binding.
  219. /// @param range The bytes to bind starting from the offset. If it's MAX_PTR_SIZE then map from offset to the end
  220. /// of the buffer.
  221. /// @param fmt The format of the buffer.
  222. /// @param arrayIdx The array index if the binding is an array.
  223. void bindReadOnlyTextureBuffer(U32 set, U32 binding, const BufferPtr& buff, PtrSize offset, PtrSize range,
  224. Format fmt, U32 arrayIdx = 0);
  225. /// Bind an acceleration structure.
  226. /// @param set The set to bind to.
  227. /// @param binding The binding to bind to.
  228. /// @param[in,out] as The AS to bind.
  229. /// @param arrayIdx The array index if the binding is an array.
  230. void bindAccelerationStructure(U32 set, U32 binding, const AccelerationStructurePtr& as, U32 arrayIdx = 0);
  231. /// Bind the bindless descriptor set into a slot.
  232. void bindAllBindless(U32 set);
  233. /// Set push constants.
  234. void setPushConstants(const void* data, U32 dataSize);
  235. /// Bind a program.
  236. void bindShaderProgram(const ShaderProgramPtr& prog);
  237. /// Begin renderpass.
  238. /// The minx, miny, width, height control the area that the load and store operations will happen. If the scissor is
  239. /// bigger than the render area the results are undefined.
  240. void beginRenderPass(const FramebufferPtr& fb,
  241. const Array<TextureUsageBit, MAX_COLOR_ATTACHMENTS>& colorAttachmentUsages,
  242. TextureUsageBit depthStencilAttachmentUsage, U32 minx = 0, U32 miny = 0, U32 width = MAX_U32,
  243. U32 height = MAX_U32);
  244. /// End renderpass.
  245. void endRenderPass();
  246. /// Set VRS rate of the following drawcalls. By default it's 1x1.
  247. void setVrsRate(VrsRate rate);
  248. /// @}
  249. /// @name Jobs
  250. /// @{
  251. void drawElements(PrimitiveTopology topology, U32 count, U32 instanceCount = 1, U32 firstIndex = 0,
  252. U32 baseVertex = 0, U32 baseInstance = 0);
  253. void drawArrays(PrimitiveTopology topology, U32 count, U32 instanceCount = 1, U32 first = 0, U32 baseInstance = 0);
  254. void drawElementsIndirect(PrimitiveTopology topology, U32 drawCount, PtrSize offset, const BufferPtr& indirectBuff);
  255. void drawArraysIndirect(PrimitiveTopology topology, U32 drawCount, PtrSize offset, const BufferPtr& indirectBuff);
  256. void dispatchCompute(U32 groupCountX, U32 groupCountY, U32 groupCountZ);
  257. /// Trace rays.
  258. ///
  259. /// The 1st thing in the sbtBuffer is the ray gen shader group handle:
  260. /// @code RG = RG_offset @endcode
  261. /// The RG_offset is equal to the stbBufferOffset.
  262. ///
  263. /// Then the sbtBuffer contains the miss shader group handles and their data. The indexing is as follows:
  264. /// @code M = M_offset + M_stride * R_miss @endcode
  265. /// The M_offset is equal to stbBufferOffset + GpuDeviceCapabilities::m_sbtRecordSize.
  266. /// The M_stride is equal to GpuDeviceCapabilities::m_sbtRecordSize.
  267. /// The R_miss is defined in the traceRayEXT and it's the "ray type".
  268. ///
  269. /// After the miss shaders the sbtBuffer has the hit group shader group handles and their data. The indexing is:
  270. /// @code HG = HG_offset + (HG_stride * (R_offset + R_stride * G_id + I_offset)) @endcode
  271. /// The HG_offset is equal to sbtBufferOffset + GpuDeviceCapabilities::m_sbtRecordSize * (missShaderCount + 1).
  272. /// The HG_stride is equal GpuDeviceCapabilities::m_sbtRecordSize * rayTypecount.
  273. /// The R_offset and R_stride are provided in traceRayEXT. The R_offset is the "ray type" and R_stride the number of
  274. /// ray types.
  275. /// The G_id is always 0 ATM.
  276. /// The I_offset is the AccelerationStructureInstance::m_hitgroupSbtRecordIndex.
  277. ///
  278. /// @param[in] sbtBuffer The SBT buffer.
  279. /// @param sbtBufferOffset Offset inside the sbtBuffer where SBT records start.
  280. /// @param hitGroupSbtRecordCount The number of SBT records that contain hit groups.
  281. /// @param sbtRecordSize The size of an SBT record
  282. /// @param rayTypecount The number of ray types hosted in the pipeline. See above on how it's been used.
  283. /// @param width Width.
  284. /// @param height Height.
  285. /// @param depth Depth.
  286. void traceRays(const BufferPtr& sbtBuffer, PtrSize sbtBufferOffset, U32 sbtRecordSize, U32 hitGroupSbtRecordCount,
  287. U32 rayTypeCount, U32 width, U32 height, U32 depth);
  288. /// Generate mipmaps for non-3D textures. You have to transition all the mip levels of this face and layer to
  289. /// TextureUsageBit::GENERATE_MIPMAPS before calling this method.
  290. /// @param texView The texture view to generate mips. It should point to a subresource that contains the whole
  291. /// mip chain and only one face and one layer.
  292. void generateMipmaps2d(const TextureViewPtr& texView);
  293. /// Generate mipmaps only for 3D textures.
  294. /// @param texView The texture view to generate mips.
  295. void generateMipmaps3d(const TextureViewPtr& tex);
  296. /// Blit from surface to surface.
  297. /// @param srcView The source view that points to a surface.
  298. /// @param dstView The destination view that points to a surface.
  299. void blitTextureViews(const TextureViewPtr& srcView, const TextureViewPtr& destView);
  300. /// Clear a single texture surface. Can be used for all textures except 3D.
  301. /// @param[in,out] texView The texture view to clear.
  302. /// @param[in] clearValue The value to clear it with.
  303. void clearTextureView(const TextureViewPtr& texView, const ClearValue& clearValue);
  304. /// Copy a buffer to a texture surface or volume.
  305. /// @param buff The source buffer to copy from.
  306. /// @param offset The offset in the buffer to start reading from.
  307. /// @param range The size of the buffer to read.
  308. /// @param texView The texture view that points to a surface or volume to write to.
  309. void copyBufferToTextureView(const BufferPtr& buff, PtrSize offset, PtrSize range, const TextureViewPtr& texView);
  310. /// Fill a buffer with some value.
  311. /// @param[in,out] buff The buffer to fill.
  312. /// @param offset From where to start filling. Must be multiple of 4.
  313. /// @param size The bytes to fill. Must be multiple of 4 or MAX_PTR_SIZE to indicate the whole buffer.
  314. /// @param value The value to fill the buffer with.
  315. void fillBuffer(const BufferPtr& buff, PtrSize offset, PtrSize size, U32 value);
  316. /// Write the occlusion result to buffer.
  317. /// @param[in] query The query to get the result from.
  318. /// @param offset The offset inside the buffer to write the result.
  319. /// @param buff The buffer to update.
  320. void writeOcclusionQueryResultToBuffer(const OcclusionQueryPtr& query, PtrSize offset, const BufferPtr& buff);
  321. /// Copy buffer to buffer.
  322. /// @param[in] src Source buffer.
  323. /// @param srcOffset Offset in the src buffer.
  324. /// @param[out] dst Destination buffer.
  325. /// @param dstOffset Offset in the destination buffer.
  326. /// @param range Size to copy.
  327. void copyBufferToBuffer(const BufferPtr& src, PtrSize srcOffset, const BufferPtr& dst, PtrSize dstOffset,
  328. PtrSize range);
  329. /// Build the acceleration structure.
  330. void buildAccelerationStructure(const AccelerationStructurePtr& as);
  331. /// @}
  332. /// @name Sync
  333. /// @{
  334. void setTextureBarrier(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
  335. const TextureSubresourceInfo& subresource);
  336. void setTextureSurfaceBarrier(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
  337. const TextureSurfaceInfo& surf);
  338. void setTextureVolumeBarrier(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
  339. const TextureVolumeInfo& vol);
  340. void setBufferBarrier(const BufferPtr& buff, BufferUsageBit prevUsage, BufferUsageBit nextUsage, PtrSize offset,
  341. PtrSize size);
  342. void setAccelerationStructureBarrier(const AccelerationStructurePtr& as, AccelerationStructureUsageBit prevUsage,
  343. AccelerationStructureUsageBit nextUsage);
  344. /// @}
  345. /// @name Other
  346. /// @{
  347. /// Reset query before beginOcclusionQuery.
  348. void resetOcclusionQuery(const OcclusionQueryPtr& query);
  349. /// Begin query.
  350. void beginOcclusionQuery(const OcclusionQueryPtr& query);
  351. /// End query.
  352. void endOcclusionQuery(const OcclusionQueryPtr& query);
  353. /// Reset timestamp query before writeTimestamp.
  354. void resetTimestampQuery(const TimestampQueryPtr& query);
  355. /// Write a timestamp.
  356. void writeTimestamp(const TimestampQueryPtr& query);
  357. /// Append a second level command buffer.
  358. void pushSecondLevelCommandBuffer(const CommandBufferPtr& cmdb);
  359. Bool isEmpty() const;
  360. /// @}
  361. protected:
  362. /// Construct.
  363. CommandBuffer(GrManager* manager, CString name)
  364. : GrObject(manager, CLASS_TYPE, name)
  365. {
  366. }
  367. /// Destroy.
  368. ~CommandBuffer()
  369. {
  370. }
  371. private:
  372. /// Allocate and initialize a new instance.
  373. [[nodiscard]] static CommandBuffer* newInstance(GrManager* manager, const CommandBufferInitInfo& init);
  374. };
  375. /// @}
  376. } // end namespace anki