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