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 #ifndef RENDER_RENDER__RENDER_NODE_POST_PROCESS_UTIL_H
17 #define RENDER_RENDER__RENDER_NODE_POST_PROCESS_UTIL_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/array_view.h>
22 #include <render/datastore/render_data_store_render_pods.h>
23 #include <render/device/pipeline_state_desc.h>
24 #include <render/namespace.h>
25 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
26 #include <render/nodecontext/intf_render_node_post_process_util.h>
27 #include <render/render_data_structures.h>
28 
29 #include "node/render_bloom.h"
30 #include "node/render_blur.h"
31 #include "node/render_copy.h"
32 #include "node/render_motion_blur.h"
33 
34 RENDER_BEGIN_NAMESPACE()
35 struct RenderableList;
36 struct PipelineLayout;
37 class IRenderNodeContextManager;
38 class IRenderNodeCommandList;
39 
40 class RenderNodePostProcessUtil final {
41 public:
42     RenderNodePostProcessUtil() = default;
43     ~RenderNodePostProcessUtil() = default;
44 
45     void Init(IRenderNodeContextManager& renderNodeContextMgr,
46         const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo);
47     void PreExecute(const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo);
48     void Execute(IRenderCommandList& cmdList);
49 
50 private:
51     IRenderNodeContextManager* renderNodeContextMgr_;
52 
53     void ParseRenderNodeInputs();
54     void UpdateImageData();
55 
56     void UpdatePostProcessData(const PostProcessConfiguration& postProcessConfiguration);
57     void ProcessPostProcessConfiguration();
58     void InitCreateShaderResources();
59     void InitCreateBinders();
60 
61     struct InputOutput {
62         BindableImage input;
63         BindableImage output;
64     };
65     void ExecuteCombine(IRenderCommandList& cmdList, const InputOutput& inOut);
66     void ExecuteFXAA(IRenderCommandList& cmdList, const InputOutput& inOut);
67     void ExecuteBlit(IRenderCommandList& cmdList, const InputOutput& inOut);
68     void ExecuteTAA(IRenderCommandList& cmdList, const InputOutput& inOut);
69     void ExecuteDofBlur(IRenderCommandList& cmdList, const InputOutput& inOut);
70     void ExecuteDof(IRenderCommandList& cmdList, const InputOutput& inOut);
71 
72     // Json resources which might need re-fetching
73     struct JsonInputs {
74         RenderNodeGraphInputs::InputResources resources;
75         RenderNodeGraphInputs::RenderDataStore renderDataStore;
76         bool hasChangeableResourceHandles { false };
77 
78         uint32_t colorIndex { ~0u };
79         uint32_t depthIndex { ~0u };
80         uint32_t velocityIndex { ~0u };
81         uint32_t historyIndex { ~0u };
82         uint32_t historyNextIndex { ~0u };
83     };
84     JsonInputs jsonInputs_;
85     RenderNodeHandles::InputResources inputResources_;
86 
87     struct EffectData {
88         RenderHandle shader;
89         RenderHandle pl;
90         RenderHandle pso;
91 
92         PipelineLayout pipelineLayout;
93     };
94     EffectData fxaaData_;
95     EffectData taaData_;
96     EffectData dofBlurData_;
97     EffectData dofData_;
98     EffectData copyData_;
99     EffectData combineData_;
100 
101     RenderBloom renderBloom_;
102     RenderBlur renderBlur_;
103     RenderMotionBlur renderMotionBlur_;
104     RenderCopy renderCopy_;
105     // additional layer copy
106     RenderCopy renderCopyLayer_;
107 
108     RenderBlur renderNearBlur_;
109     RenderBlur renderFarBlur_;
110 
111     struct AdditionalImageData {
112         RenderHandle black;
113         RenderHandle white;
114     };
115     IRenderNodePostProcessUtil::ImageData images_;
116     AdditionalImageData aimg_;
117 
118     IRenderNodePostProcessUtil::PostProcessInfo postProcessInfo_;
119 
120     enum POST_PROCESS_UBO_INDICES {
121         PP_TAA_IDX = 0U,
122         PP_BLOOM_IDX,
123         PP_BLUR_IDX,
124         PP_FXAA_IDX,
125         PP_COMBINED_IDX,
126         PP_DOF_IDX,
127         PP_MB_IDX,
128         PP_COUNT_IDX,
129     };
130 
131     struct UboHandles {
132         // first 512 aligned is global post process
133         // after (256) we have effect local data
134         RenderHandleReference postProcess;
135     };
136     UboHandles ubos_;
137 
138     BASE_NS::Math::UVec2 outputSize_ { 0U, 0U };
139 
140     bool validInputs_ { true };
141     bool validInputsForTaa_ { false };
142     bool validInputsForDof_ { false };
143     bool validInputsForMb_ { false };
144     BASE_NS::vector<InputOutput> framePostProcessInOut_;
145 
146     struct DefaultSamplers {
147         RenderHandle nearest;
148         RenderHandle linear;
149         RenderHandle mipLinear;
150     };
151     DefaultSamplers samplers_;
152     PostProcessConfiguration ppConfig_;
153 
154     struct TemporaryImages {
155         uint32_t idx = 0U;
156         uint32_t imageCount = 0U;
157         uint32_t mipIdx = 0U;
158         uint32_t mipImageCount = 0U;
159         RenderHandleReference images[2U];
160         RenderHandleReference mipImages[2U];
161         BASE_NS::Math::Vec4 targetSize { 0.0f, 0.0f, 0.0f, 0.0f };
162         uint32_t mipCount[2U];
163 
164         RenderHandleReference layerCopyImage;
165     };
166     TemporaryImages ti_;
GetIntermediateImage(const RenderHandle & input)167     BindableImage GetIntermediateImage(const RenderHandle& input)
168     {
169         if (ti_.imageCount == 0U) {
170             return {};
171         }
172         if (input == ti_.images[ti_.idx].GetHandle()) {
173             ti_.idx = (ti_.idx + 1) % static_cast<uint32_t>(ti_.imageCount);
174         }
175         return { ti_.images[ti_.idx].GetHandle() };
176     }
GetMipImage(const RenderHandle & input)177     BindableImage GetMipImage(const RenderHandle& input)
178     {
179         if (ti_.mipImageCount == 0U) {
180             return {};
181         }
182         if (input == ti_.mipImages[ti_.mipIdx].GetHandle()) {
183             ti_.mipIdx = (ti_.mipIdx + 1) % static_cast<uint32_t>(ti_.mipImageCount);
184         }
185         return { ti_.mipImages[ti_.mipIdx].GetHandle() };
186     }
187 
188     struct AllBinders {
189         IDescriptorSetBinder::Ptr globalSet0[POST_PROCESS_UBO_INDICES::PP_COUNT_IDX];
190 
191         IDescriptorSetBinder::Ptr combineBinder;
192         IDescriptorSetBinder::Ptr taaBinder;
193         IDescriptorSetBinder::Ptr fxaaBinder;
194         IDescriptorSetBinder::Ptr dofBlurBinder;
195         IDescriptorSetBinder::Ptr dofBinder;
196 
197         IDescriptorSetBinder::Ptr copyBinder;
198     };
199     AllBinders binders_;
200 
201     DeviceBackendType deviceBackendType_ { DeviceBackendType::VULKAN };
202 };
203 
204 class RenderNodePostProcessUtilImpl final : public IRenderNodePostProcessUtil {
205 public:
206     RenderNodePostProcessUtilImpl() = default;
207     ~RenderNodePostProcessUtilImpl() override = default;
208 
209     void Init(IRenderNodeContextManager& renderNodeContextMgr,
210         const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo) override;
211     void PreExecute(const IRenderNodePostProcessUtil::PostProcessInfo& postProcessInfo) override;
212     void Execute(IRenderCommandList& cmdList) override;
213 
214     const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
215     CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override;
216 
217     void Ref() override;
218     void Unref() override;
219 
220 private:
221     RenderNodePostProcessUtil rn_;
222 
223     uint32_t refCount_ { 0U };
224 };
225 RENDER_END_NAMESPACE()
226 
227 #endif // RENDER__RENDER_NODE_POST_PROCESS_UTIL_H
228