• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "render_node_copy_util.h"
17 
18 #include <render/device/intf_gpu_resource_manager.h>
19 #include <render/device/intf_shader_manager.h>
20 #include <render/device/pipeline_layout_desc.h>
21 #include <render/device/pipeline_state_desc.h>
22 #include <render/namespace.h>
23 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
24 #include <render/nodecontext/intf_node_context_pso_manager.h>
25 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
26 #include <render/nodecontext/intf_render_command_list.h>
27 #include <render/nodecontext/intf_render_node_context_manager.h>
28 #include <render/nodecontext/intf_render_node_util.h>
29 
30 #include "default_engine_constants.h"
31 #include "device/gpu_resource_handle_util.h"
32 #include "util/log.h"
33 
34 // shaders
35 #include <render/shaders/common/render_post_process_structs_common.h>
36 
37 using namespace BASE_NS;
38 
39 RENDER_BEGIN_NAMESPACE()
40 namespace {
41 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
42 
CreateRenderPass(const IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderHandle input)43 RenderPass CreateRenderPass(const IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandle input)
44 {
45     const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input);
46     RenderPass rp;
47     rp.renderPassDesc.attachmentCount = 1u;
48     rp.renderPassDesc.attachmentHandles[0u] = input;
49     rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
50     rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
51     rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
52 
53     rp.renderPassDesc.subpassCount = 1u;
54     rp.subpassDesc.colorAttachmentCount = 1u;
55     rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
56     rp.subpassStartIndex = 0u;
57     return rp;
58 }
59 
CreatePso(IRenderNodeContextManager & renderNodeContextMgr,const RenderHandle & shader,const PipelineLayout & pipelineLayout,IDescriptorSetBinder::Ptr & binder)60 RenderHandle CreatePso(IRenderNodeContextManager& renderNodeContextMgr, const RenderHandle& shader,
61     const PipelineLayout& pipelineLayout, IDescriptorSetBinder::Ptr& binder)
62 {
63     auto& psoMgr = renderNodeContextMgr.GetPsoManager();
64     const auto& shaderMgr = renderNodeContextMgr.GetShaderManager();
65     const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shader);
66 
67     if (!binder) {
68         // single binder for both
69         INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr.GetDescriptorSetManager();
70         const auto& bindings = pipelineLayout.descriptorSetLayouts[0U].bindings;
71         const RenderHandle descHandle = descriptorSetMgr.CreateDescriptorSet(bindings);
72         binder = descriptorSetMgr.CreateDescriptorSetBinder(descHandle, bindings);
73     }
74     return psoMgr.GetGraphicsPsoHandle(
75         shader, graphicsStateHandle, pipelineLayout, {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
76 }
77 } // namespace
78 
Init(IRenderNodeContextManager & renderNodeContextMgr)79 void RenderNodeCopyUtil::Init(IRenderNodeContextManager& renderNodeContextMgr)
80 {
81     renderNodeContextMgr_ = &renderNodeContextMgr;
82     const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr.GetShaderManager();
83     {
84         renderData_ = {};
85         renderData_.shader = shaderMgr.GetShaderHandle("rendershaders://shader/fullscreen_copy.shader");
86         renderData_.pipelineLayout = shaderMgr.GetReflectionPipelineLayout(renderData_.shader);
87         renderData_.sampler = renderNodeContextMgr.GetGpuResourceManager().GetSamplerHandle(
88             DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP);
89 
90         renderData_.shaderLayer = shaderMgr.GetShaderHandle("rendershaders://shader/fullscreen_copy_layer.shader");
91         renderData_.pipelineLayoutLayer = shaderMgr.GetReflectionPipelineLayout(renderData_.shaderLayer);
92     }
93 }
94 
PreExecute()95 void RenderNodeCopyUtil::PreExecute() {}
96 
Execute(IRenderCommandList & cmdList,const CopyInfo & copyInfo)97 void RenderNodeCopyUtil::Execute(IRenderCommandList& cmdList, const CopyInfo& copyInfo)
98 {
99     copyInfo_ = copyInfo;
100 
101     // extra blit from input to ouput
102     if (RenderHandleUtil::IsGpuImage(copyInfo_.input.handle) && RenderHandleUtil::IsGpuImage(copyInfo_.output.handle)) {
103         RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderCopy", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
104 
105         auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
106 
107         auto renderPass = CreateRenderPass(gpuResourceMgr, copyInfo_.output.handle);
108         RenderHandle pso;
109         if (copyInfo_.copyType == CopyType::LAYER_COPY) {
110             if (!RenderHandleUtil::IsValid(renderData_.psoLayer)) {
111                 renderData_.psoLayer = CreatePso(
112                     *renderNodeContextMgr_, renderData_.shaderLayer, renderData_.pipelineLayoutLayer, binder_);
113             }
114             pso = renderData_.psoLayer;
115         } else {
116             if (!RenderHandleUtil::IsValid(renderData_.pso)) {
117                 renderData_.pso =
118                     CreatePso(*renderNodeContextMgr_, renderData_.shader, renderData_.pipelineLayout, binder_);
119             }
120             pso = renderData_.pso;
121         }
122 
123         cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
124         cmdList.BindPipeline(pso);
125 
126         {
127             auto& binder = *binder_;
128             binder.ClearBindings();
129             uint32_t binding = 0u;
130             binder.BindSampler(
131                 binding, RenderHandleUtil::IsValid(copyInfo_.sampler) ? copyInfo_.sampler : renderData_.sampler);
132             binder.BindImage(++binding, copyInfo_.input);
133             cmdList.UpdateDescriptorSet(
134                 binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
135             cmdList.BindDescriptorSet(0u, binder.GetDescriptorSetHandle());
136         }
137 
138         // dynamic state
139         const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
140         const ViewportDesc viewportDesc = renderNodeUtil.CreateDefaultViewport(renderPass);
141         const ScissorDesc scissorDesc = renderNodeUtil.CreateDefaultScissor(renderPass);
142         cmdList.SetDynamicStateViewport(viewportDesc);
143         cmdList.SetDynamicStateScissor(scissorDesc);
144 
145         const auto& pl =
146             (copyInfo_.copyType == CopyType::LAYER_COPY) ? renderData_.pipelineLayoutLayer : renderData_.pipelineLayout;
147         if (pl.pushConstant.byteSize > 0) {
148             const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
149             const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
150             const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight },
151                 { static_cast<float>(copyInfo_.input.layer), 0.0f, 0.0f, 0.0f } };
152             cmdList.PushConstantData(pl.pushConstant, arrayviewU8(pc));
153         }
154 
155         cmdList.Draw(3u, 1u, 0u, 0u);
156         cmdList.EndRenderPass();
157     }
158 }
159 
GetRenderDescriptorCounts() const160 DescriptorCounts RenderNodeCopyUtil::GetRenderDescriptorCounts() const
161 {
162     // prepare only for a single copy operation per frame
163     return DescriptorCounts { {
164         { CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1U },
165         { CORE_DESCRIPTOR_TYPE_SAMPLER, 1U },
166     } };
167 }
168 
GetInterface(const Uid & uid) const169 const CORE_NS::IInterface* RenderNodeCopyUtil::GetInterface(const Uid& uid) const
170 {
171     if ((uid == IRenderNodeCopyUtil::UID) || (uid == IInterface::UID)) {
172         return this;
173     }
174     return nullptr;
175 }
176 
GetInterface(const Uid & uid)177 CORE_NS::IInterface* RenderNodeCopyUtil::GetInterface(const Uid& uid)
178 {
179     if ((uid == IRenderNodeCopyUtil::UID) || (uid == IInterface::UID)) {
180         return this;
181     }
182     return nullptr;
183 }
184 
Ref()185 void RenderNodeCopyUtil::Ref()
186 {
187     refCount_++;
188 }
189 
Unref()190 void RenderNodeCopyUtil::Unref()
191 {
192     if (--refCount_ == 0) {
193         delete this;
194     }
195 }
196 RENDER_END_NAMESPACE()
197