1 /* 2 * Copyright (C) 2023 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 RENDER_GRAPH_H 17 #define RENDER_GRAPH_H 18 19 #include <cstdint> 20 21 #include <base/containers/unordered_map.h> 22 #include <base/containers/vector.h> 23 #include <render/device/pipeline_state_desc.h> 24 #include <render/namespace.h> 25 #include <render/resource_handle.h> 26 27 #include "device/gpu_resource_handle_util.h" 28 #include "nodecontext/render_command_list.h" 29 30 RENDER_BEGIN_NAMESPACE() 31 class Device; 32 class GpuResourceManager; 33 class RenderBarrierList; 34 35 struct RenderNodeGraphNodeStore; 36 struct RenderNodeContextData; 37 38 /** 39 RenderGraph. 40 Creates dependencies between resources (used in render nodes) and queues. 41 Automatically creates transitions and barriers to command lists. 42 */ 43 class RenderGraph final { 44 public: 45 explicit RenderGraph(GpuResourceManager& gpuResourceMgr); 46 ~RenderGraph() = default; 47 48 RenderGraph(const RenderGraph&) = delete; 49 RenderGraph operator=(const RenderGraph&) = delete; 50 51 void BeginFrame(); 52 53 /** Process all render nodes and patch needed barriers. 54 * backbufferHandle Backbuffer handle for automatic backbuffer/swapchain dependency. 55 * renderNodeGraphNodeStore All render node graph render nodes. 56 */ 57 void ProcessRenderNodeGraph(const RenderHandle backBufferHandle, 58 const BASE_NS::array_view<RenderNodeGraphNodeStore*> renderNodeGraphNodeStores); 59 60 struct RenderGraphBufferState { 61 GpuResourceState state; 62 BindableBuffer resource; 63 RenderCommandWithType prevRc; 64 uint32_t prevRenderNodeIndex { ~0u }; 65 }; 66 struct RenderGraphImageState { 67 GpuResourceState state; 68 BindableImage resource; 69 RenderCommandWithType prevRc; 70 uint32_t prevRenderNodeIndex { ~0u }; 71 }; 72 struct MultiRenderPassStore { 73 BASE_NS::vector<RenderCommandBeginRenderPass*> renderPasses; 74 75 // batch barriers to the first render pass 76 RenderBarrierList* firstRenderPassBarrierList { nullptr }; 77 uint32_t firstBarrierPointIndex { ~0u }; 78 bool supportOpen { false }; 79 }; 80 81 struct GpuQueueTransferState { 82 RenderHandle handle; 83 uint32_t releaseNodeIdx { 0 }; 84 uint32_t acquireNodeIdx { 0 }; 85 86 ImageLayout optionalReleaseImageLayout { CORE_IMAGE_LAYOUT_UNDEFINED }; 87 ImageLayout optionalAcquireImageLayout { CORE_IMAGE_LAYOUT_UNDEFINED }; 88 }; 89 90 struct BackbufferState { 91 // state after render node graph processing 92 GpuResourceState state; 93 // layout after render node graph processing 94 ImageLayout layout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED }; 95 }; 96 97 /** Get backbuffer resource state after render node graph for further processing. 98 * There might different configurations, or state where backbuffer has not been touched, but we want to present. 99 */ 100 BackbufferState GetBackbufferResourceState() const; 101 102 private: 103 struct StateCache { 104 MultiRenderPassStore multiRenderPassStore; 105 RenderHandle backbufferHandle; 106 bool checkForBackbufferDependency { false }; 107 uint32_t firstBackBufferUseNodeIdx { ~0u }; 108 } stateCache_; 109 110 struct BeginRenderPassParameters { 111 RenderCommandBeginRenderPass& rc; 112 StateCache& stateCache; 113 RenderCommandWithType rpForCmdRef; 114 }; 115 void ProcessRenderNodeGraphNodeStores( 116 const BASE_NS::array_view<RenderNodeGraphNodeStore*>& renderNodeGraphNodeStores, StateCache& stateCache); 117 void ProcessRenderNodeCommands(BASE_NS::array_view<const RenderCommandWithType>& cmdListRef, 118 const uint32_t& nodeIdx, RenderNodeContextData& ref, StateCache& stateCache); 119 void StoreFinalBufferState(const StateCache& stateCache); 120 // handles backbuffer layouts as well 121 void StoreFinalImageState(StateCache& stateCache); 122 123 void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 124 RenderNodeContextData& nodeData, RenderCommandBeginRenderPass& rc, StateCache& stateCache); 125 void BeginRenderPassHandleDependency( 126 BeginRenderPassParameters& params, const uint32_t commandListCommandIndex, RenderNodeContextData& nodeData); 127 void BeginRenderPassUpdateImageStates(BeginRenderPassParameters& params, const GpuQueue& gpuQueue, 128 BASE_NS::array_view<ImageLayout>& finalImageLayouts, const uint32_t renderNodeIndex); 129 void BeginRenderPassUpdateSubpassImageStates(BASE_NS::array_view<const uint32_t> attatchmentIndices, 130 const RenderPassDesc& renderPassDesc, const RenderPassAttachmentResourceStates& subpassResourceStatesRef, 131 BASE_NS::array_view<ImageLayout> finalImageLayouts, StateCache& stateCache); 132 133 void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 134 const RenderNodeContextData& nodeData, RenderCommandEndRenderPass& rc, StateCache& stateCache); 135 void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 136 RenderNodeContextData& nodeData, RenderCommandBarrierPoint& rc, StateCache& stateCache); 137 138 struct ParameterCacheAllocOpt { 139 BASE_NS::vector<CommandBarrier> combinedBarriers; 140 BASE_NS::unordered_map<RenderHandle, uint32_t> handledCustomBarriers; 141 }; 142 ParameterCacheAllocOpt parameterCachePools_; 143 struct ParameterCache { 144 BASE_NS::vector<CommandBarrier>& combinedBarriers; 145 BASE_NS::unordered_map<RenderHandle, uint32_t>& handledCustomBarriers; 146 const uint32_t customBarrierCount; 147 const uint32_t vertexInputBarrierCount; 148 const uint32_t renderNodeIndex; 149 const GpuQueue gpuQueue; 150 const RenderCommandWithType rcWithType; 151 StateCache& stateCache; 152 }; 153 static void UpdateBufferResourceState( 154 RenderGraphBufferState& stateRef, const ParameterCache& params, const CommandBarrier& cb); 155 static void UpdateImageResourceState( 156 RenderGraphImageState& stateRef, const ParameterCache& params, const CommandBarrier& cb); 157 158 void HandleCustomBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 159 const BASE_NS::array_view<const CommandBarrier>& customBarrierListRef); 160 void HandleVertexInputBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 161 const BASE_NS::array_view<const VertexBuffer>& vertexInputBufferBarrierListRef); 162 163 void HandleBlitImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 164 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 165 166 void HandleCopyBuffer(ParameterCache& params, const uint32_t& commandListCommandIndex, 167 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 168 169 void HandleCopyBufferImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 170 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 171 172 void HandleDescriptorSets(ParameterCache& params, 173 const BASE_NS::array_view<const RenderHandle>& descriptorSetHandlesForBarriers, 174 const NodeContextDescriptorSetManager& nodeDescriptorSetMgrRef); 175 176 void UpdateStateAndCreateBarriersGpuImage( 177 const GpuResourceState& resourceState, const BindableImage& res, RenderGraph::ParameterCache& params); 178 179 void UpdateStateAndCreateBarriersGpuBuffer( 180 const GpuResourceState& resourceState, const BindableBuffer& res, RenderGraph::ParameterCache& params); 181 182 void AddCommandBarrierAndUpdateStateCache(const uint32_t renderNodeIndex, 183 const GpuResourceState& newGpuResourceState, const RenderCommandWithType& rcWithType, 184 BASE_NS::vector<CommandBarrier>& barriers, BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 185 186 void AddCommandBarrierAndUpdateStateCacheBuffer(const uint32_t renderNodeIndex, 187 const GpuResourceState& newGpuResourceState, const BindableBuffer& newBuffer, 188 const RenderCommandWithType& rcWithType, BASE_NS::vector<CommandBarrier>& barriers, 189 BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 190 191 void AddCommandBarrierAndUpdateStateCacheImage(const uint32_t renderNodeIndex, 192 const GpuResourceState& newGpuResourceState, const BindableImage& newImage, 193 const RenderCommandWithType& rcWithType, BASE_NS::vector<CommandBarrier>& barriers, 194 BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 195 196 // if there's no state ATM, a undefined/invalid starting state is created 197 // do not call this method with non dynamic trackable resources 198 RenderGraphBufferState& GetBufferResourceStateRef(const RenderHandle handle, const GpuQueue& queue); 199 RenderGraphImageState& GetImageResourceStateRef(const RenderHandle handle, const GpuQueue& queue); 200 201 GpuResourceManager& gpuResourceMgr_; 202 203 // stored every time at the end of the frame 204 BackbufferState gpuImageBackbufferState_; 205 206 // helper to access current render node transfers 207 BASE_NS::vector<GpuQueueTransferState> currNodeGpuResourceTransfers_; 208 209 // ~0u is invalid index, i.e. no state tracking 210 BASE_NS::vector<uint32_t> gpuBufferDataIndices_; 211 // ~0u is invalid index, i.e. no state tracking 212 BASE_NS::vector<uint32_t> gpuImageDataIndices_; 213 214 // resources that are tracked 215 BASE_NS::vector<RenderGraphBufferState> gpuBufferTracking_; 216 BASE_NS::vector<RenderGraphImageState> gpuImageTracking_; 217 218 // available positions from gpuXXXTracking_ 219 BASE_NS::vector<uint32_t> gpuBufferAvailableIndices_; 220 BASE_NS::vector<uint32_t> gpuImageAvailableIndices_; 221 222 RenderGraphBufferState defaultBufferState_ {}; 223 RenderGraphImageState defaultImageState_ {}; 224 }; 225 RENDER_END_NAMESPACE() 226 227 #endif // RENDER_GRAPH_H 228