• 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_post_process_fxaa_node.h"
17 
18 #include <base/containers/fixed_string.h>
19 #include <base/containers/unordered_map.h>
20 #include <base/math/vector.h>
21 #include <core/property/property_types.h>
22 #include <core/property_tools/property_api_impl.inl>
23 #include <render/datastore/intf_render_data_store_manager.h>
24 #include <render/datastore/intf_render_data_store_pod.h>
25 #include <render/datastore/render_data_store_render_pods.h>
26 #include <render/device/intf_gpu_resource_manager.h>
27 #include <render/device/intf_shader_manager.h>
28 #include <render/namespace.h>
29 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
30 #include <render/nodecontext/intf_node_context_pso_manager.h>
31 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
32 #include <render/nodecontext/intf_render_command_list.h>
33 #include <render/nodecontext/intf_render_node_context_manager.h>
34 #include <render/nodecontext/intf_render_node_util.h>
35 #include <render/property/property_types.h>
36 
37 #include "datastore/render_data_store_pod.h"
38 #include "datastore/render_data_store_post_process.h"
39 #include "default_engine_constants.h"
40 #include "device/gpu_resource_handle_util.h"
41 #include "render_post_process_fxaa.h"
42 #include "util/log.h"
43 
44 // shaders
45 #include <render/shaders/common/render_post_process_structs_common.h>
46 
47 using namespace BASE_NS;
48 using namespace CORE_NS;
49 using namespace RENDER_NS;
50 
51 CORE_BEGIN_NAMESPACE()
52 DATA_TYPE_METADATA(RenderPostProcessFxaaNode::NodeInputs, MEMBER_PROPERTY(input, "input", 0))
53 DATA_TYPE_METADATA(RenderPostProcessFxaaNode::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 FXAA_SHADER_NAME = "rendershaders://shader/fullscreen_fxaa.shader";
60 
61 } // namespace
62 
RenderPostProcessFxaaNode()63 RenderPostProcessFxaaNode::RenderPostProcessFxaaNode()
64     : inputProperties_(
65           &nodeInputsData, array_view(PropertyType::DataType<RenderPostProcessFxaaNode::NodeInputs>::properties)),
66       outputProperties_(
67           &nodeOutputsData, array_view(PropertyType::DataType<RenderPostProcessFxaaNode::NodeOutputs>::properties))
68 
69 {}
70 
GetRenderInputProperties()71 IPropertyHandle* RenderPostProcessFxaaNode::GetRenderInputProperties()
72 {
73     return inputProperties_.GetData();
74 }
75 
GetRenderOutputProperties()76 IPropertyHandle* RenderPostProcessFxaaNode::GetRenderOutputProperties()
77 {
78     return outputProperties_.GetData();
79 }
80 
SetRenderAreaRequest(const RenderAreaRequest & renderAreaRequest)81 void RenderPostProcessFxaaNode::SetRenderAreaRequest(const RenderAreaRequest& renderAreaRequest)
82 {
83     useRequestedRenderArea_ = true;
84     renderAreaRequest_ = renderAreaRequest;
85 }
86 
GetExecuteFlags() const87 IRenderNode::ExecuteFlags RenderPostProcessFxaaNode::GetExecuteFlags() const
88 {
89     if (effectProperties_.enabled) {
90         return 0;
91     } else {
92         return IRenderNode::ExecuteFlagBits::EXECUTE_FLAG_BITS_DO_NOT_EXECUTE;
93     }
94 }
95 
Init(const IRenderPostProcess::Ptr & postProcess,IRenderNodeContextManager & renderNodeContextMgr)96 void RenderPostProcessFxaaNode::Init(
97     const IRenderPostProcess::Ptr& postProcess, IRenderNodeContextManager& renderNodeContextMgr)
98 {
99     renderNodeContextMgr_ = &renderNodeContextMgr;
100     postProcess_ = postProcess;
101 
102     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
103     samplerHandle_ =
104         gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP);
105 
106     const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
107     shaderData_ = shaderMgr.GetShaderDataByShaderName(FXAA_SHADER_NAME);
108 
109     const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
110     descriptorCounts_ = renderNodeUtil.GetDescriptorCounts(shaderData_.pipelineLayoutData);
111 
112     valid_ = true;
113 }
114 
PreExecute()115 void RenderPostProcessFxaaNode::PreExecute()
116 {
117     if (valid_ && postProcess_) {
118         const array_view<const uint8_t> propertyView = postProcess_->GetData();
119         // this node is directly dependant
120         PLUGIN_ASSERT(propertyView.size_bytes() == sizeof(RenderPostProcessFxaaNode::EffectProperties));
121         if (propertyView.size_bytes() == sizeof(RenderPostProcessFxaaNode::EffectProperties)) {
122             effectProperties_ = (const RenderPostProcessFxaaNode::EffectProperties&)(*propertyView.data());
123         }
124     } else {
125         effectProperties_.enabled = false;
126     }
127 }
128 
CreateRenderPass(const RenderHandle input) const129 RenderPass RenderPostProcessFxaaNode::CreateRenderPass(const RenderHandle input) const
130 {
131     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
132     const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input);
133     RenderPass rp;
134     rp.renderPassDesc.attachmentCount = 1u;
135     rp.renderPassDesc.attachmentHandles[0u] = input;
136     rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
137     rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
138     rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
139 
140     rp.renderPassDesc.subpassCount = 1u;
141     rp.subpassDesc.colorAttachmentCount = 1u;
142     rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
143     rp.subpassStartIndex = 0u;
144     return rp;
145 }
146 
GetFactorFxaa() const147 BASE_NS::Math::Vec4 RenderPostProcessFxaaNode::GetFactorFxaa() const
148 {
149     return { static_cast<float>(effectProperties_.fxaaConfiguration.sharpness),
150         static_cast<float>(effectProperties_.fxaaConfiguration.quality), 0.0f, 0.0f };
151 }
152 
Execute(IRenderCommandList & cmdList)153 void RenderPostProcessFxaaNode::Execute(IRenderCommandList& cmdList)
154 {
155     CheckDescriptorSetNeed();
156 
157     RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderFXAA", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
158 
159     auto renderPass = CreateRenderPass(nodeOutputsData.output.handle);
160     if (!RenderHandleUtil::IsValid(pso_)) {
161         auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
162         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
163         const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shaderData_.shader);
164         pso_ = psoMgr.GetGraphicsPsoHandle(shaderData_.shader, gfxHandle, shaderData_.pipelineLayout, {}, {},
165             { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
166     }
167 
168     cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
169     cmdList.BindPipeline(pso_);
170 
171     {
172         auto& binder = *fxaaBinder_;
173         binder.ClearBindings();
174         uint32_t binding = 0u;
175         binder.BindImage(binding, nodeInputsData.input);
176         binder.BindSampler(++binding, samplerHandle_);
177 
178         const RenderHandle set = binder.GetDescriptorSetHandle();
179         const DescriptorSetLayoutBindingResources resources = binder.GetDescriptorSetLayoutBindingResources();
180 
181         cmdList.UpdateDescriptorSet(set, resources);
182         cmdList.BindDescriptorSet(0U, set);
183     }
184 
185     if (shaderData_.pipelineLayoutData.pushConstant.byteSize > 0U) {
186         const LocalPostProcessPushConstantStruct pc { effectProperties_.targetSize, GetFactorFxaa() };
187         cmdList.PushConstantData(shaderData_.pipelineLayoutData.pushConstant, arrayviewU8(pc));
188     }
189 
190     // dynamic state
191     cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
192     cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
193 
194     cmdList.Draw(3u, 1u, 0u, 0u);
195     cmdList.EndRenderPass();
196 }
197 
CheckDescriptorSetNeed()198 void RenderPostProcessFxaaNode::CheckDescriptorSetNeed()
199 {
200     if (!fxaaBinder_) {
201         INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
202         fxaaBinder_ = descriptorSetMgr.CreateDescriptorSetBinder(
203             descriptorSetMgr.CreateDescriptorSet(0, shaderData_.pipelineLayoutData),
204             shaderData_.pipelineLayoutData.descriptorSetLayouts[0].bindings);
205     }
206 }
207 
GetRenderDescriptorCounts() const208 DescriptorCounts RenderPostProcessFxaaNode::GetRenderDescriptorCounts() const
209 {
210     return descriptorCounts_;
211 }
212 
213 RENDER_END_NAMESPACE()
214