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 CORE_RENDER_RENDER_COMMAND_LIST_H
17 #define CORE_RENDER_RENDER_COMMAND_LIST_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include <base/containers/array_view.h>
23 #include <base/containers/string.h>
24 #include <base/containers/string_view.h>
25 #include <base/containers/unique_ptr.h>
26 #include <base/containers/vector.h>
27 #include <render/namespace.h>
28 #include <render/nodecontext/intf_render_command_list.h>
29 #include <render/render_data_structures.h>
30 #include <render/resource_handle.h>
31 
32 RENDER_BEGIN_NAMESPACE()
33 class GpuResourceManager;
34 class LinearAllocator;
35 class NodeContextDescriptorSetManager;
36 class NodeContextPsoManager;
37 class RenderNodeContextManager;
38 
39 enum class DrawType : uint32_t {
40     UNDEFINED = 0,
41     DRAW = 1,
42     DRAW_INDEXED = 2,
43     DRAW_INDIRECT = 3,
44     DRAW_INDEXED_INDIRECT = 4,
45 };
46 
47 // BarrierPoint is a special command which will be added before render commands
48 // that need some kind of syncing.
49 // RenderGraph is responsible for updating the barriers to be correct.
50 //
51 // BarrierPoint is added for:
52 //
53 // BeginRenderPass
54 // Dispatch
55 // DispatchIndirect
56 //
57 // CopyBuffer
58 // CopyBufferImage
59 // BlitImage
60 // ClearColorImage
61 
62 enum class RenderCommandType : uint32_t {
63     UNDEFINED,
64     DRAW,
65     DRAW_INDIRECT,
66     DISPATCH,
67     DISPATCH_INDIRECT,
68     BIND_PIPELINE,
69     BEGIN_RENDER_PASS,
70     NEXT_SUBPASS,
71     END_RENDER_PASS,
72     BIND_VERTEX_BUFFERS,
73     BIND_INDEX_BUFFER,
74     COPY_BUFFER,
75     COPY_BUFFER_IMAGE,
76     COPY_IMAGE,
77     BLIT_IMAGE,
78 
79     BARRIER_POINT,
80 
81     BIND_DESCRIPTOR_SETS,
82 
83     PUSH_CONSTANT,
84 
85     BUILD_ACCELERATION_STRUCTURE,
86 
87     CLEAR_COLOR_IMAGE,
88 
89     DYNAMIC_STATE_VIEWPORT,
90     DYNAMIC_STATE_SCISSOR,
91     DYNAMIC_STATE_LINE_WIDTH,
92     DYNAMIC_STATE_DEPTH_BIAS,
93     DYNAMIC_STATE_BLEND_CONSTANTS,
94     DYNAMIC_STATE_DEPTH_BOUNDS,
95     DYNAMIC_STATE_STENCIL,
96     DYNAMIC_STATE_FRAGMENT_SHADING_RATE,
97 
98     EXECUTE_BACKEND_FRAME_POSITION,
99 
100     WRITE_TIMESTAMP,
101 
102     GPU_QUEUE_TRANSFER_RELEASE,
103     GPU_QUEUE_TRANSFER_ACQUIRE,
104 
105     COUNT, // used as the number of values and must be last
106 };
107 
108 #if RENDER_DEBUG_COMMAND_MARKERS_ENABLED
109 // These names should match the RenderCommandType enum values.
110 constexpr const char* COMMAND_NAMES[] = {
111     "Undefined",
112     "Draw",
113     "DrawIndirect",
114     "Dispatch",
115     "DispatchIndirect",
116     "BindPipeline",
117     "BeginRenderPass",
118     "NextSubpass",
119     "EndRenderPass",
120     "BindVertexBuffers",
121     "BindIndexBuffer",
122     "CopyBuffer",
123     "CopyBufferImage",
124     "CopyImage",
125     "BlitImage",
126 
127     "BarrierPoint",
128     "BindDescriptorSets",
129 
130     "PushConstant",
131 
132     "BuildAccelerationStructures",
133 
134     "ClearColorImage",
135 
136     "DynamicStateViewport",
137     "DynamicStateScissor",
138     "DynamicStateLineWidth",
139     "DynamicStateDepthBias",
140     "DynamicStateBlendConstants",
141     "DynamicStateDepthBounds",
142     "DynamicStateStencil",
143     "DynamicStateFragmentShadingRate",
144 
145     "ExecuteBackendFramePosition",
146 
147     "WriteTimestamp",
148 
149     "GpuQueueTransferRelease",
150     "GpuQueueTransferAcquire",
151 };
152 static_assert(BASE_NS::countof(COMMAND_NAMES) == (static_cast<uint32_t>(RenderCommandType::COUNT)));
153 #endif
154 
155 enum class RenderPassBeginType : uint32_t {
156     RENDER_PASS_BEGIN,
157     RENDER_PASS_SUBPASS_BEGIN, // multi render commandlist render pass subpass begin
158 };
159 
160 enum class RenderPassEndType : uint32_t {
161     END_RENDER_PASS,
162     END_SUBPASS,
163 };
164 
165 struct RenderCommandDraw {
166     DrawType drawType { DrawType::UNDEFINED };
167 
168     uint32_t vertexCount { 0 };
169     uint32_t instanceCount { 0 };
170     uint32_t firstVertex { 0 };
171     uint32_t firstInstance { 0 };
172 
173     uint32_t indexCount { 0 };
174     uint32_t firstIndex { 0 };
175     int32_t vertexOffset { 0 };
176 };
177 
178 struct RenderCommandDrawIndirect {
179     DrawType drawType { DrawType::UNDEFINED };
180 
181     RenderHandle argsHandle;
182     uint32_t offset { 0 };
183     uint32_t drawCount { 0 };
184     uint32_t stride { 0 };
185 };
186 
187 struct RenderCommandDispatch {
188     uint32_t groupCountX { 0 };
189     uint32_t groupCountY { 0 };
190     uint32_t groupCountZ { 0 };
191 };
192 
193 struct RenderCommandDispatchIndirect {
194     RenderHandle argsHandle;
195     uint32_t offset { 0 };
196 };
197 
198 struct RenderCommandBindPipeline {
199     RenderHandle psoHandle;
200     PipelineBindPoint pipelineBindPoint;
201 };
202 
203 struct RenderCommandBindDescriptorSets {
204     RenderHandle psoHandle; // this is the previously BindPipeline() pso handle
205 
206     uint32_t firstSet { 0u };
207     uint32_t setCount { 0u };
208     RenderHandle descriptorSetHandles[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT] { {}, {}, {}, {} };
209 
210     struct DescriptorSetDynamicOffsets {
211         uint32_t dynamicOffsetCount { 0u };
212         uint32_t* dynamicOffsets { nullptr };
213     };
214     DescriptorSetDynamicOffsets descriptorSetDynamicOffsets[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
215 };
216 
217 struct RenderPassImageLayouts {
218     // counts are the same as in RenderPassDesc
219     // these layouts are used for render pass hashing
220     // layouts in the beginning of the render pass
221     ImageLayout attachmentInitialLayouts[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] {
222         ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED
223     };
224 
225     // layouts after the render pass
226     ImageLayout attachmentFinalLayouts[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] {
227         ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED
228     };
229 };
230 
231 struct RenderPassAttachmentResourceStates {
232     // the state of resources when used in render pass (subpasses)
233     GpuResourceState states[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] {};
234     ImageLayout layouts[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] { CORE_IMAGE_LAYOUT_UNDEFINED,
235         CORE_IMAGE_LAYOUT_UNDEFINED, CORE_IMAGE_LAYOUT_UNDEFINED, CORE_IMAGE_LAYOUT_UNDEFINED,
236         CORE_IMAGE_LAYOUT_UNDEFINED, CORE_IMAGE_LAYOUT_UNDEFINED, CORE_IMAGE_LAYOUT_UNDEFINED,
237         CORE_IMAGE_LAYOUT_UNDEFINED };
238 };
239 
240 struct RenderCommandBeginRenderPass {
241     RenderPassBeginType beginType { RenderPassBeginType::RENDER_PASS_BEGIN };
242     RenderPassDesc renderPassDesc;
243     RenderPassImageLayouts imageLayouts;
244     RenderPassAttachmentResourceStates inputResourceStates;
245     bool enableAutomaticLayoutChanges { true };
246 
247     uint32_t subpassStartIndex { 0 }; // patched multi render command list render passes can have > 0
248     BASE_NS::array_view<RenderPassSubpassDesc> subpasses;
249     BASE_NS::array_view<RenderPassAttachmentResourceStates> subpassResourceStates;
250 };
251 
252 struct RenderCommandNextSubpass {
253     SubpassContents subpassContents { SubpassContents::CORE_SUBPASS_CONTENTS_INLINE };
254     // index to other render command list if CORE_SUBPASS_CONTENTS_SECONDARY_COMMAND_LISTS
255     uint64_t renderCommandListIndex { 0 };
256 };
257 
258 struct RenderCommandEndRenderPass {
259     RenderPassEndType endType { RenderPassEndType::END_RENDER_PASS };
260     uint32_t subpassStartIndex { 0u };
261     uint32_t subpassCount { 0u };
262 };
263 
264 struct RenderCommandBlitImage {
265     RenderHandle srcHandle;
266     RenderHandle dstHandle;
267 
268     ImageBlit imageBlit;
269 
270     Filter filter { Filter::CORE_FILTER_NEAREST };
271 
272     // added already in render command list methods to correct layouts
273     ImageLayout srcImageLayout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED };
274     ImageLayout dstImageLayout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED };
275 };
276 
277 struct RenderCommandPushConstant {
278     RenderHandle psoHandle; // this is the previously BindPipeline() pso handle
279 
280     PushConstant pushConstant;
281     uint8_t* data { nullptr };
282 };
283 
284 struct ResourceBarrier {
285     AccessFlags accessFlags { 0 };
286     PipelineStageFlags pipelineStageFlags { 0 };
287     ImageLayout optionalImageLayout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED };
288     uint32_t optionalByteOffset { 0 };
289     uint32_t optionalByteSize { PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE };
290     ImageSubresourceRange optionalImageSubresourceRange {};
291 };
292 
293 struct CommandBarrier {
294     RenderHandle resourceHandle;
295 
296     ResourceBarrier src;
297     GpuQueue srcGpuQueue;
298 
299     ResourceBarrier dst;
300     GpuQueue dstGpuQueue;
301 };
302 
303 struct RenderCommandBarrierPoint {
304     RenderCommandType renderCommandType { RenderCommandType::UNDEFINED };
305 
306     uint32_t barrierPointIndex { ~0u };
307 
308     uint32_t customBarrierIndexBegin { ~0u };
309     uint32_t customBarrierCount { 0u };
310 
311     uint32_t vertexIndexBarrierIndexBegin { ~0u };
312     uint32_t vertexIndexBarrierCount { 0u };
313 
314     uint32_t indirectBufferBarrierIndexBegin { ~0u };
315     uint32_t indirectBufferBarrierCount { 0u };
316 
317     uint32_t descriptorSetHandleIndexBegin { ~0u };
318     uint32_t descriptorSetHandleCount { 0 };
319 };
320 
321 struct RenderCommandBindVertexBuffers {
322     uint32_t vertexBufferCount { 0 };
323     VertexBuffer vertexBuffers[PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT];
324 };
325 
326 struct RenderCommandBindIndexBuffer {
327     IndexBuffer indexBuffer;
328 };
329 
330 struct RenderCommandCopyBuffer {
331     RenderHandle srcHandle;
332     RenderHandle dstHandle;
333 
334     BufferCopy bufferCopy;
335 };
336 
337 struct RenderCommandCopyBufferImage {
338     enum class CopyType : uint32_t {
339         UNDEFINED = 0,
340         BUFFER_TO_IMAGE = 1,
341         IMAGE_TO_BUFFER = 2,
342     };
343 
344     CopyType copyType { CopyType::UNDEFINED };
345     RenderHandle srcHandle;
346     RenderHandle dstHandle;
347 
348     BufferImageCopy bufferImageCopy;
349 };
350 
351 struct RenderCommandCopyImage {
352     RenderHandle srcHandle;
353     RenderHandle dstHandle;
354 
355     ImageCopy imageCopy;
356 };
357 
358 struct RenderCommandBuildAccelerationStructure {
359     AccelerationStructureType type { AccelerationStructureType::CORE_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL };
360     BuildAccelerationStructureFlags flags { 0 };
361     BuildAccelerationStructureMode mode {
362         BuildAccelerationStructureMode::CORE_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD
363     };
364     RenderHandle srcAccelerationStructure;
365     RenderHandle dstAccelerationStructure;
366 
367     RenderHandle scratchBuffer;
368     uint32_t scratchOffset { 0u };
369 
370     AccelerationStructureGeometryTrianglesData* trianglesData { nullptr };
371     AccelerationStructureGeometryAabbsData* aabbsData { nullptr };
372     AccelerationStructureGeometryInstancesData* instancesData { nullptr };
373 
374     BASE_NS::array_view<AccelerationStructureGeometryTrianglesData> trianglesView;
375     BASE_NS::array_view<AccelerationStructureGeometryAabbsData> aabbsView;
376     BASE_NS::array_view<AccelerationStructureGeometryInstancesData> instancesView;
377 };
378 
379 struct RenderCommandClearColorImage {
380     RenderHandle handle;
381     ClearColorValue color;
382     // added already in render command list methods to correct layout
383     ImageLayout imageLayout { CORE_IMAGE_LAYOUT_UNDEFINED };
384 
385     BASE_NS::array_view<ImageSubresourceRange> ranges;
386 };
387 
388 // dynamic states
389 struct RenderCommandDynamicStateViewport {
390     ViewportDesc viewportDesc;
391 };
392 
393 struct RenderCommandDynamicStateScissor {
394     ScissorDesc scissorDesc;
395 };
396 
397 struct RenderCommandDynamicStateLineWidth {
398     float lineWidth { 1.0f };
399 };
400 
401 struct RenderCommandDynamicStateDepthBias {
402     float depthBiasConstantFactor { 0.0f };
403     float depthBiasClamp { 0.0f };
404     float depthBiasSlopeFactor { 0.0f };
405 };
406 
407 struct RenderCommandDynamicStateBlendConstants {
408     float blendConstants[4u] { 0.0f, 0.0f, 0.0f, 0.0f }; // rgba values used in blending
409 };
410 
411 struct RenderCommandDynamicStateDepthBounds {
412     float minDepthBounds { 0.0f };
413     float maxDepthBounds { 1.0f };
414 };
415 
416 enum class StencilDynamicState : uint32_t {
417     UNDEFINED = 0,
418     COMPARE_MASK = 1,
419     WRITE_MASK = 2,
420     REFERENCE = 3,
421 };
422 
423 struct RenderCommandDynamicStateStencil {
424     StencilDynamicState dynamicState { StencilDynamicState::UNDEFINED };
425     StencilFaceFlags faceMask { 0 };
426     uint32_t mask { 0 };
427 };
428 
429 struct RenderCommandDynamicStateFragmentShadingRate {
430     Size2D fragmentSize { 1u, 1u };
431     FragmentShadingRateCombinerOps combinerOps {};
432 };
433 
434 struct RenderCommandWriteTimestamp {
435     RenderHandle handle;
436     uint32_t queryIndex { 0 };
437     PipelineStageFlagBits pipelineStageFlagBits { PipelineStageFlagBits::CORE_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
438 };
439 
440 struct RenderCommandExecuteBackendFramePosition {
441     uint64_t id { 0 };
442 };
443 
444 struct RenderCommandWithType {
445     RenderCommandType type { RenderCommandType::UNDEFINED };
446     void* rc { nullptr };
447 };
448 
449 struct MultiRenderPassCommandListData {
450     uint32_t subpassCount { 1u };
451     uint32_t rpBeginCmdIndex { ~0u };
452     uint32_t rpEndCmdIndex { ~0u };
453     uint32_t rpBarrierCmdIndex { ~0u };
454     bool secondaryCmdLists { false };
455 };
456 
457 // RenderCommandList implementation
458 // NOTE: Many early optimizations cannot be done in the render command list
459 // (e.g. render pass and pipeline hashes are fully evaluated in the backend)
460 class RenderCommandList final : public IRenderCommandList {
461 public:
462     struct LinearAllocatorStruct {
463         BASE_NS::vector<BASE_NS::unique_ptr<LinearAllocator>> allocators;
464     };
465 
466     RenderCommandList(const BASE_NS::string_view nodeName, NodeContextDescriptorSetManager& nodeContextDescriptorSetMgr,
467         const GpuResourceManager& gpuResourceMgr, const NodeContextPsoManager& nodeContextPsoMgr, const GpuQueue& queue,
468         const bool enableMultiQueue);
469     ~RenderCommandList() = default;
470 
471     // called in render node graph if multi-queue gpu release acquire barriers have been patched
472     void SetValidGpuQueueReleaseAcquireBarriers();
473 
474     BASE_NS::array_view<const RenderCommandWithType> GetRenderCommands() const;
475     uint32_t GetRenderCommandCount() const;
476     bool HasValidRenderCommands() const;
477     GpuQueue GetGpuQueue() const;
478     bool HasMultiRenderCommandListSubpasses() const;
479     MultiRenderPassCommandListData GetMultiRenderCommandListData() const;
480 
481     BASE_NS::array_view<const CommandBarrier> GetCustomBarriers() const;
482     BASE_NS::array_view<const VertexBuffer> GetRenderpassVertexInputBufferBarriers() const;
483     BASE_NS::array_view<const VertexBuffer> GetRenderpassIndirectBufferBarriers() const;
484     // for barriers
485     BASE_NS::array_view<const RenderHandle> GetDescriptorSetHandles() const;
486     BASE_NS::array_view<const RenderHandle> GetUpdateDescriptorSetHandles() const;
487 
488     // reset buffers and data
489     void BeginFrame();
490 
491     // preparations if needed
492     void BeforeRenderNodeExecuteFrame();
493     // clean-up if needed
494     void AfterRenderNodeExecuteFrame();
495 
496     void Draw(const uint32_t vertexCount, const uint32_t instanceCount, const uint32_t firstVertex,
497         const uint32_t firstInstance) override;
498     void DrawIndexed(const uint32_t indexCount, const uint32_t instanceCount, const uint32_t firstIndex,
499         const int32_t vertexOffset, const uint32_t firstInstance) override;
500     void DrawIndirect(const RenderHandle bufferHandle, const uint32_t offset, const uint32_t drawCount,
501         const uint32_t stride) override;
502     void DrawIndexedIndirect(const RenderHandle bufferHandle, const uint32_t offset, const uint32_t drawCount,
503         const uint32_t stride) override;
504 
505     void Dispatch(const uint32_t groupCountX, const uint32_t groupCountY, const uint32_t groupCountZ) override;
506     void DispatchIndirect(const RenderHandle bufferHandle, const uint32_t offset) override;
507 
508     void BindPipeline(const RenderHandle psoHandle) override;
509 
510     void PushConstantData(
511         const struct RENDER_NS::PushConstant& pushConstant, const BASE_NS::array_view<const uint8_t> data) override;
512     void PushConstant(const struct RENDER_NS::PushConstant& pushConstant, const uint8_t* data) override;
513 
514     void BindVertexBuffers(const BASE_NS::array_view<const VertexBuffer> vertexBuffers) override;
515     void BindIndexBuffer(const IndexBuffer& indexBuffer) override;
516 
517     void BeginRenderPass(const RenderPassDesc& renderPassDesc,
518         const BASE_NS::array_view<const RenderPassSubpassDesc> subpassDescs) override;
519     void BeginRenderPass(const RenderPassDesc& renderPassDesc, const uint32_t subpassStartIdx,
520         const RenderPassSubpassDesc& subpassDescs) override;
521     void EndRenderPass() override;
522 
523     void NextSubpass(const SubpassContents& subpassContents) override;
524 
525     void BeginDisableAutomaticBarrierPoints() override;
526     void EndDisableAutomaticBarrierPoints() override;
527     void AddCustomBarrierPoint() override;
528 
529     void CustomMemoryBarrier(const GeneralBarrier& source, const GeneralBarrier& destination) override;
530     void CustomBufferBarrier(const RenderHandle handle, const BufferResourceBarrier& source,
531         const BufferResourceBarrier& destination, const uint32_t byteOffset, const uint32_t byteSize) override;
532     void CustomImageBarrier(const RenderHandle handle, const ImageResourceBarrier& destination,
533         const ImageSubresourceRange& imageSubresourceRange) override;
534     void CustomImageBarrier(const RenderHandle handle, const ImageResourceBarrier& source,
535         const ImageResourceBarrier& destination, const ImageSubresourceRange& imageSubresourceRange) override;
536 
537     void CopyBufferToBuffer(
538         const RenderHandle sourceHandle, const RenderHandle destinationHandle, const BufferCopy& bufferCopy) override;
539     void CopyBufferToImage(const RenderHandle sourceHandle, const RenderHandle destinationHandle,
540         const BufferImageCopy& bufferImageCopy) override;
541     void CopyImageToBuffer(const RenderHandle sourceHandle, const RenderHandle destinationHandle,
542         const BufferImageCopy& bufferImageCopy) override;
543     void CopyImageToImage(
544         const RenderHandle sourceHandle, const RenderHandle destinationHandle, const ImageCopy& imageCopy) override;
545 
546     void BlitImage(const RenderHandle sourceImageHandle, const RenderHandle destinationImageHandle,
547         const ImageBlit& imageBlit, const Filter filter) override;
548 
549     void UpdateDescriptorSet(
550         const RenderHandle handle, const DescriptorSetLayoutBindingResources& bindingResources) override;
551     void UpdateDescriptorSets(const BASE_NS::array_view<const RenderHandle> handles,
552         const BASE_NS::array_view<const DescriptorSetLayoutBindingResources> bindingResources) override;
553     void BindDescriptorSet(const uint32_t set, const RenderHandle handle) override;
554     void BindDescriptorSet(const uint32_t set, const RenderHandle handle,
555         const BASE_NS::array_view<const uint32_t> dynamicOffsets) override;
556     void BindDescriptorSets(const uint32_t firstSet, const BASE_NS::array_view<const RenderHandle> handles) override;
557     void BindDescriptorSet(const uint32_t set, const BindDescriptorSetData& desriptorSetData) override;
558     void BindDescriptorSets(
559         const uint32_t firstSet, const BASE_NS::array_view<const BindDescriptorSetData> descriptorSetData) override;
560 
561     void BuildAccelerationStructures(const AccelerationStructureBuildGeometryData& geometry,
562         const BASE_NS::array_view<const AccelerationStructureGeometryTrianglesData> triangles,
563         const BASE_NS::array_view<const AccelerationStructureGeometryAabbsData> aabbs,
564         const BASE_NS::array_view<const AccelerationStructureGeometryInstancesData> instances) override;
565 
566     void ClearColorImage(const RenderHandle handle, const ClearColorValue color,
567         const BASE_NS::array_view<const ImageSubresourceRange> ranges) override;
568 
569     // dynamic states
570     void SetDynamicStateViewport(const ViewportDesc& viewportDesc) override;
571     void SetDynamicStateScissor(const ScissorDesc& scissorDesc) override;
572     void SetDynamicStateLineWidth(const float lineWidth) override;
573     void SetDynamicStateDepthBias(
574         const float depthBiasConstantFactor, const float depthBiasClamp, const float depthBiasSlopeFactor) override;
575     void SetDynamicStateBlendConstants(const BASE_NS::array_view<const float> blendConstants) override;
576     void SetDynamicStateDepthBounds(const float minDepthBounds, const float maxDepthBounds) override;
577     void SetDynamicStateStencilCompareMask(const StencilFaceFlags faceMask, const uint32_t compareMask) override;
578     void SetDynamicStateStencilWriteMask(const StencilFaceFlags faceMask, const uint32_t writeMask) override;
579     void SetDynamicStateStencilReference(const StencilFaceFlags faceMask, const uint32_t reference) override;
580     void SetDynamicStateFragmentShadingRate(
581         const Size2D& fragmentSize, const FragmentShadingRateCombinerOps& combinerOps) override;
582 
583     void SetExecuteBackendFramePosition() override;
584 
585     // IInterface
586     const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
587     CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override;
588     void Ref() override;
589     void Unref() override;
590 
591 private:
592     const BASE_NS::string nodeName_;
593 #if (RENDER_VALIDATION_ENABLED == 1)
594     // used for validation
595     const GpuResourceManager& gpuResourceMgr_;
596     const NodeContextPsoManager& psoMgr_;
597 #endif
598     NodeContextDescriptorSetManager& nodeContextDescriptorSetManager_;
599 
600     // add barrier/synchronization point where descriptor resources need to be synchronized
601     // on gfx this happens before BeginRenderPass()
602     // on compute this happens before Dispatch -methods
603     void AddBarrierPoint(const RenderCommandType renderCommandType);
604 
605     bool ProcessInputAttachments(const RenderPassDesc& renderPassDsc, const RenderPassSubpassDesc& subpassRef,
606         RenderPassAttachmentResourceStates& subpassResourceStates);
607     bool ProcessColorAttachments(const RenderPassDesc& renderPassDsc, const RenderPassSubpassDesc& subpassRef,
608         RenderPassAttachmentResourceStates& subpassResourceStates);
609     bool ProcessResolveAttachments(const RenderPassDesc& renderPassDsc, const RenderPassSubpassDesc& subpassRef,
610         RenderPassAttachmentResourceStates& subpassResourceStates);
611     bool ProcessDepthAttachments(const RenderPassDesc& renderPassDsc, const RenderPassSubpassDesc& subpassRef,
612         RenderPassAttachmentResourceStates& subpassResourceStates);
613     bool ProcessFragmentShadingRateAttachments(const RenderPassDesc& renderPassDsc,
614         const RenderPassSubpassDesc& subpassRef, RenderPassAttachmentResourceStates& subpassResourceStates);
615 
616     void ValidateRenderPass(const RenderPassDesc& renderPassDesc);
617     void ValidatePipeline();
618     void ValidatePipelineLayout();
619 
620     struct DescriptorSetBind {
621         RenderHandle descriptorSetHandle;
622         bool hasDynamicBarrierResources { false };
623     };
624     struct CustomBarrierIndices {
625         int32_t prevSize { 0 };
626         bool dirtyCustomBarriers { false };
627     };
628 
629     // state data is mostly for validation
630     struct StateData {
631         bool validCommandList { true };
632         bool validPso { false };
633         bool renderPassHasBegun { false };
634         bool automaticBarriersEnabled { true };
635         bool executeBackendFrameSet { false };
636 
637         bool dirtyDescriptorSetsForBarriers { false };
638 
639         uint32_t renderPassStartIndex { 0u };
640         uint32_t renderPassSubpassCount { 0u };
641 
642         uint32_t currentBarrierPointIndex { 0u };
643 
644         // handle for validation
645         RenderHandle currentPsoHandle;
646         bool checkBindPipelineLayout { false };
647         PipelineBindPoint currentPsoBindPoint { PipelineBindPoint::CORE_PIPELINE_BIND_POINT_GRAPHICS };
648 
649         uint32_t currentBoundSetsMask { 0u }; // bitmask for all descriptor sets
650         DescriptorSetBind currentBoundSets[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
651         CustomBarrierIndices currentCustomBarrierIndices;
652 
653         RenderCommandBarrierPoint* currentBarrierPoint { nullptr };
654     };
655     StateData stateData_;
656 
ResetStateData()657     void ResetStateData()
658     {
659         stateData_ = {};
660     }
661 
662     GpuQueue gpuQueue_;
663     // if device has enabled multiple queues this is true
664     bool enableMultiQueue_ { false };
665     // true if valid multi-queue gpu resource transfers are created in render node graph
666     bool validReleaseAcquire_ { false };
667 
668     // true if render pass has been begun with subpasscount > 1 and not all subpasses given
669     bool hasMultiRpCommandListSubpasses_ { false };
670     MultiRenderPassCommandListData multiRpCommandListData_ {};
671 
672     BASE_NS::vector<RenderCommandWithType> renderCommands_;
673 
674     // store all custom barriers to this list and provide indices in "barrier point"
675     // barriers are batched in this point and command is commit to the real GPU command buffer
676     BASE_NS::vector<CommandBarrier> customBarriers_;
677 
678     // store all vertex and index buffer barriers to this list and provide indices in "barrier point"
679     // barriers are batched in this point and command is commit to the real GPU command buffer
680     // obviously barriers are only needed in begin render pass barrier point
681     BASE_NS::vector<VertexBuffer> rpVertexInputBufferBarriers_;
682 
683     // store all renderpass draw indirect barriers to this list and provide indices in "barrier point"
684     // barriers are batched in this point and command is commit to the real GPU command buffer
685     // obviously barriers are only needed in begin render pass barrier point
686     BASE_NS::vector<VertexBuffer> rpIndirectBufferBarriers_;
687 
688     // store all descriptor set handles to this list and provide indices in "barrier point"
689     // barriers are batched in this point and command is commit to the real GPU command buffer
690     BASE_NS::vector<RenderHandle> descriptorSetHandlesForBarriers_;
691 
692     // store all descriptor set handles which are updated to this list
693     BASE_NS::vector<RenderHandle> descriptorSetHandlesForUpdates_;
694 
695     // linear allocator for render command list commands
696     LinearAllocatorStruct allocator_;
697 };
698 RENDER_END_NAMESPACE()
699 
700 #endif // CORE_RENDER_RENDER_COMMAND_LIST_H
701