• 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_taa_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/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 "default_engine_constants.h"
36 #include "device/gpu_resource_handle_util.h"
37 #include "render_post_process_taa.h"
38 #include "util/log.h"
39 
40 // shaders
41 #include <render/shaders/common/render_post_process_structs_common.h>
42 
43 using namespace BASE_NS;
44 using namespace CORE_NS;
45 using namespace RENDER_NS;
46 
47 CORE_BEGIN_NAMESPACE()
48 DATA_TYPE_METADATA(RenderPostProcessTaaNode::NodeInputs, MEMBER_PROPERTY(input, "input", 0),
49     MEMBER_PROPERTY(depth, "depth", 0), MEMBER_PROPERTY(velocity, "velocity", 0),
50     MEMBER_PROPERTY(history, "history", 0))
51 DATA_TYPE_METADATA(RenderPostProcessTaaNode::NodeOutputs, MEMBER_PROPERTY(output, "output", 0))
52 CORE_END_NAMESPACE()
53 
54 RENDER_BEGIN_NAMESPACE()
55 namespace {
56 constexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR };
57 constexpr string_view TAA_SHADER_NAME = "rendershaders://shader/fullscreen_taa.shader";
58 } // namespace
59 
RenderPostProcessTaaNode()60 RenderPostProcessTaaNode::RenderPostProcessTaaNode()
61     : inputProperties_(
62           &nodeInputsData, array_view(PropertyType::DataType<RenderPostProcessTaaNode::NodeInputs>::properties)),
63       outputProperties_(
64           &nodeOutputsData, array_view(PropertyType::DataType<RenderPostProcessTaaNode::NodeOutputs>::properties))
65 
66 {}
67 
GetRenderInputProperties()68 IPropertyHandle* RenderPostProcessTaaNode::GetRenderInputProperties()
69 {
70     return inputProperties_.GetData();
71 }
72 
GetRenderOutputProperties()73 IPropertyHandle* RenderPostProcessTaaNode::GetRenderOutputProperties()
74 {
75     return outputProperties_.GetData();
76 }
77 
SetRenderAreaRequest(const RenderAreaRequest & renderAreaRequest)78 void RenderPostProcessTaaNode::SetRenderAreaRequest(const RenderAreaRequest& renderAreaRequest)
79 {
80     useRequestedRenderArea_ = true;
81     renderAreaRequest_ = renderAreaRequest;
82 }
83 
GetExecuteFlags() const84 IRenderNode::ExecuteFlags RenderPostProcessTaaNode::GetExecuteFlags() const
85 {
86     if (effectProperties_.enabled) {
87         return 0;
88     } else {
89         return IRenderNode::ExecuteFlagBits::EXECUTE_FLAG_BITS_DO_NOT_EXECUTE;
90     }
91 }
92 
Init(const IRenderPostProcess::Ptr & postProcess,IRenderNodeContextManager & renderNodeContextMgr)93 void RenderPostProcessTaaNode::Init(
94     const IRenderPostProcess::Ptr& postProcess, IRenderNodeContextManager& renderNodeContextMgr)
95 {
96     renderNodeContextMgr_ = &renderNodeContextMgr;
97     postProcess_ = postProcess;
98 
99     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
100     samplerHandle_ =
101         gpuResourceMgr.GetSamplerHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP);
102 
103     const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
104     shaderData_ = shaderMgr.GetShaderDataByShaderName(TAA_SHADER_NAME);
105 
106     const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
107     descriptorCounts_ = renderNodeUtil.GetDescriptorCounts(shaderData_.pipelineLayoutData);
108 
109     valid_ = true;
110 }
111 
PreExecute()112 void RenderPostProcessTaaNode::PreExecute()
113 {
114     if (valid_ && postProcess_) {
115         const array_view<const uint8_t> propertyView = postProcess_->GetData();
116         // this node is directly dependant
117         PLUGIN_ASSERT(propertyView.size_bytes() == sizeof(RenderPostProcessTaaNode::EffectProperties));
118         if (propertyView.size_bytes() == sizeof(RenderPostProcessTaaNode::EffectProperties)) {
119             effectProperties_ = (const RenderPostProcessTaaNode::EffectProperties&)(*propertyView.data());
120         }
121     } else {
122         effectProperties_.enabled = false;
123     }
124 }
125 
CreateRenderPass(const RenderHandle input) const126 RenderPass RenderPostProcessTaaNode::CreateRenderPass(const RenderHandle input) const
127 {
128     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
129     const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input);
130     RenderPass rp;
131     rp.renderPassDesc.attachmentCount = 1u;
132     rp.renderPassDesc.attachmentHandles[0u] = input;
133     rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE;
134     rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
135     rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height };
136 
137     rp.renderPassDesc.subpassCount = 1u;
138     rp.subpassDesc.colorAttachmentCount = 1u;
139     rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
140     rp.subpassStartIndex = 0u;
141     return rp;
142 }
143 
GetFactorTaa() const144 BASE_NS::Math::Vec4 RenderPostProcessTaaNode::GetFactorTaa() const
145 {
146     constexpr float alpha = 0.1f;
147 
148     uint32_t varianceClippingBicubic = 0;
149     if (effectProperties_.taaConfiguration.useBicubic) {
150         varianceClippingBicubic |= (1 << TAA_USE_BICUBIC_BIT);
151     }
152     if (effectProperties_.taaConfiguration.useVarianceClipping) {
153         varianceClippingBicubic |= (1 << TAA_USE_VARIANCE_CLIPPING_BIT);
154     }
155     if (effectProperties_.taaConfiguration.useyCoCG) {
156         varianceClippingBicubic |= (1 << TAA_USE_YCOCG_BIT);
157     }
158     if (effectProperties_.taaConfiguration.ignoreBicubicEdges) {
159         varianceClippingBicubic |= (1 << TAA_IGNORE_EDGES_BIT);
160     }
161 
162     const float vcb = *(reinterpret_cast<float*>(&varianceClippingBicubic));
163 
164     return { static_cast<float>(effectProperties_.taaConfiguration.sharpness),
165         static_cast<float>(effectProperties_.taaConfiguration.quality), vcb, alpha };
166 }
167 
Execute(IRenderCommandList & cmdList)168 void RenderPostProcessTaaNode::Execute(IRenderCommandList& cmdList)
169 {
170     CheckDescriptorSetNeed();
171 
172     RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderTAA", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
173 
174     auto renderPass = CreateRenderPass(nodeOutputsData.output.handle);
175     if (!RenderHandleUtil::IsValid(pso_)) {
176         const auto& shaderMgr = renderNodeContextMgr_->GetShaderManager();
177         auto& psoMgr = renderNodeContextMgr_->GetPsoManager();
178         const RenderHandle gfxHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shaderData_.shader);
179         pso_ = psoMgr.GetGraphicsPsoHandle(shaderData_.shader, gfxHandle, shaderData_.pipelineLayout, {}, {},
180             { DYNAMIC_STATES, countof(DYNAMIC_STATES) });
181     }
182 
183     cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
184     cmdList.BindPipeline(pso_);
185 
186     {
187         auto& binder = *taaBinder_;
188         binder.ClearBindings();
189         uint32_t binding = 0u;
190         binder.BindImage(binding, nodeInputsData.depth.handle);
191         binder.BindImage(++binding, nodeInputsData.input.handle);
192         binder.BindImage(++binding, nodeInputsData.velocity.handle);
193         binder.BindImage(++binding, nodeInputsData.history.handle);
194         binder.BindSampler(++binding, samplerHandle_);
195 
196         const RenderHandle set = binder.GetDescriptorSetHandle();
197         const DescriptorSetLayoutBindingResources resources = binder.GetDescriptorSetLayoutBindingResources();
198 
199         cmdList.UpdateDescriptorSet(set, resources);
200         cmdList.BindDescriptorSet(0U, set);
201     }
202 
203     if (shaderData_.pipelineLayoutData.pushConstant.byteSize > 0U) {
204         const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth);
205         const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight);
206         const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight },
207             GetFactorTaa() };
208         cmdList.PushConstantData(shaderData_.pipelineLayoutData.pushConstant, arrayviewU8(pc));
209     }
210 
211     // dynamic state
212     cmdList.SetDynamicStateViewport(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultViewport(renderPass));
213     cmdList.SetDynamicStateScissor(renderNodeContextMgr_->GetRenderNodeUtil().CreateDefaultScissor(renderPass));
214 
215     cmdList.Draw(3u, 1u, 0u, 0u);
216     cmdList.EndRenderPass();
217 }
218 
CheckDescriptorSetNeed()219 void RenderPostProcessTaaNode::CheckDescriptorSetNeed()
220 {
221     if (!taaBinder_) {
222         INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr_->GetDescriptorSetManager();
223         taaBinder_ = descriptorSetMgr.CreateDescriptorSetBinder(
224             descriptorSetMgr.CreateDescriptorSet(0, shaderData_.pipelineLayoutData),
225             shaderData_.pipelineLayoutData.descriptorSetLayouts[0].bindings);
226     }
227 }
228 
GetRenderDescriptorCounts() const229 DescriptorCounts RenderPostProcessTaaNode::GetRenderDescriptorCounts() const
230 {
231     return descriptorCounts_;
232 }
233 
234 RENDER_END_NAMESPACE()
235