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 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 bool checkBackbufferDependancy, 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 static constexpr uint32_t MAX_MIP_STATE_COUNT { 16u }; 67 struct RenderGraphAdditionalImageState { 68 BASE_NS::unique_ptr<ImageLayout[]> layouts; 69 // NOTE: layers not handled yet 70 }; 71 struct RenderGraphImageState { 72 GpuResourceState state; 73 BindableImage resource; 74 RenderCommandWithType prevRc; 75 uint32_t prevRenderNodeIndex { ~0u }; 76 RenderGraphAdditionalImageState additionalState; 77 }; 78 struct MultiRenderPassStore { 79 BASE_NS::vector<RenderCommandBeginRenderPass*> renderPasses; 80 81 // batch barriers to the first render pass 82 RenderBarrierList* firstRenderPassBarrierList { nullptr }; 83 uint32_t firstBarrierPointIndex { ~0u }; 84 bool supportOpen { false }; 85 }; 86 87 struct GpuQueueTransferState { 88 RenderHandle handle; 89 uint32_t releaseNodeIdx { 0 }; 90 uint32_t acquireNodeIdx { 0 }; 91 92 ImageLayout optionalReleaseImageLayout { CORE_IMAGE_LAYOUT_UNDEFINED }; 93 ImageLayout optionalAcquireImageLayout { CORE_IMAGE_LAYOUT_UNDEFINED }; 94 }; 95 96 struct SwapchainStates { 97 struct SwapchainState { 98 RenderHandle handle; 99 // state after render node graph processing 100 GpuResourceState state; 101 // layout after render node graph processing 102 ImageLayout layout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED }; 103 }; 104 BASE_NS::vector<SwapchainState> swapchains; 105 }; 106 107 /** Get backbuffer resource state after render node graph for further processing. 108 * There might different configurations, or state where backbuffer has not been touched, but we want to present. 109 */ 110 SwapchainStates GetSwapchainResourceStates() const; 111 112 private: 113 struct StateCache { 114 MultiRenderPassStore multiRenderPassStore; 115 116 uint32_t nodeCounter { 0u }; 117 118 bool checkForBackbufferDependency { false }; 119 bool usesSwapchainImage { false }; 120 }; 121 StateCache stateCache_; 122 123 struct BeginRenderPassParameters { 124 RenderCommandBeginRenderPass& rc; 125 StateCache& stateCache; 126 RenderCommandWithType rpForCmdRef; 127 }; 128 void ProcessRenderNodeGraphNodeStores( 129 const BASE_NS::array_view<RenderNodeGraphNodeStore*>& renderNodeGraphNodeStores, StateCache& stateCache); 130 void ProcessRenderNodeCommands(BASE_NS::array_view<const RenderCommandWithType>& cmdListRef, 131 const uint32_t& nodeIdx, RenderNodeContextData& ref, StateCache& stateCache); 132 void StoreFinalBufferState(); 133 // handles backbuffer layouts as well 134 void StoreFinalImageState(); 135 136 void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 137 RenderNodeContextData& nodeData, RenderCommandBeginRenderPass& rc, StateCache& stateCache); 138 void BeginRenderPassHandleDependency( 139 BeginRenderPassParameters& params, const uint32_t commandListCommandIndex, RenderNodeContextData& nodeData); 140 void BeginRenderPassUpdateImageStates(BeginRenderPassParameters& params, const GpuQueue& gpuQueue, 141 BASE_NS::array_view<ImageLayout>& finalImageLayouts, const uint32_t renderNodeIndex); 142 void BeginRenderPassUpdateSubpassImageStates(BASE_NS::array_view<const uint32_t> attatchmentIndices, 143 const RenderPassDesc& renderPassDesc, const RenderPassAttachmentResourceStates& subpassResourceStatesRef, 144 BASE_NS::array_view<ImageLayout> finalImageLayouts, StateCache& stateCache); 145 146 void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 147 const RenderNodeContextData& nodeData, RenderCommandEndRenderPass& rc, StateCache& stateCache); 148 void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 149 RenderNodeContextData& nodeData, RenderCommandBarrierPoint& rc, StateCache& stateCache); 150 151 struct ParameterCacheAllocOpt { 152 BASE_NS::vector<CommandBarrier> combinedBarriers; 153 BASE_NS::unordered_map<RenderHandle, uint32_t> handledCustomBarriers; 154 }; 155 ParameterCacheAllocOpt parameterCachePools_; 156 struct ParameterCache { 157 BASE_NS::vector<CommandBarrier>& combinedBarriers; 158 BASE_NS::unordered_map<RenderHandle, uint32_t>& handledCustomBarriers; 159 const uint32_t customBarrierCount; 160 const uint32_t vertexInputBarrierCount; 161 const uint32_t indirectBufferBarrierCount; 162 const uint32_t renderNodeIndex; 163 const GpuQueue gpuQueue; 164 const RenderCommandWithType rcWithType; 165 StateCache& stateCache; 166 }; 167 static void UpdateBufferResourceState( 168 RenderGraphBufferState& stateRef, const ParameterCache& params, const CommandBarrier& cb); 169 static void UpdateImageResourceState( 170 RenderGraphImageState& stateRef, const ParameterCache& params, const CommandBarrier& cb); 171 172 void HandleCustomBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 173 const BASE_NS::array_view<const CommandBarrier>& customBarrierListRef); 174 void HandleVertexInputBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 175 const BASE_NS::array_view<const VertexBuffer>& vertexInputBufferBarrierListRef); 176 void HandleRenderpassIndirectBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 177 const BASE_NS::array_view<const VertexBuffer>& indirectBufferBarrierListRef); 178 179 void HandleClearImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 180 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 181 void HandleBlitImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 182 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 183 void HandleCopyBuffer(ParameterCache& params, const uint32_t& commandListCommandIndex, 184 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 185 void HandleCopyBufferImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 186 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 187 void HandleDispatchIndirect(ParameterCache& params, const uint32_t& commandListCommandIndex, 188 const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 189 190 void HandleDescriptorSets(ParameterCache& params, 191 const BASE_NS::array_view<const RenderHandle>& descriptorSetHandlesForBarriers, 192 const NodeContextDescriptorSetManager& nodeDescriptorSetMgrRef); 193 194 void UpdateStateAndCreateBarriersGpuImage( 195 const GpuResourceState& resourceState, const BindableImage& res, RenderGraph::ParameterCache& params); 196 197 void UpdateStateAndCreateBarriersGpuBuffer( 198 const GpuResourceState& resourceState, const BindableBuffer& res, RenderGraph::ParameterCache& params); 199 200 void AddCommandBarrierAndUpdateStateCache(const uint32_t renderNodeIndex, 201 const GpuResourceState& newGpuResourceState, const RenderCommandWithType& rcWithType, 202 BASE_NS::vector<CommandBarrier>& barriers, BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 203 204 void AddCommandBarrierAndUpdateStateCacheBuffer(const uint32_t renderNodeIndex, 205 const GpuResourceState& newGpuResourceState, const BindableBuffer& newBuffer, 206 const RenderCommandWithType& rcWithType, BASE_NS::vector<CommandBarrier>& barriers, 207 BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 208 209 void AddCommandBarrierAndUpdateStateCacheImage(const uint32_t renderNodeIndex, 210 const GpuResourceState& newGpuResourceState, const BindableImage& newImage, 211 const RenderCommandWithType& rcWithType, BASE_NS::vector<CommandBarrier>& barriers, 212 BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 213 214 // if there's no state ATM, a undefined/invalid starting state is created 215 // do not call this method with non dynamic trackable resources 216 RenderGraphBufferState& GetBufferResourceStateRef(const RenderHandle handle, const GpuQueue& queue); 217 RenderGraphImageState& GetImageResourceStateRef(const RenderHandle handle, const GpuQueue& queue); 218 219 GpuResourceManager& gpuResourceMgr_; 220 221 // stored every time at the end of the frame 222 SwapchainStates swapchainStates_; 223 224 // helper to access current render node transfers 225 BASE_NS::vector<GpuQueueTransferState> currNodeGpuResourceTransfers_; 226 227 // ~0u is invalid index, i.e. no state tracking 228 BASE_NS::vector<uint32_t> gpuBufferDataIndices_; 229 // ~0u is invalid index, i.e. no state tracking 230 BASE_NS::vector<uint32_t> gpuImageDataIndices_; 231 232 // resources that are tracked 233 BASE_NS::vector<RenderGraphBufferState> gpuBufferTracking_; 234 BASE_NS::vector<RenderGraphImageState> gpuImageTracking_; 235 236 // available positions from gpuXXXTracking_ 237 BASE_NS::vector<uint32_t> gpuBufferAvailableIndices_; 238 BASE_NS::vector<uint32_t> gpuImageAvailableIndices_; 239 240 RenderGraphBufferState defaultBufferState_ {}; 241 RenderGraphImageState defaultImageState_ {}; 242 }; 243 RENDER_END_NAMESPACE() 244 245 #endif // RENDER_GRAPH_H 246