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 #ifndef RENDER_POSTPROCESS_RENDER_POSTPROCESS_UPSCALE_NODE_H
17 #define RENDER_POSTPROCESS_RENDER_POSTPROCESS_UPSCALE_NODE_H
18
19 #include <array>
20
21 #include <base/containers/unique_ptr.h>
22 #include <base/math/matrix_util.h>
23 #include <base/util/uid.h>
24 #include <core/plugin/intf_interface.h>
25 #include <core/plugin/intf_interface_helper.h>
26 #include <core/property/intf_property_api.h>
27 #include <core/property/intf_property_handle.h>
28 #include <core/property/property_types.h>
29 #include <core/property_tools/property_api_impl.h>
30 #include <core/property_tools/property_macros.h>
31 #include <render/device/intf_shader_manager.h>
32 #include <render/namespace.h>
33 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
34 #include <render/nodecontext/intf_render_node.h>
35 #include <render/nodecontext/intf_render_post_process.h>
36 #include <render/nodecontext/intf_render_post_process_node.h>
37 #include <render/property/property_types.h>
38 #include <render/render_data_structures.h>
39
40 #include "nodecontext/render_node_copy_util.h"
41
RENDER_BEGIN_NAMESPACE()42 RENDER_BEGIN_NAMESPACE()
43 class RenderPostProcessUpscaleNode : public CORE_NS::IInterfaceHelper<RENDER_NS::IRenderPostProcessNode> {
44 public:
45 static constexpr auto UID = BASE_NS::Uid("81321991-8314-4c74-bc6a-487eed297550");
46
47 using Ptr = BASE_NS::refcnt_ptr<RenderPostProcessUpscaleNode>;
48
49 struct EffectProperties {
50 bool enabled { true };
51 float ratio = 1.5f;
52 };
53
54 RenderPostProcessUpscaleNode();
55 ~RenderPostProcessUpscaleNode() = default;
56
57 CORE_NS::IPropertyHandle* GetRenderInputProperties() override;
58 CORE_NS::IPropertyHandle* GetRenderOutputProperties() override;
59 RENDER_NS::DescriptorCounts GetRenderDescriptorCounts() const override;
60 void SetRenderAreaRequest(const RenderAreaRequest& renderAreaRequest) override;
61
62 RENDER_NS::IRenderNode::ExecuteFlags GetExecuteFlags() const override;
63 void Init(const RENDER_NS::IRenderPostProcess::Ptr& postProcess,
64 RENDER_NS::IRenderNodeContextManager& renderNodeContextMgr) override;
65 void PreExecute() override;
66 void Execute(RENDER_NS::IRenderCommandList& cmdList) override;
67
68 void SetCameraData();
69
70 struct NodeInputs {
71 RENDER_NS::BindableImage input;
72 RENDER_NS::BindableImage depth;
73 RENDER_NS::BindableImage velocity;
74 RENDER_NS::BindableImage history;
75 };
76 struct NodeOutputs {
77 RENDER_NS::BindableImage output;
78 };
79
80 NodeInputs nodeInputsData;
81 NodeOutputs nodeOutputsData;
82
83 private:
84 RENDER_NS::IRenderNodeContextManager* renderNodeContextMgr_ { nullptr };
85 RENDER_NS::IRenderPostProcess::Ptr postProcess_;
86
87 // Super resolution functions for each pass
88 void ComputeLuminancePyramid(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
89 void ComputeReconstructAndDilate(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
90 void ComputeDebug(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
91 void ComputeDepthClip(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
92 void ComputeCreateLocks(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
93 void ComputeAccumulate(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
94 void ComputeRcas(const PushConstant& pc, RENDER_NS::IRenderCommandList& cmdList);
95
96 void CreateTargets(const BASE_NS::Math::UVec2 baseSize);
97 void CreatePsos();
98
99 BASE_NS::Math::UVec2 baseSize_ { 0U, 0U };
100
101 // Mip level count for Luminance Pyramid
102 uint32_t mipLevels_ { 1U };
103
104 static constexpr uint32_t TARGET_COUNT { 10U };
105
106 struct Targets {
107 BASE_NS::Math::UVec2 renderResolution { 0U, 0U };
108 BASE_NS::Math::UVec2 displayResolution { 0U, 0U };
109
110 // ---------- Compute Luminance pass textures ----------
111 std::array<RenderHandleReference, TARGET_COUNT> tex1;
112 std::array<BASE_NS::Math::UVec2, TARGET_COUNT> tex1Size;
113
114 // ---------- Dilate and Reconstruct pass textures ----------
115 RenderHandleReference estPrevDepth;
116 RenderHandleReference dilatedDepth;
117
118 // Two textures for ping-ponging history/current dilated motion vectors
119 std::array<RenderHandleReference, 2U> dilatedMotionVectors;
120 uint32_t motionVectorIdx { 0U };
121
122 RenderHandleReference lockInputLuma;
123
124 // ---------- Debug pass textures ----------
125 RenderHandleReference debugImage;
126
127 // ---------- Depth Clip pass textures ----------
128 RenderHandleReference adjustedColorBuffer;
129 RenderHandleReference dilatedReactiveMask;
130
131 // ---------- Create Locks Pass texture ----------
132 RenderHandleReference newLocksMask;
133
134 // ---------- Accumulate Pass History Textures (ping-pong) ----------
135 std::array<RenderHandleReference, 2U> historyColorAndReactive;
136 std::array<RenderHandleReference, 2U> historyLockStatus;
137 std::array<RenderHandleReference, 2U> historyLuma;
138
139 //----------- RCAS pass (optional) -------------
140 RenderHandleReference rcas_final;
141 bool rcas_enabled = false;
142
143 RenderHandleReference finalColor;
144 RenderHandle cameraUbo;
145 uint32_t historyBufferIdx { 0U };
146 };
147 Targets targets_;
148
149 struct PSOs {
150 // Luminance Pyramid pass. Last mip level is 1x1 texture containing exposure (avg luminance)
151 RenderHandle luminanceDownscale;
152 RenderHandle luminancePyramid;
153 RenderHandle reconstructAndDilate;
154 RenderHandle debugPass;
155 RenderHandle depthClipPass;
156 RenderHandle locksPass;
157 RenderHandle accumulatePass;
158 RenderHandle rcasPass;
159
160 ShaderThreadGroup luminanceDownscaleTGS { 1, 1, 1 };
161 ShaderThreadGroup luminancePyramidTGS { 1, 1, 1 };
162 ShaderThreadGroup reconstructAndDilateTGS { 1, 1, 1 };
163 ShaderThreadGroup debugPassTGS { 1, 1, 1 };
164 ShaderThreadGroup depthClipPassTGS { 1, 1, 1 };
165 ShaderThreadGroup locksPassTGS { 1, 1, 1 };
166 ShaderThreadGroup accumulatePassTGS { 1, 1, 1 };
167 ShaderThreadGroup rcasPassTGS { 1, 1, 1 };
168 };
169 PSOs psos_;
170
171 struct Binders {
172 IDescriptorSetBinder::Ptr luminanceDownscale;
173 std::array<IDescriptorSetBinder::Ptr, TARGET_COUNT> luminancePyramid;
174 IDescriptorSetBinder::Ptr reconstructAndDilate;
175 IDescriptorSetBinder::Ptr debugPass;
176 IDescriptorSetBinder::Ptr depthClipPass;
177 IDescriptorSetBinder::Ptr locksPass;
178 IDescriptorSetBinder::Ptr accumulatePass;
179 IDescriptorSetBinder::Ptr rcasPass;
180 };
181 Binders binders_;
182
183 RenderHandleReference samplerHandle_;
184
185 RenderNodeCopyUtil renderCopyOutput_;
186
187 void EvaluateOutput();
188
189 struct LockPassPushConstant {
190 BASE_NS::Math::Vec4 renderSizeInvSize { 0.0f, 0.0f, 0.0f, 0.0f };
191 BASE_NS::Math::Vec4 displaySizeInvSize { 0.0f, 0.0f, 0.0f, 0.0f };
192 };
193
194 struct AccumulatePassPushConstant {
195 BASE_NS::Math::Vec4 displaySizeInvSize { 0.0f, 0.0f, 0.0f, 0.0f };
196 BASE_NS::Math::Vec4 viewportSizeInvSize { 0.0f, 0.0f, 0.0f, 0.0f };
197 float exposure = 1.0f;
198 uint32_t frameIndex = 0; // Current frame count/index
199 uint32_t jitterSequenceLength = 16U;
200 float avgLanczosWeightPerFrame = 1.0f / 16.0f;
201 float maxAccumulationLanczosWeight = 0.98f;
202 };
203
204 RenderAreaRequest renderAreaRequest_;
205 bool useRequestedRenderArea_ { false };
206
207 CORE_NS::PropertyApiImpl<NodeInputs> inputProperties_;
208 CORE_NS::PropertyApiImpl<NodeOutputs> outputProperties_;
209
210 bool valid_ { false };
211
212 EffectProperties effectProperties_;
213 };
214 RENDER_END_NAMESPACE()
215
216 #endif // RENDER_POSTPROCESS_RENDER_POSTPROCESS_UPSCALE_NODE_H
217