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 CORE3D_RENDER_NODE_RENDER_NODE_GENERICS_H
17 #define CORE3D_RENDER_NODE_RENDER_NODE_GENERICS_H
18
19 #include <array>
20 #include <tuple>
21
22 #include <3d/render/intf_render_node_scene_util.h>
23 #include <base/containers/allocator.h>
24 #include <base/containers/array_view.h>
25 #include <base/containers/string.h>
26 #include <base/math/float_packer.h>
27 #include <render/device/intf_gpu_resource_manager.h>
28 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
29 #include <render/nodecontext/intf_render_command_list.h>
30 #include <render/nodecontext/intf_render_node_context_manager.h>
31 #include <render/render_data_structures.h>
32
33 struct RenderSize {
34 int32_t w { 0 };
35 int32_t h { 0 };
RenderSizeRenderSize36 constexpr explicit RenderSize(int32_t width, int32_t height) : w(width), h(height) {};
DownscaleRenderSize37 constexpr RenderSize Downscale(int factor)
38 {
39 return RenderSize(w >> factor, h >> factor);
40 }
41 };
42
43 template<typename T>
begin(T & s)44 uint8_t* begin(T& s)
45 {
46 return reinterpret_cast<uint8_t*>(&s);
47 }
48
49 template<typename T>
cbegin(const T & s)50 const uint8_t* cbegin(const T& s)
51 {
52 return reinterpret_cast<const uint8_t*>(&s);
53 }
54
55 template<typename T>
cend(const T & s)56 const uint8_t* cend(const T& s)
57 {
58 return reinterpret_cast<const uint8_t*>(&s) + sizeof(s);
59 }
60
61 struct Pass {
62 const BASE_NS::Math::UVec2 size;
63 RENDER_NS::AttachmentLoadOp op;
64 const RENDER_NS::RenderHandle input;
65 const RENDER_NS::RenderHandle output;
66 const RENDER_NS::RenderHandle depth;
67 const RENDER_NS::RenderHandle sampler;
68
RenderPassPass69 operator RENDER_NS::RenderPass() const
70 {
71 using namespace RENDER_NS;
72 RenderPass rp;
73 rp.renderPassDesc.attachmentCount = 1u;
74 rp.renderPassDesc.attachmentHandles[0u] = output;
75 rp.renderPassDesc.attachments[0u].loadOp = op;
76 rp.renderPassDesc.attachments[0u].clearValue.color = { 0.0f, 0.0f, 0.0f, 0.0f };
77 rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE;
78 rp.renderPassDesc.renderArea = { 0, 0, size.x, size.y };
79 rp.renderPassDesc.subpassCount = 1u;
80 rp.subpassDesc.colorAttachmentCount = 1u;
81 rp.subpassDesc.colorAttachmentIndices[0u] = 0u;
82 rp.subpassStartIndex = 0u;
83 return rp;
84 }
85 };
86
87 struct ExplicitPass {
88 BASE_NS::Math::UVec2 size;
89 RENDER_NS::RenderPass p;
RenderPassExplicitPass90 operator RENDER_NS::RenderPass() const
91 {
92 return p;
93 }
94 };
95
96 struct CommonShaderData {
97 RENDER_NS::RenderHandle shader;
98 RENDER_NS::RenderHandle pipelineLayout;
99 RENDER_NS::RenderHandle pso;
100 RENDER_NS::PipelineLayout pipelineLayoutData;
101 };
102
103 struct GraphicsShaderData : public CommonShaderData {
104 RENDER_NS::RenderHandle graphicsState;
105 };
106
107 struct ComputeShaderData : public CommonShaderData {
108 RENDER_NS::ShaderThreadGroup threadGroupSize;
109 };
110
111 template<typename T>
112 struct PushContant {
113 const T& pc;
114 operator BASE_NS::array_view<const uint8_t>() const
115 {
116 return { reinterpret_cast<const uint8_t*>(&pc), sizeof(pc) };
117 }
118 };
119
120 template<typename T, class U = Pass>
121 struct BlurParams {
122 const CommonShaderData& shader;
123 RENDER_NS::IPipelineDescriptorSetBinder& binder;
124 PushContant<T> pc;
125 U data;
126 };
127
128 struct Guassian {
129 BASE_NS::Math::Vec4 texSizeInvTexSize { 0.0f, 0.0f, 0.0f, 0.0f };
130 BASE_NS::Math::Vec4 dir { 0.0f, 0.0f, 0.0f, 0.0f };
131 std::array<uint32_t, 16U> packed {};
132
StandardWeightsGuassian133 static Guassian StandardWeights() noexcept
134 {
135 using namespace BASE_NS;
136 static constexpr int BLUR_SEPARATE_COUNT = 3;
137 static constexpr float offset[BLUR_SEPARATE_COUNT] = { 0.0f, 1.3846153846f, 3.2307692308f };
138 static constexpr float weight[BLUR_SEPARATE_COUNT] = { 0.2270270270f, 0.3162162162f, 0.0702702703f };
139 std::array<uint32_t, 16> packed = {};
140 for (uint32_t i = 0; i < BLUR_SEPARATE_COUNT; ++i) {
141 packed[i] = Math::PackHalf2X16(Math::Vec2(offset[i], weight[i]));
142 }
143
144 return Guassian { { 3.0f + 0.5f, 0.0f, 0.0f, 0.0f }, {}, packed };
145 }
146 };
147
148 struct RenderNodeMixin {
149 void Load(const BASE_NS::string_view shader, BASE_NS::vector<RENDER_NS::DescriptorCounts>& counts,
150 ComputeShaderData& debugShaderData_, size_t reserved);
151 void Load(const BASE_NS::string_view file, BASE_NS::vector<RENDER_NS::DescriptorCounts>& counts,
152 GraphicsShaderData& debugShaderData_, BASE_NS::array_view<const RENDER_NS::DynamicStateEnum> dynstates,
153 size_t reserved);
154 RENDER_NS::RenderPass CreateRenderPass(const RENDER_NS::RenderHandle input);
155
156 void RecreateImages(RenderSize size, RENDER_NS::RenderHandleReference& handle);
157 void RecreateImages(RenderSize size, RENDER_NS::RenderHandleReference& handle, RENDER_NS::GpuImageDesc desc);
158
159 protected:
160 virtual operator RENDER_NS::IRenderNodeContextManager*() const = 0;
161 virtual ~RenderNodeMixin() = default;
162 };
163
164 template<typename T>
UpdateBufferData(const RENDER_NS::IRenderNodeGpuResourceManager & gpuResourceMgr,RENDER_NS::RenderHandle handle,const T & settings)165 void UpdateBufferData(
166 const RENDER_NS::IRenderNodeGpuResourceManager& gpuResourceMgr, RENDER_NS::RenderHandle handle, const T& settings)
167 {
168 auto view = BASE_NS::array_view(cbegin(settings), cend(settings));
169 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(handle)); data) {
170 BASE_NS::CloneData(data, view.size(), view.data(), view.size());
171 gpuResourceMgr.UnmapBuffer(handle);
172 }
173 }
174
175 #endif // CORE3D_RENDER_NODE_RENDER_NODE_GENERICS_H