• 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 <base/containers/fixed_string.h>
17 #include <base/containers/unordered_map.h>
18 #include <base/math/vector.h>
19 #include <core/property/property_types.h>
20 #include <core/property_tools/property_api_impl.inl>
21 #include <render/datastore/intf_render_data_store_manager.h>
22 #include <render/datastore/intf_render_data_store_pod.h>
23 #include <render/datastore/render_data_store_render_pods.h>
24 #include <render/device/intf_gpu_resource_manager.h>
25 #include <render/device/intf_shader_manager.h>
26 #include <render/namespace.h>
27 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
28 #include <render/nodecontext/intf_node_context_pso_manager.h>
29 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
30 #include <render/nodecontext/intf_render_command_list.h>
31 #include <render/nodecontext/intf_render_node_context_manager.h>
32 #include <render/nodecontext/intf_render_node_util.h>
33 #include <render/property/property_types.h>
34 
35 #include "datastore/render_data_store_pod.h"
36 #include "datastore/render_data_store_post_process.h"
37 #include "default_engine_constants.h"
38 #include "device/gpu_resource_handle_util.h"
39 #include "render_post_process_combined.h"
40 #include "render_post_process_fxaa_node.h"
41 #include "util/log.h"
42 
43 // shaders
44 #include <render/shaders/common/render_post_process_structs_common.h>
45 
46 using namespace BASE_NS;
47 using namespace CORE_NS;
48 using namespace RENDER_NS;
49 
50 CORE_BEGIN_NAMESPACE()
51 DATA_TYPE_METADATA(RenderPostProcessCombinedNode::NodeInputs, MEMBER_PROPERTY(input, "input", 0),
52     MEMBER_PROPERTY(bloomFinalTarget, "bloomFinalTarget", 0), MEMBER_PROPERTY(dirtMask, "dirtMask", 0))
53 DATA_TYPE_METADATA(RenderPostProcessCombinedNode::NodeOutputs, MEMBER_PROPERTY(output, "output", 0))
54 CORE_END_NAMESPACE()
55 
56 RENDER_BEGIN_NAMESPACE()
57 namespace {
58 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
59 constexpr string_view COMBINED_SHADER_NAME = "rendershaders://shader/fullscreen_combined_post_process.shader";
60 constexpr string_view COMBINED_LAYER_SHADER_NAME =
61     "rendershaders://shader/fullscreen_combined_post_process_layer.shader";
62 } // namespace
63 
RenderPostProcessCombinedNode()64 RenderPostProcessCombinedNode::RenderPostProcessCombinedNode()
65     : inputProperties_(
66           &nodeInputsData, array_view(PropertyType::DataType<RenderPostProcessCombinedNode::NodeInputs>::properties)),
67       outputProperties_(
68           &nodeOutputsData, array_view(PropertyType::DataType<RenderPostProcessCombinedNode::NodeOutputs>::properties))
69 
70 {}
71 
GetRenderInputProperties()72 IPropertyHandle* RenderPostProcessCombinedNode::GetRenderInputProperties()
73 {
74     return inputProperties_.GetData();
75 }
76 
GetRenderOutputProperties()77 IPropertyHandle* RenderPostProcessCombinedNode::GetRenderOutputProperties()
78 {
79     return outputProperties_.GetData();
80 }
81 
SetRenderAreaRequest(const RenderAreaRequest & renderAreaRequest)82 void RenderPostProcessCombinedNode::SetRenderAreaRequest(const RenderAreaRequest& renderAreaRequest)
83 {
84     useRequestedRenderArea_ = true;
85     renderAreaRequest_ = renderAreaRequest;
86 }
87 
GetExecuteFlags() const88 IRenderNode::ExecuteFlags RenderPostProcessCombinedNode::GetExecuteFlags() const
89 {
90     if (effectProperties_.enabled) {
91         return 0;
92     } else {
93         return IRenderNode::ExecuteFlagBits::EXECUTE_FLAG_BITS_DO_NOT_EXECUTE;
94     }
95 }
96 
Init(const IRenderPostProcess::Ptr & postProcess,IRenderNodeContextManager & renderNodeContextMgr)97 void RenderPostProcessCombinedNode::Init(
98     const IRenderPostProcess::Ptr& postProcess, IRenderNodeContextManager& renderNodeContextMgr)
99 {
100     renderNodeContextMgr_ = &renderNodeContextMgr;
101     postProcess_ = postProcess;
102 
103     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
104     samplers_.nearest =
105         gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_CLAMP);
106     samplers_.linear =
107         gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP);
108 
109     const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
110     combineData_.sd = shaderMgr.GetShaderDataByShaderName(COMBINED_SHADER_NAME);
111     combineDataLayer_.sd = shaderMgr.GetShaderDataByShaderName(COMBINED_LAYER_SHADER_NAME);
112 
113     const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
114     auto combineLayerDescriptors = renderNodeUtil.GetDescriptorCounts(combineDataLayer_.sd.pipelineLayoutData);
115     descriptorCounts_ = renderNodeUtil.GetDescriptorCounts(combineData_.sd.pipelineLayoutData);
116 
117     descriptorCounts_.counts.insert(
118         descriptorCounts_.counts.end(), combineLayerDescriptors.counts.begin(), combineLayerDescriptors.counts.end());
119 
120     valid_ = true;
121 }
122 
PreExecute()123 void RenderPostProcessCombinedNode::PreExecute()
124 {
125     if (valid_ && postProcess_) {
126         const array_view<const uint8_t> propertyView = postProcess_->GetData();
127         // this node is directly dependant
128         PLUGIN_ASSERT(propertyView.size_bytes() == sizeof(RenderPostProcessCombinedNode::EffectProperties));
129         if (propertyView.size_bytes() == sizeof(RenderPostProcessCombinedNode::EffectProperties)) {
130             effectProperties_ = (const RenderPostProcessCombinedNode::EffectProperties&)(*propertyView.data());
131         }
132         // allocate UBO data
133         IRenderNodeGpuResourceManager& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
134         reservedUboHandle_ = gpuResourceMgr.ReserveGpuBuffer(sizeof(RenderPostProcessConfiguration));
135     } else {
136         effectProperties_.enabled = false;
137     }
138 }
139 
CreateRenderPass(const RenderHandle input)140 RenderPass RenderPostProcessCombinedNode::CreateRenderPass(const RenderHandle input)
141 {
142     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
143     const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input);
144     RenderPass rp;
145     rp.renderPassDesc.attachmentCount = 1u;
146     rp.renderPassDesc.attachmentHandles[0u] = input;
147     rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
148     rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
149     rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
150 
151     rp.renderPassDesc.subpassCount = 1u;
152     rp.subpassDesc.colorAttachmentCount = 1u;
153     rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
154     rp.subpassStartIndex = 0u;
155     return rp;
156 }
157 
Execute(IRenderCommandList & cmdList)158 void RenderPostProcessCombinedNode::Execute(IRenderCommandList& cmdList)
159 {
160     CheckDescriptorSetNeed();
161 
162     RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderCombine", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
163 
164     UpdatePostProcessData(effectProperties_.postProcessConfiguration);
165 
166     auto& effect = effectProperties_.glOptimizedLayerCopyEnabled ? combineDataLayer_ : combineData_;
167     const RenderPass renderPass = CreateRenderPass(nodeOutputsData.output.handle);
168     if (!RenderHandleUtil::IsValid(effect.pso)) {
169         auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
170         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
171         const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(effect.sd.shader);
172         effect.pso = psoMgr.GetGraphicsPsoHandle(effect.sd.shader, graphicsStateHandle, effect.sd.pipelineLayout, {},
173             {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
174     }
175 
176     cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
177     cmdList.BindPipeline(effect.pso);
178 
179     {
180         RenderHandle sets[2U] {};
181         DescriptorSetLayoutBindingResources resources[2U] {};
182         {
183             auto& binder = *binders_.set0;
184             binder.ClearBindings();
185             uint32_t binding = 0u;
186             binder.BindBuffer(binding, acquiredGpuBufferData_.handle, acquiredGpuBufferData_.bindingByteOffset);
187             sets[0U] = binder.GetDescriptorSetHandle();
188             resources[0U] = binder.GetDescriptorSetLayoutBindingResources();
189         }
190         {
191             auto& binder = *binders_.combineBinder;
192             binder.ClearBindings();
193             uint32_t binding = 0u;
194             BindableImage mainInput = nodeInputsData.input;
195             mainInput.samplerHandle = samplers_.linear;
196             binder.BindImage(binding++, mainInput);
197             binder.BindImage(binding++, nodeInputsData.bloomFinalTarget.handle, samplers_.linear);
198             binder.BindImage(binding++, nodeInputsData.dirtMask.handle, samplers_.linear);
199             sets[1U] = binder.GetDescriptorSetHandle();
200             resources[1U] = binder.GetDescriptorSetLayoutBindingResources();
201         }
202         cmdList.UpdateDescriptorSets(sets, resources);
203         cmdList.BindDescriptorSets(0u, sets);
204     }
205 
206     // dynamic state
207     cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
208     cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
209 
210     if (effect.sd.pipelineLayoutData.pushConstant.byteSize > 0U) {
211         const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
212         const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
213         const float layer = effectProperties_.glOptimizedLayerCopyEnabled ? float(nodeInputsData.input.layer) : 0.0f;
214         const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight },
215             { layer, 0.0f, 0.0f, 0.0f } };
216         cmdList.PushConstantData(effect.sd.pipelineLayoutData.pushConstant, arrayviewU8(pc));
217     }
218 
219     cmdList.Draw(3u, 1u, 0u, 0u);
220     cmdList.EndRenderPass();
221 }
222 
UpdatePostProcessData(const PostProcessConfiguration & postProcessConfiguration)223 void RenderPostProcessCombinedNode::UpdatePostProcessData(const PostProcessConfiguration& postProcessConfiguration)
224 {
225     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
226     acquiredGpuBufferData_ = gpuResourceMgr.AcquireGpubuffer(reservedUboHandle_);
227 
228     const RenderPostProcessConfiguration rppc =
229         renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(postProcessConfiguration);
230     PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration));
231     if (acquiredGpuBufferData_.data) {
232         const auto& mgbd = acquiredGpuBufferData_;
233         if (!CloneData(mgbd.data, size_t(mgbd.byteSize), &rppc, sizeof(RenderPostProcessConfiguration))) {
234             PLUGIN_LOG_E("post process ubo copying failed.");
235         }
236     }
237 }
238 
CheckDescriptorSetNeed()239 void RenderPostProcessCombinedNode::CheckDescriptorSetNeed()
240 {
241     if (!binders_.set0) {
242         INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
243         constexpr uint32_t globalSetIdx = 0u;
244         constexpr uint32_t localSetIdx = 1u;
245 
246         binders_.set0 = descriptorSetMgr.CreateDescriptorSetBinder(
247             descriptorSetMgr.CreateDescriptorSet(globalSetIdx, combineData_.sd.pipelineLayoutData),
248             combineData_.sd.pipelineLayoutData.descriptorSetLayouts[globalSetIdx].bindings);
249 
250         binders_.combineBinder = descriptorSetMgr.CreateDescriptorSetBinder(
251             descriptorSetMgr.CreateDescriptorSet(localSetIdx, combineData_.sd.pipelineLayoutData),
252             combineData_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
253         binders_.combineLayerBinder = descriptorSetMgr.CreateDescriptorSetBinder(
254             descriptorSetMgr.CreateDescriptorSet(localSetIdx, combineDataLayer_.sd.pipelineLayoutData),
255             combineDataLayer_.sd.pipelineLayoutData.descriptorSetLayouts[localSetIdx].bindings);
256     }
257 }
258 
GetRenderDescriptorCounts() const259 DescriptorCounts RenderPostProcessCombinedNode::GetRenderDescriptorCounts() const
260 {
261     return descriptorCounts_;
262 }
263 
264 RENDER_END_NAMESPACE()
265