18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef RENDER_GRAPH_H 178bf80f4bSopenharmony_ci#define RENDER_GRAPH_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cstdint> 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_ci#include <base/containers/unordered_map.h> 228bf80f4bSopenharmony_ci#include <base/containers/vector.h> 238bf80f4bSopenharmony_ci#include <render/device/pipeline_state_desc.h> 248bf80f4bSopenharmony_ci#include <render/namespace.h> 258bf80f4bSopenharmony_ci#include <render/resource_handle.h> 268bf80f4bSopenharmony_ci 278bf80f4bSopenharmony_ci#include "device/gpu_resource_handle_util.h" 288bf80f4bSopenharmony_ci#include "nodecontext/render_command_list.h" 298bf80f4bSopenharmony_ci 308bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 318bf80f4bSopenharmony_ciclass Device; 328bf80f4bSopenharmony_ciclass GpuResourceManager; 338bf80f4bSopenharmony_ciclass RenderBarrierList; 348bf80f4bSopenharmony_ci 358bf80f4bSopenharmony_cistruct RenderNodeGraphNodeStore; 368bf80f4bSopenharmony_cistruct RenderNodeContextData; 378bf80f4bSopenharmony_ci 388bf80f4bSopenharmony_ci/** 398bf80f4bSopenharmony_ciRenderGraph. 408bf80f4bSopenharmony_ciCreates dependencies between resources (used in render nodes) and queues. 418bf80f4bSopenharmony_ciAutomatically creates transitions and barriers to command lists. 428bf80f4bSopenharmony_ci*/ 438bf80f4bSopenharmony_ciclass RenderGraph final { 448bf80f4bSopenharmony_cipublic: 458bf80f4bSopenharmony_ci explicit RenderGraph(GpuResourceManager& gpuResourceMgr); 468bf80f4bSopenharmony_ci ~RenderGraph() = default; 478bf80f4bSopenharmony_ci 488bf80f4bSopenharmony_ci RenderGraph(const RenderGraph&) = delete; 498bf80f4bSopenharmony_ci RenderGraph operator=(const RenderGraph&) = delete; 508bf80f4bSopenharmony_ci 518bf80f4bSopenharmony_ci void BeginFrame(); 528bf80f4bSopenharmony_ci 538bf80f4bSopenharmony_ci /** Process all render nodes and patch needed barriers. 548bf80f4bSopenharmony_ci * backbufferHandle Backbuffer handle for automatic backbuffer/swapchain dependency. 558bf80f4bSopenharmony_ci * renderNodeGraphNodeStore All render node graph render nodes. 568bf80f4bSopenharmony_ci */ 578bf80f4bSopenharmony_ci void ProcessRenderNodeGraph(const bool checkBackbufferDependancy, 588bf80f4bSopenharmony_ci const BASE_NS::array_view<RenderNodeGraphNodeStore*> renderNodeGraphNodeStores); 598bf80f4bSopenharmony_ci 608bf80f4bSopenharmony_ci struct RenderGraphBufferState { 618bf80f4bSopenharmony_ci GpuResourceState state; 628bf80f4bSopenharmony_ci BindableBuffer resource; 638bf80f4bSopenharmony_ci RenderCommandWithType prevRc; 648bf80f4bSopenharmony_ci uint32_t prevRenderNodeIndex { ~0u }; 658bf80f4bSopenharmony_ci }; 668bf80f4bSopenharmony_ci static constexpr uint32_t MAX_MIP_STATE_COUNT { 16u }; 678bf80f4bSopenharmony_ci struct RenderGraphAdditionalImageState { 688bf80f4bSopenharmony_ci BASE_NS::unique_ptr<ImageLayout[]> layouts; 698bf80f4bSopenharmony_ci // NOTE: layers not handled yet 708bf80f4bSopenharmony_ci }; 718bf80f4bSopenharmony_ci struct RenderGraphImageState { 728bf80f4bSopenharmony_ci GpuResourceState state; 738bf80f4bSopenharmony_ci BindableImage resource; 748bf80f4bSopenharmony_ci RenderCommandWithType prevRc; 758bf80f4bSopenharmony_ci uint32_t prevRenderNodeIndex { ~0u }; 768bf80f4bSopenharmony_ci RenderGraphAdditionalImageState additionalState; 778bf80f4bSopenharmony_ci }; 788bf80f4bSopenharmony_ci struct MultiRenderPassStore { 798bf80f4bSopenharmony_ci BASE_NS::vector<RenderCommandBeginRenderPass*> renderPasses; 808bf80f4bSopenharmony_ci 818bf80f4bSopenharmony_ci // batch barriers to the first render pass 828bf80f4bSopenharmony_ci RenderBarrierList* firstRenderPassBarrierList { nullptr }; 838bf80f4bSopenharmony_ci uint32_t firstBarrierPointIndex { ~0u }; 848bf80f4bSopenharmony_ci bool supportOpen { false }; 858bf80f4bSopenharmony_ci }; 868bf80f4bSopenharmony_ci 878bf80f4bSopenharmony_ci struct GpuQueueTransferState { 888bf80f4bSopenharmony_ci RenderHandle handle; 898bf80f4bSopenharmony_ci uint32_t releaseNodeIdx { 0 }; 908bf80f4bSopenharmony_ci uint32_t acquireNodeIdx { 0 }; 918bf80f4bSopenharmony_ci 928bf80f4bSopenharmony_ci ImageLayout optionalReleaseImageLayout { CORE_IMAGE_LAYOUT_UNDEFINED }; 938bf80f4bSopenharmony_ci ImageLayout optionalAcquireImageLayout { CORE_IMAGE_LAYOUT_UNDEFINED }; 948bf80f4bSopenharmony_ci }; 958bf80f4bSopenharmony_ci 968bf80f4bSopenharmony_ci struct SwapchainStates { 978bf80f4bSopenharmony_ci struct SwapchainState { 988bf80f4bSopenharmony_ci RenderHandle handle; 998bf80f4bSopenharmony_ci // state after render node graph processing 1008bf80f4bSopenharmony_ci GpuResourceState state; 1018bf80f4bSopenharmony_ci // layout after render node graph processing 1028bf80f4bSopenharmony_ci ImageLayout layout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED }; 1038bf80f4bSopenharmony_ci }; 1048bf80f4bSopenharmony_ci BASE_NS::vector<SwapchainState> swapchains; 1058bf80f4bSopenharmony_ci }; 1068bf80f4bSopenharmony_ci 1078bf80f4bSopenharmony_ci /** Get backbuffer resource state after render node graph for further processing. 1088bf80f4bSopenharmony_ci * There might different configurations, or state where backbuffer has not been touched, but we want to present. 1098bf80f4bSopenharmony_ci */ 1108bf80f4bSopenharmony_ci SwapchainStates GetSwapchainResourceStates() const; 1118bf80f4bSopenharmony_ci 1128bf80f4bSopenharmony_ciprivate: 1138bf80f4bSopenharmony_ci struct StateCache { 1148bf80f4bSopenharmony_ci MultiRenderPassStore multiRenderPassStore; 1158bf80f4bSopenharmony_ci 1168bf80f4bSopenharmony_ci uint32_t nodeCounter { 0u }; 1178bf80f4bSopenharmony_ci 1188bf80f4bSopenharmony_ci bool checkForBackbufferDependency { false }; 1198bf80f4bSopenharmony_ci bool usesSwapchainImage { false }; 1208bf80f4bSopenharmony_ci }; 1218bf80f4bSopenharmony_ci StateCache stateCache_; 1228bf80f4bSopenharmony_ci 1238bf80f4bSopenharmony_ci struct BeginRenderPassParameters { 1248bf80f4bSopenharmony_ci RenderCommandBeginRenderPass& rc; 1258bf80f4bSopenharmony_ci StateCache& stateCache; 1268bf80f4bSopenharmony_ci RenderCommandWithType rpForCmdRef; 1278bf80f4bSopenharmony_ci }; 1288bf80f4bSopenharmony_ci void ProcessRenderNodeGraphNodeStores( 1298bf80f4bSopenharmony_ci const BASE_NS::array_view<RenderNodeGraphNodeStore*>& renderNodeGraphNodeStores, StateCache& stateCache); 1308bf80f4bSopenharmony_ci void ProcessRenderNodeCommands(BASE_NS::array_view<const RenderCommandWithType>& cmdListRef, 1318bf80f4bSopenharmony_ci const uint32_t& nodeIdx, RenderNodeContextData& ref, StateCache& stateCache); 1328bf80f4bSopenharmony_ci void StoreFinalBufferState(); 1338bf80f4bSopenharmony_ci // handles backbuffer layouts as well 1348bf80f4bSopenharmony_ci void StoreFinalImageState(); 1358bf80f4bSopenharmony_ci 1368bf80f4bSopenharmony_ci void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 1378bf80f4bSopenharmony_ci RenderNodeContextData& nodeData, RenderCommandBeginRenderPass& rc, StateCache& stateCache); 1388bf80f4bSopenharmony_ci void BeginRenderPassHandleDependency( 1398bf80f4bSopenharmony_ci BeginRenderPassParameters& params, const uint32_t commandListCommandIndex, RenderNodeContextData& nodeData); 1408bf80f4bSopenharmony_ci void BeginRenderPassUpdateImageStates(BeginRenderPassParameters& params, const GpuQueue& gpuQueue, 1418bf80f4bSopenharmony_ci BASE_NS::array_view<ImageLayout>& finalImageLayouts, const uint32_t renderNodeIndex); 1428bf80f4bSopenharmony_ci void BeginRenderPassUpdateSubpassImageStates(BASE_NS::array_view<const uint32_t> attatchmentIndices, 1438bf80f4bSopenharmony_ci const RenderPassDesc& renderPassDesc, const RenderPassAttachmentResourceStates& subpassResourceStatesRef, 1448bf80f4bSopenharmony_ci BASE_NS::array_view<ImageLayout> finalImageLayouts, StateCache& stateCache); 1458bf80f4bSopenharmony_ci 1468bf80f4bSopenharmony_ci void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 1478bf80f4bSopenharmony_ci const RenderNodeContextData& nodeData, RenderCommandEndRenderPass& rc, StateCache& stateCache); 1488bf80f4bSopenharmony_ci void RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 1498bf80f4bSopenharmony_ci RenderNodeContextData& nodeData, RenderCommandBarrierPoint& rc, StateCache& stateCache); 1508bf80f4bSopenharmony_ci 1518bf80f4bSopenharmony_ci struct ParameterCacheAllocOpt { 1528bf80f4bSopenharmony_ci BASE_NS::vector<CommandBarrier> combinedBarriers; 1538bf80f4bSopenharmony_ci BASE_NS::unordered_map<RenderHandle, uint32_t> handledCustomBarriers; 1548bf80f4bSopenharmony_ci }; 1558bf80f4bSopenharmony_ci ParameterCacheAllocOpt parameterCachePools_; 1568bf80f4bSopenharmony_ci struct ParameterCache { 1578bf80f4bSopenharmony_ci BASE_NS::vector<CommandBarrier>& combinedBarriers; 1588bf80f4bSopenharmony_ci BASE_NS::unordered_map<RenderHandle, uint32_t>& handledCustomBarriers; 1598bf80f4bSopenharmony_ci const uint32_t customBarrierCount; 1608bf80f4bSopenharmony_ci const uint32_t vertexInputBarrierCount; 1618bf80f4bSopenharmony_ci const uint32_t indirectBufferBarrierCount; 1628bf80f4bSopenharmony_ci const uint32_t renderNodeIndex; 1638bf80f4bSopenharmony_ci const GpuQueue gpuQueue; 1648bf80f4bSopenharmony_ci const RenderCommandWithType rcWithType; 1658bf80f4bSopenharmony_ci StateCache& stateCache; 1668bf80f4bSopenharmony_ci }; 1678bf80f4bSopenharmony_ci static void UpdateBufferResourceState( 1688bf80f4bSopenharmony_ci RenderGraphBufferState& stateRef, const ParameterCache& params, const CommandBarrier& cb); 1698bf80f4bSopenharmony_ci static void UpdateImageResourceState( 1708bf80f4bSopenharmony_ci RenderGraphImageState& stateRef, const ParameterCache& params, const CommandBarrier& cb); 1718bf80f4bSopenharmony_ci 1728bf80f4bSopenharmony_ci void HandleCustomBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 1738bf80f4bSopenharmony_ci const BASE_NS::array_view<const CommandBarrier>& customBarrierListRef); 1748bf80f4bSopenharmony_ci void HandleVertexInputBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 1758bf80f4bSopenharmony_ci const BASE_NS::array_view<const VertexBuffer>& vertexInputBufferBarrierListRef); 1768bf80f4bSopenharmony_ci void HandleRenderpassIndirectBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 1778bf80f4bSopenharmony_ci const BASE_NS::array_view<const VertexBuffer>& indirectBufferBarrierListRef); 1788bf80f4bSopenharmony_ci 1798bf80f4bSopenharmony_ci void HandleClearImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 1808bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 1818bf80f4bSopenharmony_ci void HandleBlitImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 1828bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 1838bf80f4bSopenharmony_ci void HandleCopyBuffer(ParameterCache& params, const uint32_t& commandListCommandIndex, 1848bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 1858bf80f4bSopenharmony_ci void HandleCopyBufferImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 1868bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 1878bf80f4bSopenharmony_ci void HandleDispatchIndirect(ParameterCache& params, const uint32_t& commandListCommandIndex, 1888bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef); 1898bf80f4bSopenharmony_ci 1908bf80f4bSopenharmony_ci void HandleDescriptorSets(ParameterCache& params, 1918bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderHandle>& descriptorSetHandlesForBarriers, 1928bf80f4bSopenharmony_ci const NodeContextDescriptorSetManager& nodeDescriptorSetMgrRef); 1938bf80f4bSopenharmony_ci 1948bf80f4bSopenharmony_ci void UpdateStateAndCreateBarriersGpuImage( 1958bf80f4bSopenharmony_ci const GpuResourceState& resourceState, const BindableImage& res, RenderGraph::ParameterCache& params); 1968bf80f4bSopenharmony_ci 1978bf80f4bSopenharmony_ci void UpdateStateAndCreateBarriersGpuBuffer( 1988bf80f4bSopenharmony_ci const GpuResourceState& resourceState, const BindableBuffer& res, RenderGraph::ParameterCache& params); 1998bf80f4bSopenharmony_ci 2008bf80f4bSopenharmony_ci void AddCommandBarrierAndUpdateStateCache(const uint32_t renderNodeIndex, 2018bf80f4bSopenharmony_ci const GpuResourceState& newGpuResourceState, const RenderCommandWithType& rcWithType, 2028bf80f4bSopenharmony_ci BASE_NS::vector<CommandBarrier>& barriers, BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 2038bf80f4bSopenharmony_ci 2048bf80f4bSopenharmony_ci void AddCommandBarrierAndUpdateStateCacheBuffer(const uint32_t renderNodeIndex, 2058bf80f4bSopenharmony_ci const GpuResourceState& newGpuResourceState, const BindableBuffer& newBuffer, 2068bf80f4bSopenharmony_ci const RenderCommandWithType& rcWithType, BASE_NS::vector<CommandBarrier>& barriers, 2078bf80f4bSopenharmony_ci BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 2088bf80f4bSopenharmony_ci 2098bf80f4bSopenharmony_ci void AddCommandBarrierAndUpdateStateCacheImage(const uint32_t renderNodeIndex, 2108bf80f4bSopenharmony_ci const GpuResourceState& newGpuResourceState, const BindableImage& newImage, 2118bf80f4bSopenharmony_ci const RenderCommandWithType& rcWithType, BASE_NS::vector<CommandBarrier>& barriers, 2128bf80f4bSopenharmony_ci BASE_NS::vector<GpuQueueTransferState>& currNodeGpuResourceTransfer); 2138bf80f4bSopenharmony_ci 2148bf80f4bSopenharmony_ci // if there's no state ATM, a undefined/invalid starting state is created 2158bf80f4bSopenharmony_ci // do not call this method with non dynamic trackable resources 2168bf80f4bSopenharmony_ci RenderGraphBufferState& GetBufferResourceStateRef(const RenderHandle handle, const GpuQueue& queue); 2178bf80f4bSopenharmony_ci RenderGraphImageState& GetImageResourceStateRef(const RenderHandle handle, const GpuQueue& queue); 2188bf80f4bSopenharmony_ci 2198bf80f4bSopenharmony_ci GpuResourceManager& gpuResourceMgr_; 2208bf80f4bSopenharmony_ci 2218bf80f4bSopenharmony_ci // stored every time at the end of the frame 2228bf80f4bSopenharmony_ci SwapchainStates swapchainStates_; 2238bf80f4bSopenharmony_ci 2248bf80f4bSopenharmony_ci // helper to access current render node transfers 2258bf80f4bSopenharmony_ci BASE_NS::vector<GpuQueueTransferState> currNodeGpuResourceTransfers_; 2268bf80f4bSopenharmony_ci 2278bf80f4bSopenharmony_ci // ~0u is invalid index, i.e. no state tracking 2288bf80f4bSopenharmony_ci BASE_NS::vector<uint32_t> gpuBufferDataIndices_; 2298bf80f4bSopenharmony_ci // ~0u is invalid index, i.e. no state tracking 2308bf80f4bSopenharmony_ci BASE_NS::vector<uint32_t> gpuImageDataIndices_; 2318bf80f4bSopenharmony_ci 2328bf80f4bSopenharmony_ci // resources that are tracked 2338bf80f4bSopenharmony_ci BASE_NS::vector<RenderGraphBufferState> gpuBufferTracking_; 2348bf80f4bSopenharmony_ci BASE_NS::vector<RenderGraphImageState> gpuImageTracking_; 2358bf80f4bSopenharmony_ci 2368bf80f4bSopenharmony_ci // available positions from gpuXXXTracking_ 2378bf80f4bSopenharmony_ci BASE_NS::vector<uint32_t> gpuBufferAvailableIndices_; 2388bf80f4bSopenharmony_ci BASE_NS::vector<uint32_t> gpuImageAvailableIndices_; 2398bf80f4bSopenharmony_ci 2408bf80f4bSopenharmony_ci RenderGraphBufferState defaultBufferState_ {}; 2418bf80f4bSopenharmony_ci RenderGraphImageState defaultImageState_ {}; 2428bf80f4bSopenharmony_ci}; 2438bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 2448bf80f4bSopenharmony_ci 2458bf80f4bSopenharmony_ci#endif // RENDER_GRAPH_H 246