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__NODE__RENDER_BLOOM_H
17 #define RENDER_RENDER__NODE__RENDER_BLOOM_H
18 
19 #include <array>
20 
21 #include <base/containers/string.h>
22 #include <base/containers/string_view.h>
23 #include <base/math/vector.h>
24 #include <render/datastore/render_data_store_render_pods.h>
25 #include <render/namespace.h>
26 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
27 #include <render/nodecontext/intf_render_node.h>
28 #include <render/render_data_structures.h>
29 #include <render/resource_handle.h>
30 
RENDER_BEGIN_NAMESPACE()31 RENDER_BEGIN_NAMESPACE()
32 class RenderBloom final {
33 public:
34     RenderBloom() = default;
35     ~RenderBloom() = default;
36 
37     struct BloomInfo {
38         BindableImage input;
39         BindableImage output;
40         RenderHandle globalUbo;
41         bool useCompute { false };
42     };
43 
44     void Init(IRenderNodeContextManager& renderNodeContextMgr, const BloomInfo& bloomInfo);
45     void PreExecute(IRenderNodeContextManager& renderNodeContextMgr, const BloomInfo& bloomInfo,
46         const PostProcessConfiguration& ppConfig);
47     void Execute(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList,
48         const PostProcessConfiguration& ppConfig);
49 
50     DescriptorCounts GetDescriptorCounts() const;
51     // call after PreExecute, to get the output
52     RenderHandle GetFinalTarget() const;
53 
54 private:
55     void ComputeBloom(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList);
56     void ComputeDownscaleAndThreshold(const PushConstant& pc, IRenderCommandList& cmdList);
57     void ComputeDownscale(const PushConstant& pc, IRenderCommandList& cmdList);
58     void ComputeUpscale(const PushConstant& pc, IRenderCommandList& cmdList);
59     void ComputeCombine(const PushConstant& pc, IRenderCommandList& cmdList);
60 
61     void GraphicsBloom(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList);
62 
63     void RenderDownscaleAndThreshold(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList);
64     void RenderDownscale(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList);
65     void RenderUpscale(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList);
66     void RenderCombine(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList);
67 
68     void CreateTargets(IRenderNodeContextManager& renderNodeContextMgr, const BASE_NS::Math::UVec2 baseSize);
69     void CreatePsos(IRenderNodeContextManager& renderNodeContextMgr);
70     void CreateComputePsos(IRenderNodeContextManager& renderNodeContextMgr);
71     void CreateRenderPsos(IRenderNodeContextManager& renderNodeContextMgr);
72     std::pair<RenderHandle, const PipelineLayout&> CreateAndReflectRenderPso(
73         IRenderNodeContextManager& renderNodeContextMgr, const BASE_NS::string_view shader,
74         const RenderPass& renderPass);
75     void UpdateGlobalSet(IRenderCommandList& cmdList);
76 
77     static constexpr uint32_t TARGET_COUNT { 7u };
78     static constexpr uint32_t CORE_BLOOM_QUALITY_LOW { 1u };
79     static constexpr uint32_t CORE_BLOOM_QUALITY_NORMAL { 2u };
80     static constexpr uint32_t CORE_BLOOM_QUALITY_HIGH { 4u };
81     static constexpr int CORE_BLOOM_QUALITY_COUNT { 3u };
82 
83     struct Targets {
84         std::array<RenderHandleReference, TARGET_COUNT> tex1;
85         // separate target needed in graphics bloom upscale
86         std::array<RenderHandleReference, TARGET_COUNT> tex2;
87         std::array<BASE_NS::Math::UVec2, TARGET_COUNT> tex1Size;
88     };
89     Targets targets_;
90 
91     struct PSOs {
92         struct DownscaleHandles {
93             RenderHandle regular;
94             RenderHandle threshold;
95         };
96 
97         std::array<DownscaleHandles, CORE_BLOOM_QUALITY_COUNT> downscaleHandles;
98         std::array<DownscaleHandles, CORE_BLOOM_QUALITY_COUNT> downscaleHandlesCompute;
99 
100         RenderHandle downscaleAndThreshold;
101         RenderHandle downscale;
102         RenderHandle upscale;
103         RenderHandle combine;
104 
105         ShaderThreadGroup downscaleAndThresholdTGS { 1, 1, 1 };
106         ShaderThreadGroup downscaleTGS { 1, 1, 1 };
107         ShaderThreadGroup upscaleTGS { 1, 1, 1 };
108         ShaderThreadGroup combineTGS { 1, 1, 1 };
109     };
110     PSOs psos_;
111 
112     struct Binders {
113         IDescriptorSetBinder::Ptr globalSet0;
114 
115         IDescriptorSetBinder::Ptr downscaleAndThreshold;
116         std::array<IDescriptorSetBinder::Ptr, TARGET_COUNT> downscale;
117         std::array<IDescriptorSetBinder::Ptr, TARGET_COUNT> upscale;
118         IDescriptorSetBinder::Ptr combine;
119     };
120     Binders binders_;
121 
122     BASE_NS::Math::UVec2 baseSize_ { 0u, 0u };
123     BASE_NS::Math::Vec4 bloomParameters_ { 0.0f, 0.0f, 0.0f, 0.0f };
124 
125     RenderHandleReference samplerHandle_;
126     BASE_NS::Format format_ { BASE_NS::Format::BASE_FORMAT_UNDEFINED };
127 
128     ViewportDesc baseViewportDesc_;
129     ScissorDesc baseScissorDesc_;
130 
131     bool bloomEnabled_ { false };
132     BloomInfo bloomInfo_;
133 };
134 RENDER_END_NAMESPACE()
135 
136 #endif // CORE__RENDER__NODE__RENDER_BLOOM_H
137