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