1 /*
2 * Copyright (C) 2023 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_node_bloom.h"
17
18 #include <base/math/vector.h>
19 #include <render/datastore/intf_render_data_store_manager.h>
20 #include <render/datastore/intf_render_data_store_pod.h>
21 #include <render/datastore/render_data_store_render_pods.h>
22 #include <render/device/intf_gpu_resource_manager.h>
23 #include <render/namespace.h>
24 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
25 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
26 #include <render/nodecontext/intf_render_command_list.h>
27 #include <render/nodecontext/intf_render_node_context_manager.h>
28 #include <render/nodecontext/intf_render_node_parser_util.h>
29 #include <render/nodecontext/intf_render_node_util.h>
30
31 #include "util/log.h"
32
33 // shaders
34 #include <render/shaders/common/render_post_process_structs_common.h>
35
36 using namespace BASE_NS;
37
38 RENDER_BEGIN_NAMESPACE()
39 namespace {
40 constexpr uint32_t UBO_OFFSET_ALIGNMENT { PipelineLayoutConstants::MIN_UBO_BIND_OFFSET_ALIGNMENT_BYTE_SIZE };
41 constexpr uint32_t MAX_POST_PROCESS_EFFECT_COUNT { 2 };
42
CreatePostProcessDataUniformBuffer(IRenderNodeGpuResourceManager & gpuResourceMgr,const RenderHandleReference & handle)43 RenderHandleReference CreatePostProcessDataUniformBuffer(
44 IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandleReference& handle)
45 {
46 PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == UBO_OFFSET_ALIGNMENT);
47 PLUGIN_STATIC_ASSERT(sizeof(LocalPostProcessStruct) == UBO_OFFSET_ALIGNMENT);
48 return gpuResourceMgr.Create(handle,
49 GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
50 (CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT),
51 CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, UBO_OFFSET_ALIGNMENT * MAX_POST_PROCESS_EFFECT_COUNT });
52 }
53 } // namespace
54
InitNode(IRenderNodeContextManager & renderNodeContextMgr)55 void RenderNodeBloom::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
56 {
57 renderNodeContextMgr_ = &renderNodeContextMgr;
58 ParseRenderNodeInputs();
59
60 if (jsonInputs_.renderDataStore.dataStoreName.empty()) {
61 PLUGIN_LOG_E("RenderNodeBloom: render data store configuration not set in render node graph");
62 }
63
64 postProcessUbo_ =
65 CreatePostProcessDataUniformBuffer(renderNodeContextMgr_->GetGpuResourceManager(), postProcessUbo_);
66
67 ProcessPostProcessConfiguration(renderNodeContextMgr_->GetRenderDataStoreManager());
68 renderNodeContextMgr.GetDescriptorSetManager().ResetAndReserve(renderBloom_.GetDescriptorCounts());
69 const RenderBloom::BloomInfo info { inputResources_.customInputImages[0].handle,
70 inputResources_.customOutputImages[0].handle, postProcessUbo_.GetHandle(),
71 ppConfig_.bloomConfiguration.useCompute };
72 renderBloom_.Init(renderNodeContextMgr, info);
73 }
74
PreExecuteFrame()75 void RenderNodeBloom::PreExecuteFrame()
76 {
77 const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
78 if (jsonInputs_.hasChangeableResourceHandles) {
79 inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources);
80 }
81 ProcessPostProcessConfiguration(renderNodeContextMgr_->GetRenderDataStoreManager());
82 UpdatePostProcessData(ppConfig_);
83
84 const RenderBloom::BloomInfo info { inputResources_.customInputImages[0].handle,
85 inputResources_.customOutputImages[0].handle, postProcessUbo_.GetHandle(),
86 ppConfig_.bloomConfiguration.useCompute };
87 renderBloom_.PreExecute(*renderNodeContextMgr_, info, ppConfig_);
88 }
89
ExecuteFrame(IRenderCommandList & cmdList)90 void RenderNodeBloom::ExecuteFrame(IRenderCommandList& cmdList)
91 {
92 renderBloom_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_);
93 }
94
ProcessPostProcessConfiguration(const IRenderNodeRenderDataStoreManager & dataStoreMgr)95 void RenderNodeBloom::ProcessPostProcessConfiguration(const IRenderNodeRenderDataStoreManager& dataStoreMgr)
96 {
97 if (!jsonInputs_.renderDataStore.dataStoreName.empty()) {
98 auto const dataStore = static_cast<IRenderDataStorePod const*>(
99 dataStoreMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName));
100 if (dataStore) {
101 auto const dataView = dataStore->Get(jsonInputs_.renderDataStore.configurationName);
102 if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) {
103 ppConfig_ = *((const PostProcessConfiguration*)dataView.data());
104 }
105 }
106 }
107 }
108
ParseRenderNodeInputs()109 void RenderNodeBloom::ParseRenderNodeInputs()
110 {
111 const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
112 const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
113 jsonInputs_.resources = parserUtil.GetInputResources(jsonVal, "resources");
114 jsonInputs_.renderDataStore = parserUtil.GetRenderDataStore(jsonVal, "renderDataStore");
115
116 const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
117 inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources);
118 }
119
UpdatePostProcessData(const PostProcessConfiguration & postProcessConfiguration)120 void RenderNodeBloom::UpdatePostProcessData(const PostProcessConfiguration& postProcessConfiguration)
121 {
122 auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
123 const RenderPostProcessConfiguration rppc =
124 renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(postProcessConfiguration);
125 PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration));
126 if (auto data = reinterpret_cast<uint8_t*>(gpuResourceMgr.MapBuffer(postProcessUbo_.GetHandle())); data) {
127 const auto* dataEnd = data + sizeof(RenderPostProcessConfiguration);
128 if (!CloneData(data, size_t(dataEnd - data), &rppc, sizeof(RenderPostProcessConfiguration))) {
129 PLUGIN_LOG_E("post process ubo copying failed.");
130 }
131 gpuResourceMgr.UnmapBuffer(postProcessUbo_.GetHandle());
132 }
133 }
134
135 // for plugin / factory interface
Create()136 IRenderNode* RenderNodeBloom::Create()
137 {
138 return new RenderNodeBloom();
139 }
140
Destroy(IRenderNode * instance)141 void RenderNodeBloom::Destroy(IRenderNode* instance)
142 {
143 delete static_cast<RenderNodeBloom*>(instance);
144 }
145 RENDER_END_NAMESPACE()
146