1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_RENDER_IRENDER_COMMAND_LIST_H
17 #define API_RENDER_IRENDER_COMMAND_LIST_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/array_view.h>
22 #include <base/util/uid.h>
23 #include <core/plugin/intf_interface.h>
24 #include <render/device/gpu_resource_desc.h>
25 #include <render/namespace.h>
26 #include <render/resource_handle.h>
27 
28 RENDER_BEGIN_NAMESPACE()
29 struct RenderPassDesc;
30 struct RenderPassSubpassDesc;
31 struct PushConstant;
32 struct IndexBuffer;
33 struct VertexBuffer;
34 struct ImageBlit;
35 
36 /** @ingroup group_render_irendercommandlist */
37 /** Call methods to add render commands to a render command list.
38  * Render command list is unique for every render node.
39  * Most of the methods and their inputs are familiar from different graphics APIs.
40  *
41  * RenderCommandList does not do heavy processing on unnecessary state changes etc.
42  * Prefer setting data, bindings etc. only once and do not add empty draw and/or dispatches.
43  */
44 class IRenderCommandList : public CORE_NS::IInterface {
45 public:
46     static constexpr auto UID = BASE_NS::Uid("744d8a3c-82cd-44f5-9fcb-769b33ceca1b");
47 
48     /** Can only be called inside of a render pass.
49      * @param vertexCount Vertex count
50      * @param instanceCount Instance count
51      * @param firstVertex First vertex
52      * @param firstInstance First instance
53      */
54     virtual void Draw(const uint32_t vertexCount, const uint32_t instanceCount, const uint32_t firstVertex,
55         const uint32_t firstInstance) = 0;
56 
57     /** Can only be called inside of a render pass.
58      * @param indexCount Index count
59      * @param instanceCount Instance count
60      * @param firstIndex First index
61      * @param vertexOffset Vertex offset
62      * @param firstInstance First instance
63      */
64     virtual void DrawIndexed(const uint32_t indexCount, const uint32_t instanceCount, const uint32_t firstIndex,
65         const int32_t vertexOffset, const uint32_t firstInstance) = 0;
66 
67     /** Draw with indirect arguments.
68      * Can only be called inside of a render pass.
69      * @param bufferHandle Buffer handle
70      * @param offset Offset
71      * @param drawCount Draw count
72      * @param stride Stride
73      */
74     virtual void DrawIndirect(
75         const RenderHandle bufferHandle, const uint32_t offset, const uint32_t drawCount, const uint32_t stride) = 0;
76 
77     /** Can only be called inside of a render pass.
78      * @param bufferHandle Buffer handle
79      * @param offset Offset
80      * @param drawCount Draw count
81      * @param stride Stride
82      */
83     virtual void DrawIndexedIndirect(
84         const RenderHandle bufferHandle, const uint32_t offset, const uint32_t drawCount, const uint32_t stride) = 0;
85 
86     /** Dispatch a compute program.
87      * @param groupCountX Group count x
88      * @param groupCountY Group count y
89      * @param groupCountZ Group count z
90      */
91     virtual void Dispatch(const uint32_t groupCountX, const uint32_t groupCountY, const uint32_t groupCountZ) = 0;
92 
93     /** Dispatch a compute program with indirect arguments.
94      * @param bufferHandle Buffer handle
95      * @param offset Offset
96      */
97     virtual void DispatchIndirect(const RenderHandle bufferHandle, const uint32_t offset) = 0;
98 
99     /** Bind pipeline
100      * @param psoHandle PSO handle
101      */
102     virtual void BindPipeline(const RenderHandle psoHandle) = 0;
103 
104     /** Push constant. The data is copied.
105      * @param pushConstant Push constant
106      * @param data Data
107      */
108     virtual void PushConstantData(
109         const struct PushConstant& pushConstant, const BASE_NS::array_view<const uint8_t> data) = 0;
110 
111     /** Push constant. The data is copied. Prefer using PushConstantData -method. This will be deprecated.
112      * @param pushConstant Push constant
113      * @param data Data
114      */
115     virtual void PushConstant(const struct PushConstant& pushConstant, const uint8_t* data) = 0;
116 
117     /** Bind vertex buffers
118      * @param vertexBuffers Vertex buffers
119      */
120     virtual void BindVertexBuffers(const BASE_NS::array_view<const VertexBuffer> vertexBuffers) = 0;
121 
122     /** Bind index buffer
123      * @param indexBuffer Index buffer
124      */
125     virtual void BindIndexBuffer(const IndexBuffer& indexBuffer) = 0;
126 
127     /** Draw-calls can only be made inside of a render pass.
128      * A render pass definition without content. Render pass needs to have
129      * SubpassContents::CORE_SUBPASS_CONTENTS_INLINE set.
130      * All subpasses given with subpassDescs.
131      * @param renderPassDesc Render pass descriptor
132      * @param subpassDescs Subpass descriptors
133      */
134     virtual void BeginRenderPass(
135         const RenderPassDesc& renderPassDesc, const BASE_NS::array_view<const RenderPassSubpassDesc> subpassDescs) = 0;
136 
137     /** Draw-calls can only be made inside of a render pass.
138      * A render pass definition without content. Render pass needs to have
139      * SubpassContents::CORE_SUBPASS_CONTENTS_INLINE set.
140      * Subpasses are patched to this render pass from other render command lists, if renderPassDesc.subpassCount > 1.
141      * There cannot be multiple "open" render passes from other render command lists.
142      * @param renderPassDesc Render pass descriptor
143      * @param subpassStartIndex Subpass start index
144      * @param subpassDesc Subpass descriptor
145      */
146     virtual void BeginRenderPass(const RenderPassDesc& renderPassDesc, const uint32_t subpassStartIndex,
147         const RenderPassSubpassDesc& subpassDesc) = 0;
148 
149     /** Must be called when a render pass ends. */
150     virtual void EndRenderPass() = 0;
151 
152     /** Next subpass
153      * @param subpassContents subpass contents
154      */
155     virtual void NextSubpass(const SubpassContents& subpassContents) = 0;
156 
157     /** This will disable automatic barriers until EndExecuteAutomaticBarriers is called.
158      * This will add a barrier point for current pending barriers.
159      * Use when manually adding barriers and executing them in a single spot.
160      * In addition, disables initial image layouts in render passes and uses undefined layouts.
161      */
162     virtual void BeginDisableAutomaticBarrierPoints() = 0;
163 
164     /** Re-enable automatic barriers.
165      * Needs to be called after BeginDisableAutomaticBarrierPoints to re-enable automatic barriers.
166      */
167     virtual void EndDisableAutomaticBarrierPoints() = 0;
168 
169     /** This will add custom barrier point where all pending (custom) barriers will be executed.
170      */
171     virtual void AddCustomBarrierPoint() = 0;
172 
173     /** Add custom memory barrier.
174      * Can be used for a memory barrier.
175      * @param src General barrier source state
176      * @param dst General barrier destination state
177      */
178     virtual void CustomMemoryBarrier(const GeneralBarrier& src, const GeneralBarrier& dst) = 0;
179 
180     /** Add custom barriers for a GPU buffer.
181      * Can only be called outside of render pass.
182      * @param handle Handle to resource
183      * @param src Source buffer resource barrier
184      * @param dst Destination buffer resource barrier
185      * @param byteOffset Byte offset
186      * @param byteSize Byte size (use PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE for the whole buffer)
187      */
188     virtual void CustomBufferBarrier(const RenderHandle handle, const BufferResourceBarrier& src,
189         const BufferResourceBarrier& dst, const uint32_t byteOffset, const uint32_t byteSize) = 0;
190 
191     /** Add custom barriers for a GPU image.
192      * Can only be called outside of render pass.
193      * Checks the current/correct state and layout, and updates to new given dst state.
194      * @param handle Handle to resource
195      * @param dst Destination image resource barrier
196      * @param imageSubresourceRange ImageSubresourceRange
197      */
198     virtual void CustomImageBarrier(const RenderHandle handle, const ImageResourceBarrier& dst,
199         const ImageSubresourceRange& imageSubresourceRange) = 0;
200     /** Add custom barriers for a GPU image.
201      * Can only be called outside of render pass.
202      * Does not check the current/correct state and layout. Can be used e.g. as a barrier from undefined state.
203      * @param handle Handle to resource
204      * @param src Source image resource barrier
205      * @param dst Destination image resource barrier
206      * @param imageSubresourceRange ImageSubresourceRange
207      */
208     virtual void CustomImageBarrier(const RenderHandle handle, const ImageResourceBarrier& src,
209         const ImageResourceBarrier& dst, const ImageSubresourceRange& imageSubresourceRange) = 0;
210 
211     /** Copy buffer to buffer
212      * @param srcHandle Source handle
213      * @param dstHandle Destination handle
214      * @param bufferCopy Buffer copy
215      */
216     virtual void CopyBufferToBuffer(
217         const RenderHandle srcHandle, const RenderHandle dstHandle, const BufferCopy& bufferCopy) = 0;
218 
219     /** Copy buffer to image
220      * @param srcHandle Source handle
221      * @param dstHandle Destination handle
222      * @param bufferImageCopy Buffer image copy
223      */
224     virtual void CopyBufferToImage(
225         const RenderHandle srcHandle, const RenderHandle dstHandle, const BufferImageCopy& bufferImageCopy) = 0;
226 
227     /** Copy image to buffer
228      * @param srcHandle Source handle
229      * @param dstHandle Destination handle
230      * @param bufferImageCopy Buffer image copy
231      */
232     virtual void CopyImageToBuffer(
233         const RenderHandle srcHandle, const RenderHandle dstHandle, const BufferImageCopy& bufferImageCopy) = 0;
234 
235     /** Copy image to image
236      * @param srcHandle Source handle
237      * @param dstHandle Destination handle
238      * @param imageCopy Image copy
239      */
240     virtual void CopyImageToImage(
241         const RenderHandle srcHandle, const RenderHandle dstHandle, const ImageCopy& imageCopy) = 0;
242 
243     /** Blit source image to destination image.
244      * Can only be called outside of render pass.
245      * @param srcImageHandle Source handle
246      * @param dstImageHandle Destination handle
247      * @param imageBlit Image blit
248      * @param filter Filtering mode
249      */
250     virtual void BlitImage(const RenderHandle srcImageHandle, const RenderHandle dstImageHandle,
251         const ImageBlit& imageBlit, const Filter filter) = 0;
252 
253     /** Update a single descriptor set with given bindings.
254      * @param handle Handle used in update
255      * @param bindingResources Binding resources
256      */
257     virtual void UpdateDescriptorSet(
258         const RenderHandle handle, const DescriptorSetLayoutBindingResources& bindingResources) = 0;
259 
260     /** Update descriptor sets with given bindings. Array view sizes must match.
261      * @param handles Handles for descriptor sets
262      * @param bindingResources Binding resources for descriptor sets
263      */
264     virtual void UpdateDescriptorSets(const BASE_NS::array_view<const RenderHandle> handles,
265         const BASE_NS::array_view<const DescriptorSetLayoutBindingResources> bindingResources) = 0;
266 
267     /** Bind a single descriptor set to pipeline.
268      * There can be maximum of 4 sets. I.e. the maximum set index is 3.
269      * @param set Set to bind
270      * @param handle Handle to resource
271      */
272     virtual void BindDescriptorSet(const uint32_t set, const RenderHandle handle) = 0;
273 
274     /** Bind a single descriptor set to pipeline.
275      * There can be maximum of 4 sets. I.e. the maximum set index is 3.
276      * @param set Set to bind
277      * @param handle Handle to resource
278      * @param dynamicOffsets Byte offsets for dynamic descriptors
279      */
280     virtual void BindDescriptorSet(
281         const uint32_t set, const RenderHandle handle, const BASE_NS::array_view<const uint32_t> dynamicOffsets) = 0;
282 
283     /** Bind multiple descriptor sets to pipeline.
284      * There can be maximum of 4 sets. I.e. the maximum set index is 3.
285      * Descriptor sets needs to be a contiguous set.
286      * @param firstSet First set index
287      * @param handles Handles to resources
288      */
289     virtual void BindDescriptorSets(const uint32_t firstSet, const BASE_NS::array_view<const RenderHandle> handles) = 0;
290 
291     /** BindDescriptorSetData
292      */
293     struct BindDescriptorSetData {
294         /** Descriptor set handle */
295         RenderHandle handle;
296         /** Descriptor set dynamic buffer offsets */
297         BASE_NS::array_view<const uint32_t> dynamicOffsets;
298     };
299 
300     /** Bind a single descriptor set to pipeline.
301      * There can be maximum of 4 sets. I.e. the maximum set index is 3.
302      * @param set Set to bind
303      * @param descriptorSetData Descriptor set data
304      */
305     virtual void BindDescriptorSet(const uint32_t set, const BindDescriptorSetData& desriptorSetData) = 0;
306 
307     /** Bind multiple descriptor sets to pipeline some with dynamic offsets.
308      * There can be maximum of 4 sets. I.e. the maximum set index is 3.
309      * Descriptor sets needs to be a contiguous set.
310      * @param firstSet First set index
311      * @param descriptorSetData Descriptor set data
312      */
313     virtual void BindDescriptorSets(
314         const uint32_t firstSet, const BASE_NS::array_view<const BindDescriptorSetData> descriptorSetData) = 0;
315 
316     /** Build acceleration structures
317      * @param geometry Acceleration structure build geometry data
318      * @param triangles Geometry triangles
319      * @param aabbs Geometry aabbs
320      * @param instances Geometry instances
321      */
322     virtual void BuildAccelerationStructures(const AccelerationStructureBuildGeometryData& geometry,
323         const BASE_NS::array_view<const AccelerationStructureGeometryTrianglesData> triangles,
324         const BASE_NS::array_view<const AccelerationStructureGeometryAabbsData> aabbs,
325         const BASE_NS::array_view<const AccelerationStructureGeometryInstancesData> instances) = 0;
326 
327     /** Clear color image.
328      * This should only be needed when initializing images to some values.
329      * Often render pass attachment clears and shader clears are needed.
330      * Some backends might not support this, i.e. one might need to use higher level paths for e.g. OpenGLES
331      * @param handle Handle of the image
332      * @param color Clear color values
333      * @param ranges Array view of image subresource ranges
334      */
335     virtual void ClearColorImage(const RenderHandle handle, const ClearColorValue color,
336         const BASE_NS::array_view<const ImageSubresourceRange> ranges) = 0;
337 
338     /** Set dynamic state viewport
339      * @param viewportDesc Viewport descriptor
340      */
341     virtual void SetDynamicStateViewport(const ViewportDesc& viewportDesc) = 0;
342 
343     /** Set dynamic state scissor
344      * @param scissorDesc Scissor descriptor
345      */
346     virtual void SetDynamicStateScissor(const ScissorDesc& scissorDesc) = 0;
347 
348     /** Set dynamic state line width
349      * @param lineWidth Line width
350      */
351     virtual void SetDynamicStateLineWidth(const float lineWidth) = 0;
352 
353     /** Set dynamic state depth bias
354      * @param depthBiasConstantFactor Depth bias constant factor
355      * @param depthBiasClamp Depth bias clamp
356      * @param depthBiasSlopeFactor Depth bias slope factor
357      */
358     virtual void SetDynamicStateDepthBias(
359         const float depthBiasConstantFactor, const float depthBiasClamp, const float depthBiasSlopeFactor) = 0;
360 
361     /** Set dynamic state blend constants
362      * @param blendConstants Blend constants
363      */
364     virtual void SetDynamicStateBlendConstants(const BASE_NS::array_view<const float> blendConstants) = 0;
365 
366     /** Set dynamic state depth bounds
367      * @param minDepthBounds Min depth bounds
368      * @param maxDepthBounds Max depth bounds
369      */
370     virtual void SetDynamicStateDepthBounds(const float minDepthBounds, const float maxDepthBounds) = 0;
371 
372     /** Set dynamic state stencil compare mask
373      * @param faceMask Face mask
374      * @param compareMask Compare mask
375      */
376     virtual void SetDynamicStateStencilCompareMask(const StencilFaceFlags faceMask, const uint32_t compareMask) = 0;
377 
378     /** Set dynamic state stencil write mask
379      * @param faceMask Face mask
380      * @param writeMask Write mask
381      */
382     virtual void SetDynamicStateStencilWriteMask(const StencilFaceFlags faceMask, const uint32_t writeMask) = 0;
383 
384     /** Set dynamic state stencil reference
385      * @param faceMask Face mask
386      * @param reference Reference
387      */
388     virtual void SetDynamicStateStencilReference(const StencilFaceFlags faceMask, const uint32_t reference) = 0;
389 
390     /** Set dynamic state fragmend shading rate.
391      * @param fragmentSize Fragment size, pipeline fragment shading rate. (Valid values 1, 2, 4)
392      * @param combinerOps Combiner operations
393      */
394     virtual void SetDynamicStateFragmentShadingRate(
395         const Size2D& fragmentSize, const FragmentShadingRateCombinerOps& combinerOps) = 0;
396 
397     /** Set execute backend frame position. The position where the method is ran.
398      * Often this might be the only command in the render command list, when using backend nodes.
399      * This can be set only once during render command list setup per frame.
400      */
401     virtual void SetExecuteBackendFramePosition() = 0;
402 
403 protected:
404     IRenderCommandList() = default;
405     virtual ~IRenderCommandList() = default;
406 
407     IRenderCommandList(const IRenderCommandList&) = delete;
408     IRenderCommandList& operator=(const IRenderCommandList&) = delete;
409     IRenderCommandList(IRenderCommandList&&) = delete;
410     IRenderCommandList& operator=(IRenderCommandList&&) = delete;
411 };
412 RENDER_END_NAMESPACE()
413 
414 #endif // API_RENDER_IRENDER_COMMAND_LIST_H
415