CommandBuffer.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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. #pragma once
  6. #include <AnKi/Gr/GrObject.h>
  7. #include <AnKi/Gr/Buffer.h>
  8. #include <AnKi/Gr/Texture.h>
  9. #include <AnKi/Util/Functions.h>
  10. #include <AnKi/Util/WeakArray.h>
  11. #include <AnKi/Math.h>
  12. namespace anki {
  13. /// @addtogroup graphics
  14. /// @{
  15. class TextureBarrierInfo
  16. {
  17. public:
  18. TextureView m_textureView;
  19. TextureUsageBit m_previousUsage = TextureUsageBit::kNone;
  20. TextureUsageBit m_nextUsage = TextureUsageBit::kNone;
  21. };
  22. class BufferBarrierInfo
  23. {
  24. public:
  25. BufferView m_bufferView;
  26. BufferUsageBit m_previousUsage = BufferUsageBit::kNone;
  27. BufferUsageBit m_nextUsage = BufferUsageBit::kNone;
  28. };
  29. class AccelerationStructureBarrierInfo
  30. {
  31. public:
  32. AccelerationStructure* m_as = nullptr;
  33. AccelerationStructureUsageBit m_previousUsage = AccelerationStructureUsageBit::kNone;
  34. AccelerationStructureUsageBit m_nextUsage = AccelerationStructureUsageBit::kNone;
  35. };
  36. class CopyBufferToBufferInfo
  37. {
  38. public:
  39. PtrSize m_sourceOffset = 0;
  40. PtrSize m_destinationOffset = 0;
  41. PtrSize m_range = 0;
  42. };
  43. class RenderTarget
  44. {
  45. public:
  46. TextureView m_textureView;
  47. RenderTargetLoadOperation m_loadOperation = RenderTargetLoadOperation::kClear;
  48. RenderTargetStoreOperation m_storeOperation = RenderTargetStoreOperation::kStore;
  49. RenderTargetLoadOperation m_stencilLoadOperation = RenderTargetLoadOperation::kClear;
  50. RenderTargetStoreOperation m_stencilStoreOperation = RenderTargetStoreOperation::kStore;
  51. ClearValue m_clearValue;
  52. TextureUsageBit m_usage = TextureUsageBit::kRtvDsvWrite;
  53. RenderTarget() = default;
  54. RenderTarget(const TextureView& view)
  55. : m_textureView(view)
  56. {
  57. }
  58. };
  59. /// Command buffer initialization flags.
  60. enum class CommandBufferFlag : U8
  61. {
  62. kNone = 0,
  63. /// It will contain a handfull of commands.
  64. kSmallBatch = 1 << 0,
  65. /// Will contain graphics, compute and transfer work.
  66. kGeneralWork = 1 << 1,
  67. /// Will contain only compute work. It binds to async compute queues.
  68. kComputeWork = 1 << 2,
  69. };
  70. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(CommandBufferFlag)
  71. /// Command buffer init info.
  72. class CommandBufferInitInfo : public GrBaseInitInfo
  73. {
  74. public:
  75. CommandBufferFlag m_flags = CommandBufferFlag::kGeneralWork;
  76. CommandBufferInitInfo(CString name = {})
  77. : GrBaseInitInfo(name)
  78. {
  79. }
  80. CommandBufferInitInfo(CommandBufferFlag flags, CString name = {})
  81. : GrBaseInitInfo(name)
  82. , m_flags(flags)
  83. {
  84. }
  85. };
  86. /// Command buffer.
  87. class CommandBuffer : public GrObject
  88. {
  89. ANKI_GR_OBJECT
  90. public:
  91. static constexpr GrObjectType kClassType = GrObjectType::kCommandBuffer;
  92. CommandBufferFlag getFlags() const
  93. {
  94. return m_flags;
  95. }
  96. /// Finalize the command buffer.
  97. void endRecording();
  98. /// @name State manipulation
  99. /// @{
  100. /// Bind vertex buffer.
  101. void bindVertexBuffer(U32 binding, const BufferView& buff, U32 stride, VertexStepRate stepRate = VertexStepRate::kVertex);
  102. /// Setup a vertex attribute.
  103. void setVertexAttribute(VertexAttributeSemantic attribute, U32 buffBinding, Format fmt, U32 relativeOffset);
  104. /// Bind index buffer.
  105. void bindIndexBuffer(const BufferView& buff, IndexType type);
  106. /// Enable primitive restart.
  107. void setPrimitiveRestart(Bool enable);
  108. /// Set the viewport.
  109. void setViewport(U32 minx, U32 miny, U32 width, U32 height);
  110. /// Set the scissor rect. To disable the scissor just set a rect bigger than the viewport. By default it's disabled.
  111. void setScissor(U32 minx, U32 miny, U32 width, U32 height);
  112. /// Set fill mode.
  113. void setFillMode(FillMode mode);
  114. /// Set cull mode.
  115. /// By default it's FaceSelectionBit::kBack.
  116. void setCullMode(FaceSelectionBit mode);
  117. /// Set depth offset and units. Set zeros to both to disable it.
  118. void setPolygonOffset(F32 factor, F32 units);
  119. /// Set stencil operations. To disable stencil test put StencilOperation::KEEP to all operations.
  120. void setStencilOperations(FaceSelectionBit face, StencilOperation stencilFail, StencilOperation stencilPassDepthFail,
  121. StencilOperation stencilPassDepthPass);
  122. /// Set stencil compare operation.
  123. void setStencilCompareOperation(FaceSelectionBit face, CompareOperation comp);
  124. /// Set the stencil compare mask.
  125. void setStencilCompareMask(FaceSelectionBit face, U32 mask);
  126. /// Set the stencil write mask.
  127. void setStencilWriteMask(FaceSelectionBit face, U32 mask);
  128. /// Set the stencil reference.
  129. void setStencilReference(FaceSelectionBit face, U32 ref);
  130. /// Enable/disable depth write. To disable depth testing set depth write to false and depth compare operation to
  131. /// always.
  132. void setDepthWrite(Bool enable);
  133. /// Set depth compare operation. By default it's less.
  134. void setDepthCompareOperation(CompareOperation op);
  135. /// Enable/disable alpha to coverage.
  136. void setAlphaToCoverage(Bool enable);
  137. /// Set color channel write mask.
  138. void setColorChannelWriteMask(U32 attachment, ColorBit mask);
  139. /// Set blend factors seperate.
  140. /// By default the values of srcRgb, dstRgb, srcA and dstA are BlendFactor::ONE, BlendFactor::ZERO,
  141. /// BlendFactor::ONE, BlendFactor::ZERO respectively.
  142. void setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA);
  143. /// Set blend factors.
  144. void setBlendFactors(U32 attachment, BlendFactor src, BlendFactor dst)
  145. {
  146. setBlendFactors(attachment, src, dst, src, dst);
  147. }
  148. /// Set the blend operation seperate.
  149. /// By default the values of funcRgb and funcA are BlendOperation::ADD, BlendOperation::ADD respectively.
  150. void setBlendOperation(U32 attachment, BlendOperation funcRgb, BlendOperation funcA);
  151. /// Set the blend operation.
  152. void setBlendOperation(U32 attachment, BlendOperation func)
  153. {
  154. setBlendOperation(attachment, func, func);
  155. }
  156. /// Set the line width. By default it's undefined.
  157. void setLineWidth(F32 lineWidth);
  158. /// Bind constant buffer.
  159. void bindConstantBuffer(U32 reg, U32 space, const BufferView& buff);
  160. /// Bind sampler.
  161. void bindSampler(U32 reg, U32 space, Sampler* sampler);
  162. /// Bind a texture.
  163. void bindSrv(U32 reg, U32 space, const TextureView& texView);
  164. /// Bind a buffer.
  165. void bindSrv(U32 reg, U32 space, const BufferView& buffer, Format fmt = Format::kNone);
  166. /// Bind AS.
  167. void bindSrv(U32 reg, U32 space, AccelerationStructure* as);
  168. /// Bind a texture.
  169. void bindUav(U32 reg, U32 space, const TextureView& texView);
  170. /// Bind a buffer.
  171. void bindUav(U32 reg, U32 space, const BufferView& buffer, Format fmt = Format::kNone);
  172. /// Set push constants (Vulkan) or root constants (D3D).
  173. void setFastConstants(const void* data, U32 dataSize);
  174. /// Bind a program.
  175. void bindShaderProgram(ShaderProgram* prog);
  176. /// Begin a renderpass.
  177. void beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, const TextureView& vrsRt = TextureView(),
  178. U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0);
  179. /// See beginRenderPass.
  180. void beginRenderPass(std::initializer_list<RenderTarget> colorRts, RenderTarget* depthStencilRt = nullptr,
  181. const TextureView& vrsRt = TextureView(), U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0)
  182. {
  183. beginRenderPass(ConstWeakArray(colorRts.begin(), U32(colorRts.size())), depthStencilRt, vrsRt, vrsRtTexelSizeX, vrsRtTexelSizeY);
  184. }
  185. /// End renderpass.
  186. void endRenderPass();
  187. /// Set VRS rate of the following drawcalls. By default it's 1x1.
  188. void setVrsRate(VrsRate rate);
  189. /// @}
  190. /// @name Jobs
  191. /// @{
  192. void drawIndexed(PrimitiveTopology topology, U32 count, U32 instanceCount = 1, U32 firstIndex = 0, U32 baseVertex = 0, U32 baseInstance = 0);
  193. void draw(PrimitiveTopology topology, U32 count, U32 instanceCount = 1, U32 first = 0, U32 baseInstance = 0);
  194. void drawIndexedIndirect(PrimitiveTopology topology, const BufferView& indirectBuff, U32 drawCount = 1);
  195. void drawIndirect(PrimitiveTopology topology, const BufferView& indirectBuff, U32 drawCount = 1);
  196. void drawIndexedIndirectCount(PrimitiveTopology topology, const BufferView& argBuffer, U32 argBufferStride, const BufferView& countBuffer,
  197. U32 maxDrawCount);
  198. void drawIndirectCount(PrimitiveTopology topology, const BufferView& argBuffer, U32 argBufferStride, const BufferView& countBuffer,
  199. U32 maxDrawCount);
  200. void drawMeshTasks(U32 groupCountX, U32 groupCountY, U32 groupCountZ);
  201. void drawMeshTasksIndirect(const BufferView& argBuffer, U32 drawCount = 1);
  202. void dispatchCompute(U32 groupCountX, U32 groupCountY, U32 groupCountZ);
  203. void dispatchComputeIndirect(const BufferView& argBuffer);
  204. void dispatchGraph(const BufferView& scratchBuffer, const void* records, U32 recordCount, U32 recordStride);
  205. /// Trace rays.
  206. ///
  207. /// The 1st thing in the sbtBuffer is the ray gen shader group handle:
  208. /// @code RG = RG_offset @endcode
  209. /// The RG_offset is equal to the sbtBuffer.getOffset().
  210. ///
  211. /// Then the sbtBuffer contains the miss shader group handles and their data. The indexing is as follows:
  212. /// @code M = M_offset + M_stride * R_miss @endcode
  213. /// The M_offset is equal to sbtBuffer.getOffset() + GpuDeviceCapabilities::m_sbtRecordSize.
  214. /// The M_stride is equal to GpuDeviceCapabilities::m_sbtRecordSize.
  215. /// The R_miss is defined in the traceRayEXT and it's the "ray type".
  216. ///
  217. /// After the miss shaders the sbtBuffer has the hit group shader group handles and their data. The indexing is:
  218. /// @code HG = HG_offset + (HG_stride * (R_offset + R_stride * G_id + I_offset)) @endcode
  219. /// The HG_offset is equal to sbtBufferOffset + GpuDeviceCapabilities::m_sbtRecordSize * (missShaderCount + 1).
  220. /// The HG_stride is equal GpuDeviceCapabilities::m_sbtRecordSize * rayTypecount.
  221. /// The R_offset and R_stride are provided in traceRayEXT. The R_offset is the "ray type" and R_stride the number of ray types.
  222. /// The G_id is always 0 ATM.
  223. /// The I_offset is the AccelerationStructureInstance::m_hitgroupSbtRecordIndex.
  224. ///
  225. /// @param[in] sbtBuffer The SBT buffer.
  226. /// @param sbtRecordSize The size of an SBT record
  227. /// @param hitGroupSbtRecordCount The number of SBT records that contain hit groups.
  228. /// @param rayTypecount The number of ray types hosted in the pipeline. See above on how it's been used.
  229. /// @param width Width.
  230. /// @param height Height.
  231. /// @param depth Depth.
  232. void dispatchRays(const BufferView& sbtBuffer, U32 sbtRecordSize, U32 hitGroupSbtRecordCount, U32 rayTypeCount, U32 width, U32 height, U32 depth);
  233. /// Same as dispatchRays but indirect.
  234. void dispatchRaysIndirect(const BufferView& sbtBuffer, U32 sbtRecordSize, U32 hitGroupSbtRecordCount, U32 rayTypeCount, BufferView argsBuffer);
  235. /// Blit from surface to surface.
  236. void blitTexture(const TextureView& srcView, const TextureView& destView);
  237. /// Clear a single texture surface. Can be used for all textures except 3D.
  238. void clearTexture(const TextureView& texView, const ClearValue& clearValue);
  239. /// Copy a buffer to a texture surface or volume.
  240. void copyBufferToTexture(const BufferView& buff, const TextureView& texView, const TextureRect& rect = TextureRect());
  241. /// Fill a buffer with zeros. It's a copy operation.
  242. void zeroBuffer(const BufferView& buff);
  243. /// Write the occlusion result to buffer.
  244. void writeOcclusionQueriesResultToBuffer(ConstWeakArray<OcclusionQuery*> queries, const BufferView& buff);
  245. /// Copy buffer to buffer.
  246. void copyBufferToBuffer(const BufferView& src, const BufferView& dst)
  247. {
  248. ANKI_ASSERT(src.getRange() == dst.getRange());
  249. Array<CopyBufferToBufferInfo, 1> copies = {{{src.getOffset(), dst.getOffset(), src.getRange()}}};
  250. copyBufferToBuffer(&src.getBuffer(), &dst.getBuffer(), copies);
  251. }
  252. /// Copy buffer to buffer.
  253. void copyBufferToBuffer(Buffer* src, Buffer* dst, ConstWeakArray<CopyBufferToBufferInfo> copies);
  254. /// Build the acceleration structure.
  255. void buildAccelerationStructure(AccelerationStructure* as, const BufferView& scratchBuffer);
  256. /// Do upscaling by an external upscaler
  257. /// @param[in] upscaler the upscaler to use for upscaling
  258. /// @param[in] inColor Source LowRes RenderTarget.
  259. /// @param[out] outUpscaledColor Destination HighRes RenderTarget
  260. /// @param[in] motionVectors Motion Vectors
  261. /// @param[in] depth Depth attachment
  262. /// @param[in] exposure 1x1 Texture containing exposure
  263. /// @param[in] resetAccumulation Whether to clean or not any temporal history
  264. /// @param[in] jitterOffset Jittering offset that was applied during the generation of sourceTexture
  265. /// @param[in] motionVectorsScale Any scale factor that might need to be applied to the motionVectorsTexture (i.e UV space to Pixel space
  266. /// conversion)
  267. void upscale(GrUpscaler* upscaler, const TextureView& inColor, const TextureView& outUpscaledColor, const TextureView& motionVectors,
  268. const TextureView& depth, const TextureView& exposure, Bool resetAccumulation, const Vec2& jitterOffset,
  269. const Vec2& motionVectorsScale);
  270. /// @}
  271. /// @name Sync
  272. /// @{
  273. void setPipelineBarrier(ConstWeakArray<TextureBarrierInfo> textures, ConstWeakArray<BufferBarrierInfo> buffers,
  274. ConstWeakArray<AccelerationStructureBarrierInfo> accelerationStructures);
  275. /// @}
  276. /// @name Other
  277. /// @{
  278. /// Begin query.
  279. void beginOcclusionQuery(OcclusionQuery* query);
  280. /// End query.
  281. void endOcclusionQuery(OcclusionQuery* query);
  282. /// Begin query.
  283. void beginPipelineQuery(PipelineQuery* query);
  284. /// End query.
  285. void endPipelineQuery(PipelineQuery* query);
  286. /// Write a timestamp.
  287. void writeTimestamp(TimestampQuery* query);
  288. Bool isEmpty() const;
  289. void pushDebugMarker(CString name, Vec3 color);
  290. void popDebugMarker();
  291. /// @}
  292. protected:
  293. CommandBufferFlag m_flags = CommandBufferFlag::kNone;
  294. /// Construct.
  295. CommandBuffer(CString name)
  296. : GrObject(kClassType, name)
  297. {
  298. }
  299. /// Destroy.
  300. ~CommandBuffer()
  301. {
  302. }
  303. private:
  304. /// Allocate and initialize a new instance.
  305. [[nodiscard]] static CommandBuffer* newInstance(const CommandBufferInitInfo& init);
  306. };
  307. /// @}
  308. } // end namespace anki