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