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 #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)60 RenderHandle CreatePso(
61 IRenderNodeContextManager& renderNodeContextMgr, const RenderHandle& shader, const PipelineLayout& pipelineLayout)
62 {
63 auto& psoMgr = renderNodeContextMgr.GetPsoManager();
64 const auto& shaderMgr = renderNodeContextMgr.GetShaderManager();
65 const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shader);
66 return psoMgr.GetGraphicsPsoHandle(
67 shader, graphicsStateHandle, pipelineLayout, {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
68 }
69 } // namespace
70
Init(IRenderNodeContextManager & renderNodeContextMgr)71 void RenderNodeCopyUtil::Init(IRenderNodeContextManager& renderNodeContextMgr)
72 {
73 renderNodeContextMgr_ = &renderNodeContextMgr;
74 const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr.GetShaderManager();
75 {
76 renderData_ = {};
77 renderData_.shader = shaderMgr.GetShaderHandle("rendershaders://shader/fullscreen_copy.shader");
78 renderData_.pipelineLayout = shaderMgr.GetReflectionPipelineLayout(renderData_.shader);
79 renderData_.sampler = renderNodeContextMgr.GetGpuResourceManager().GetSamplerHandle(
80 DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP);
81
82 renderData_.shaderLayer = shaderMgr.GetShaderHandle("rendershaders://shader/fullscreen_copy_layer.shader");
83 renderData_.pipelineLayoutLayer = shaderMgr.GetReflectionPipelineLayout(renderData_.shaderLayer);
84 }
85 {
86 // single binder for both
87 INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr.GetDescriptorSetManager();
88 const auto& bindings = renderData_.pipelineLayout.descriptorSetLayouts[0U].bindings;
89 const RenderHandle descHandle = descriptorSetMgr.CreateDescriptorSet(bindings);
90 binder_ = descriptorSetMgr.CreateDescriptorSetBinder(descHandle, bindings);
91 }
92 }
93
PreExecute()94 void RenderNodeCopyUtil::PreExecute() {}
95
Execute(IRenderCommandList & cmdList,const CopyInfo & copyInfo)96 void RenderNodeCopyUtil::Execute(IRenderCommandList& cmdList, const CopyInfo& copyInfo)
97 {
98 copyInfo_ = copyInfo;
99
100 // extra blit from input to ouput
101 if (RenderHandleUtil::IsGpuImage(copyInfo_.input.handle) && RenderHandleUtil::IsGpuImage(copyInfo_.output.handle) &&
102 binder_) {
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 =
112 CreatePso(*renderNodeContextMgr_, renderData_.shaderLayer, renderData_.pipelineLayoutLayer);
113 }
114 pso = renderData_.psoLayer;
115 } else {
116 if (!RenderHandleUtil::IsValid(renderData_.pso)) {
117 renderData_.pso = CreatePso(*renderNodeContextMgr_, renderData_.shader, renderData_.pipelineLayout);
118 }
119 pso = renderData_.pso;
120 }
121
122 cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
123 cmdList.BindPipeline(pso);
124
125 {
126 auto& binder = *binder_;
127 binder.ClearBindings();
128 uint32_t binding = 0u;
129 binder.BindSampler(
130 binding, RenderHandleUtil::IsValid(copyInfo_.sampler) ? copyInfo_.sampler : renderData_.sampler);
131 binder.BindImage(++binding, copyInfo_.input);
132 cmdList.UpdateDescriptorSet(
133 binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources());
134 cmdList.BindDescriptorSet(0u, binder.GetDescriptorSetHandle());
135 }
136
137 // dynamic state
138 const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
139 const ViewportDesc viewportDesc = renderNodeUtil.CreateDefaultViewport(renderPass);
140 const ScissorDesc scissorDesc = renderNodeUtil.CreateDefaultScissor(renderPass);
141 cmdList.SetDynamicStateViewport(viewportDesc);
142 cmdList.SetDynamicStateScissor(scissorDesc);
143
144 const auto& pl =
145 (copyInfo_.copyType == CopyType::LAYER_COPY) ? renderData_.pipelineLayoutLayer : renderData_.pipelineLayout;
146 if (pl.pushConstant.byteSize > 0) {
147 const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
148 const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
149 const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight },
150 { static_cast<float>(copyInfo_.input.layer), 0.0f, 0.0f, 0.0f } };
151 cmdList.PushConstantData(pl.pushConstant, arrayviewU8(pc));
152 }
153
154 cmdList.Draw(3u, 1u, 0u, 0u);
155 cmdList.EndRenderPass();
156 }
157 }
158
GetRenderDescriptorCounts() const159 DescriptorCounts RenderNodeCopyUtil::GetRenderDescriptorCounts() const
160 {
161 // prepare only for a single copy operation per frame
162 return DescriptorCounts { {
163 { CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1U },
164 { CORE_DESCRIPTOR_TYPE_SAMPLER, 1U },
165 } };
166 }
167
GetInterface(const Uid & uid) const168 const CORE_NS::IInterface* RenderNodeCopyUtil::GetInterface(const Uid& uid) const
169 {
170 if ((uid == IRenderNodeCopyUtil::UID) || (uid == IInterface::UID)) {
171 return this;
172 }
173 return nullptr;
174 }
175
GetInterface(const Uid & uid)176 CORE_NS::IInterface* RenderNodeCopyUtil::GetInterface(const Uid& uid)
177 {
178 if ((uid == IRenderNodeCopyUtil::UID) || (uid == IInterface::UID)) {
179 return this;
180 }
181 return nullptr;
182 }
183
Ref()184 void RenderNodeCopyUtil::Ref()
185 {
186 refCount_++;
187 }
188
Unref()189 void RenderNodeCopyUtil::Unref()
190 {
191 if (--refCount_ == 0) {
192 delete this;
193 }
194 }
195 RENDER_END_NAMESPACE()
196