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 #include "render_node_graph_share_manager.h"
17 
18 #include <cstdint>
19 
20 #include <base/math/mathf.h>
21 #include <render/namespace.h>
22 #include <render/nodecontext/intf_render_node_graph_manager.h>
23 
24 #include "device/gpu_resource_handle_util.h"
25 #include "util/log.h"
26 
27 using namespace BASE_NS;
28 
29 namespace {
30 #if (RENDER_VALIDATION_ENABLED == 1)
31 constexpr size_t A_BIG_TEST_NUMBER { 128U };
32 #endif
33 } // namespace
34 
RENDER_BEGIN_NAMESPACE()35 RENDER_BEGIN_NAMESPACE()
36 void RenderNodeGraphGlobalShareDataManager::BeginFrame()
37 {
38     renderNodes_.clear();
39 }
40 
SetGlobalRenderNodeResources(const string_view nodeName,const array_view<const IRenderNodeGraphShareManager::NamedResource> resources)41 void RenderNodeGraphGlobalShareDataManager::SetGlobalRenderNodeResources(
42     const string_view nodeName, const array_view<const IRenderNodeGraphShareManager::NamedResource> resources)
43 {
44     auto& ref = renderNodes_[nodeName];
45     ref.resources.insert(ref.resources.end(), resources.begin(), resources.end());
46 #if (RENDER_VALIDATION_ENABLED == 1)
47     // BeginFrame() not called?
48     PLUGIN_ASSERT_MSG(ref.resources.size() < A_BIG_TEST_NUMBER,
49         "RENDER_VALIDATION: BeginFrame not called for global share data mgr?");
50 #endif
51 }
52 
53 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetGlobalRenderNodeResources(const string_view nodeName) const54 RenderNodeGraphGlobalShareDataManager::GetGlobalRenderNodeResources(const string_view nodeName) const
55 {
56     if (auto iter = renderNodes_.find(nodeName); iter != renderNodes_.cend()) {
57         return iter->second.resources;
58     } else {
59 #if (RENDER_VALIDATION_ENABLED == 1)
60         PLUGIN_LOG_W("RENDER_VALIDATION: No global render node for resources found (%s)", nodeName.data());
61 #endif
62         return {};
63     }
64 }
65 
RenderNodeGraphShareDataManager(const array_view<const RenderNodeGraphOutputResource> rngOutputResources)66 RenderNodeGraphShareDataManager::RenderNodeGraphShareDataManager(
67     const array_view<const RenderNodeGraphOutputResource> rngOutputResources)
68     : rngOutputResources_(rngOutputResources.begin(), rngOutputResources.end())
69 {}
70 
71 // NOTE: needs to have outputs at from which render node they are coming from
BeginFrame(RenderNodeGraphGlobalShareDataManager * rngGlobalShareDataMgr,const RenderNodeGraphShareDataManager * prevRngShareDataMgr,const uint32_t renderNodeCount,const array_view<const IRenderNodeGraphShareManager::NamedResource> inputs,const array_view<const IRenderNodeGraphShareManager::NamedResource> outputs)72 void RenderNodeGraphShareDataManager::BeginFrame(RenderNodeGraphGlobalShareDataManager* rngGlobalShareDataMgr,
73     const RenderNodeGraphShareDataManager* prevRngShareDataMgr, const uint32_t renderNodeCount,
74     const array_view<const IRenderNodeGraphShareManager::NamedResource> inputs,
75     const array_view<const IRenderNodeGraphShareManager::NamedResource> outputs)
76 {
77     rngGlobalShareDataMgr_ = rngGlobalShareDataMgr;
78     prevRngShareDataMgr_ = prevRngShareDataMgr;
79     lockedAccess_ = false;
80 
81     // copy / clear all
82 #if (RENDER_VALIDATION_ENABLED == 1)
83     if ((outputs.size() > 0) && (rngOutputResources_.size() > 0) && (outputs.size() != rngOutputResources_.size())) {
84         // NOTE: render node graph name needed
85         PLUGIN_LOG_ONCE_W("RenderNodeGraphShareDataManager::BeginFrame_output_miss",
86             "RENDER_VALIDATION: given output size missmatch with render node graph outputs.");
87     }
88 #endif
89     const uint32_t outputCount = static_cast<uint32_t>(Math::max(rngOutputResources_.size(), outputs.size()));
90     inOut_ = {};
91     inOut_.inputView = { inOut_.inputs, inputs.size() };
92     inOut_.outputView = { inOut_.outputs, outputCount };
93     inOut_.namedInputView = { inOut_.namedInputs, inputs.size() };
94     inOut_.namedOutputView = { inOut_.namedOutputs, outputCount };
95     for (size_t idx = 0; idx < inOut_.inputView.size(); ++idx) {
96         inOut_.inputView[idx] = inputs[idx].handle;
97         inOut_.namedInputView[idx] = inputs[idx];
98     }
99     for (size_t idx = 0; idx < inOut_.outputView.size(); ++idx) {
100         // NOTE: decision needed for output management
101         if (idx < outputs.size()) {
102             inOut_.outputView[idx] = outputs[idx].handle;
103             inOut_.namedOutputView[idx] = outputs[idx];
104         } else {
105             inOut_.outputView[idx] = {};
106             inOut_.namedOutputView[idx] =
107                 (idx < rngOutputResources_.size())
108                     ? IRenderNodeGraphShareManager::NamedResource { rngOutputResources_[idx].name, {} }
109                     : IRenderNodeGraphShareManager::NamedResource {};
110         }
111     }
112     // NOTE: output map is not cleared
113 
114     renderNodeResources_.resize(renderNodeCount);
115 
116     // clear only view to gpu resource handles
117     for (auto& rnRef : renderNodeResources_) {
118         rnRef.outputs.clear();
119     }
120 }
121 
PrepareExecuteFrame()122 void RenderNodeGraphShareDataManager::PrepareExecuteFrame()
123 {
124     lockedAccess_ = true;
125 }
126 
RegisterRenderNodeOutput(const uint32_t renderNodeIdx,const string_view name,const RenderHandle & handle)127 void RenderNodeGraphShareDataManager::RegisterRenderNodeOutput(
128     const uint32_t renderNodeIdx, const string_view name, const RenderHandle& handle)
129 {
130     if (lockedAccess_) {
131 #if (RENDER_VALIDATION_ENABLED == 1)
132         PLUGIN_LOG_ONCE_W(
133             "RegisterRenderNodeOutput_val", "RENDER_VALIDATION: outputs cannot be registered in ExecuteFrame()");
134 #endif
135         return; // early out
136     }
137 
138     PLUGIN_ASSERT(renderNodeIdx < static_cast<uint32_t>(renderNodeResources_.size()));
139     auto& rnRef = renderNodeResources_[renderNodeIdx];
140     if (rnRef.outputs.size() >= MAX_RENDER_NODE_GRAPH_RES_COUNT) {
141 #if (RENDER_VALIDATION_ENABLED == 1)
142         PLUGIN_LOG_ONCE_W("RegisterRenderNodeOutput_valcount", "RENDER_VALIDATION: only %u outputs supported",
143             MAX_RENDER_NODE_GRAPH_RES_COUNT);
144 #endif
145         return; // early out
146     }
147 
148     if (RenderHandleUtil::IsValid(handle)) {
149         // check if render node output is used as render graph output as well
150         RegisterAsRenderNodeGraphOutput(renderNodeIdx, name, handle);
151         rnRef.outputs.push_back(IRenderNodeGraphShareManager::NamedResource { name, handle });
152     } else {
153 #if (RENDER_VALIDATION_ENABLED == 1)
154         PLUGIN_LOG_ONCE_W(string(rnRef.name + name) + string("_invha"),
155             "RENDER_VALIDATION: invalid handle registered as render node output (name: %s) (render node name: %s)",
156             name.data(), rnRef.name.data());
157 #endif
158     }
159 }
160 
RegisterAsRenderNodeGraphOutput(const uint32_t renderNodeIdx,const string_view name,const RenderHandle & handle)161 void RenderNodeGraphShareDataManager::RegisterAsRenderNodeGraphOutput(
162     const uint32_t renderNodeIdx, const string_view name, const RenderHandle& handle)
163 {
164     if (name.empty()) {
165         return;
166     }
167 
168     bool rnNeedsMap = false;
169     // check if render node index matches the map list first
170     const uint32_t outputCount = static_cast<uint32_t>(inOut_.outputView.size());
171     for (uint32_t idx = 0; idx < outputCount; ++idx) {
172         if (outputMap_[idx] == renderNodeIdx) {
173             rnNeedsMap = true;
174             break;
175         }
176     }
177     if (rnNeedsMap) {
178         // do string match if this specific render node output is used as render graph output as well
179         for (uint32_t idx = 0; idx < outputCount; ++idx) {
180             if (inOut_.namedOutputView[idx].name == name) {
181                 inOut_.namedOutputView[idx].handle = handle;
182                 break;
183             }
184         }
185     }
186 }
187 
RegisterRenderNodeName(const uint32_t renderNodeIdx,const string_view name,const string_view globalUniqueName)188 void RenderNodeGraphShareDataManager::RegisterRenderNodeName(
189     const uint32_t renderNodeIdx, const string_view name, const string_view globalUniqueName)
190 {
191     PLUGIN_ASSERT(renderNodeIdx < static_cast<uint32_t>(renderNodeResources_.size()));
192     renderNodeResources_[renderNodeIdx].name = name;
193     renderNodeResources_[renderNodeIdx].globalUniqueName = globalUniqueName;
194     // add render node index to easier mapping and checking without string comparison
195     const uint32_t maxCount =
196         Math::min(static_cast<uint32_t>(rngOutputResources_.size()), MAX_RENDER_NODE_GRAPH_RES_COUNT);
197     for (uint32_t idx = 0; idx < maxCount; ++idx) {
198         const auto& rngOutputRef = rngOutputResources_[idx];
199         if (rngOutputRef.nodeName == name) {
200             outputMap_[idx] = renderNodeIdx;
201         }
202     }
203 }
204 
GetRenderNodeGraphInputs() const205 array_view<const RenderHandle> RenderNodeGraphShareDataManager::GetRenderNodeGraphInputs() const
206 {
207     return inOut_.inputView;
208 }
209 
210 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetNamedRenderNodeGraphInputs() const211 RenderNodeGraphShareDataManager::GetNamedRenderNodeGraphInputs() const
212 {
213     return inOut_.namedInputView;
214 }
215 
GetRenderNodeGraphOutputs() const216 array_view<const RenderHandle> RenderNodeGraphShareDataManager::GetRenderNodeGraphOutputs() const
217 {
218     return inOut_.outputView;
219 }
220 
221 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetNamedRenderNodeGraphOutputs() const222 RenderNodeGraphShareDataManager::GetNamedRenderNodeGraphOutputs() const
223 {
224     return inOut_.namedOutputView;
225 }
226 
GetRenderNodeOutputs(const uint32_t renderNodeIdx) const227 array_view<const IRenderNodeGraphShareManager::NamedResource> RenderNodeGraphShareDataManager::GetRenderNodeOutputs(
228     const uint32_t renderNodeIdx) const
229 {
230     if (renderNodeIdx < static_cast<uint32_t>(renderNodeResources_.size())) {
231         return renderNodeResources_[renderNodeIdx].outputs;
232     }
233     return {};
234 }
235 
GetRenderNodeIndex(const string_view renderNodeName) const236 uint32_t RenderNodeGraphShareDataManager::GetRenderNodeIndex(const string_view renderNodeName) const
237 {
238     for (uint32_t idx = 0; idx < static_cast<uint32_t>(renderNodeResources_.size()); ++idx) {
239         if (renderNodeName == renderNodeResources_[idx].name.data()) {
240             return idx;
241         }
242     }
243     return ~0u;
244 }
245 
GetPrevRenderNodeGraphOutputs() const246 array_view<const RenderHandle> RenderNodeGraphShareDataManager::GetPrevRenderNodeGraphOutputs() const
247 {
248     if (prevRngShareDataMgr_) {
249         return prevRngShareDataMgr_->GetRenderNodeGraphOutputs();
250     } else {
251         return {};
252     }
253 }
254 
RegisterGlobalRenderNodeOutput(const uint32_t renderNodeIdx,const BASE_NS::string_view name,const RenderHandle & handle)255 void RenderNodeGraphShareDataManager::RegisterGlobalRenderNodeOutput(
256     const uint32_t renderNodeIdx, const BASE_NS::string_view name, const RenderHandle& handle)
257 {
258     if (lockedAccess_) {
259 #if (RENDER_VALIDATION_ENABLED == 1)
260         PLUGIN_LOG_ONCE_W(
261             "RegisterGlobalRenderNodeOutput_val", "RENDER_VALIDATION: outputs cannot be registered in ExecuteFrame()");
262 #endif
263         return; // early out
264     }
265 
266     if (rngGlobalShareDataMgr_ && (renderNodeIdx < static_cast<uint32_t>(renderNodeResources_.size()))) {
267         const IRenderNodeGraphShareManager::NamedResource namedResource { name, handle };
268         // NOTE: global unique name
269         rngGlobalShareDataMgr_->SetGlobalRenderNodeResources(
270             renderNodeResources_[renderNodeIdx].globalUniqueName, { &namedResource, 1U });
271     }
272 }
273 
274 BASE_NS::array_view<const IRenderNodeGraphShareManager::NamedResource>
GetGlobalRenderNodeResources(const BASE_NS::string_view nodeName) const275 RenderNodeGraphShareDataManager::GetGlobalRenderNodeResources(const BASE_NS::string_view nodeName) const
276 {
277     if (rngGlobalShareDataMgr_) {
278         return rngGlobalShareDataMgr_->GetGlobalRenderNodeResources(nodeName);
279     } else {
280         return {};
281     }
282 }
283 
284 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetNamedPrevRenderNodeGraphOutputs() const285 RenderNodeGraphShareDataManager::GetNamedPrevRenderNodeGraphOutputs() const
286 {
287     if (prevRngShareDataMgr_) {
288         return prevRngShareDataMgr_->GetNamedRenderNodeGraphOutputs();
289     } else {
290         return {};
291     }
292 }
293 
RenderNodeGraphShareManager(RenderNodeGraphShareDataManager & renderNodeGraphShareDataMgr)294 RenderNodeGraphShareManager::RenderNodeGraphShareManager(RenderNodeGraphShareDataManager& renderNodeGraphShareDataMgr)
295     : renderNodeGraphShareDataMgr_(renderNodeGraphShareDataMgr)
296 {}
297 
298 RenderNodeGraphShareManager::~RenderNodeGraphShareManager() = default;
299 
Init(const uint32_t renderNodeIdx,const string_view name,const string_view globalUniqueName)300 void RenderNodeGraphShareManager::Init(
301     const uint32_t renderNodeIdx, const string_view name, const string_view globalUniqueName)
302 {
303     renderNodeIdx_ = renderNodeIdx;
304     renderNodeGraphShareDataMgr_.RegisterRenderNodeName(renderNodeIdx_, name, globalUniqueName);
305 }
306 
BeginFrame(const uint32_t renderNodeIdx)307 void RenderNodeGraphShareManager::BeginFrame(const uint32_t renderNodeIdx)
308 {
309     renderNodeIdx_ = renderNodeIdx;
310 }
311 
GetRenderNodeGraphInputs() const312 array_view<const RenderHandle> RenderNodeGraphShareManager::GetRenderNodeGraphInputs() const
313 {
314     return renderNodeGraphShareDataMgr_.GetRenderNodeGraphInputs();
315 }
316 
317 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetNamedRenderNodeGraphInputs() const318 RenderNodeGraphShareManager::GetNamedRenderNodeGraphInputs() const
319 {
320     return renderNodeGraphShareDataMgr_.GetNamedRenderNodeGraphInputs();
321 }
322 
GetRenderNodeGraphOutputs() const323 array_view<const RenderHandle> RenderNodeGraphShareManager::GetRenderNodeGraphOutputs() const
324 {
325     return renderNodeGraphShareDataMgr_.GetRenderNodeGraphOutputs();
326 }
327 
328 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetNamedRenderNodeGraphOutputs() const329 RenderNodeGraphShareManager::GetNamedRenderNodeGraphOutputs() const
330 {
331     return renderNodeGraphShareDataMgr_.GetNamedRenderNodeGraphOutputs();
332 }
333 
GetRenderNodeGraphInput(const uint32_t index) const334 RenderHandle RenderNodeGraphShareManager::GetRenderNodeGraphInput(const uint32_t index) const
335 {
336     const auto& ref = renderNodeGraphShareDataMgr_.GetRenderNodeGraphInputs();
337     return (index < ref.size()) ? ref[index] : RenderHandle {};
338 }
339 
GetRenderNodeGraphOutput(const uint32_t index) const340 RenderHandle RenderNodeGraphShareManager::GetRenderNodeGraphOutput(const uint32_t index) const
341 {
342     const auto& ref = renderNodeGraphShareDataMgr_.GetRenderNodeGraphOutputs();
343     return (index < ref.size()) ? ref[index] : RenderHandle {};
344 }
345 
GetPrevRenderNodeGraphOutputs() const346 array_view<const RenderHandle> RenderNodeGraphShareManager::GetPrevRenderNodeGraphOutputs() const
347 {
348     return renderNodeGraphShareDataMgr_.GetPrevRenderNodeGraphOutputs();
349 }
350 
351 array_view<const IRenderNodeGraphShareManager::NamedResource>
GetNamedPrevRenderNodeGraphOutputs() const352 RenderNodeGraphShareManager::GetNamedPrevRenderNodeGraphOutputs() const
353 {
354     return renderNodeGraphShareDataMgr_.GetNamedPrevRenderNodeGraphOutputs();
355 }
356 
GetPrevRenderNodeGraphOutput(const uint32_t index) const357 RenderHandle RenderNodeGraphShareManager::GetPrevRenderNodeGraphOutput(const uint32_t index) const
358 {
359     const auto& ref = renderNodeGraphShareDataMgr_.GetPrevRenderNodeGraphOutputs();
360     return (index < ref.size()) ? ref[index] : RenderHandle {};
361 }
362 
GetNamedPrevRenderNodeGraphOutput(const string_view resourceName) const363 RenderHandle RenderNodeGraphShareManager::GetNamedPrevRenderNodeGraphOutput(const string_view resourceName) const
364 {
365     const auto& ref = renderNodeGraphShareDataMgr_.GetNamedPrevRenderNodeGraphOutputs();
366     for (const auto& resRef : ref) {
367         if (resRef.name == resourceName) {
368             return resRef.handle;
369         }
370     }
371     return RenderHandle {};
372 }
373 
RegisterRenderNodeOutputs(const array_view<const RenderHandle> outputs)374 void RenderNodeGraphShareManager::RegisterRenderNodeOutputs(const array_view<const RenderHandle> outputs)
375 {
376 #if (RENDER_VALIDATION_ENABLED == 1)
377     if (outputs.size() > RenderNodeGraphShareDataManager::MAX_RENDER_NODE_GRAPH_RES_COUNT) {
378         PLUGIN_LOG_W("RENDER_VALIDATION: render node tries to register %u outputs (max count: %u)",
379             static_cast<uint32_t>(outputs.size()), RenderNodeGraphShareDataManager::MAX_RENDER_NODE_GRAPH_RES_COUNT);
380     }
381 #endif
382     for (const auto& ref : outputs) {
383         renderNodeGraphShareDataMgr_.RegisterRenderNodeOutput(renderNodeIdx_, {}, ref);
384     }
385 }
386 
RegisterRenderNodeOutput(const string_view name,const RenderHandle & handle)387 void RenderNodeGraphShareManager::RegisterRenderNodeOutput(const string_view name, const RenderHandle& handle)
388 {
389     renderNodeGraphShareDataMgr_.RegisterRenderNodeOutput(renderNodeIdx_, name, handle);
390 }
391 
GetRegisteredRenderNodeOutput(const string_view renderNodeName,const uint32_t index) const392 RenderHandle RenderNodeGraphShareManager::GetRegisteredRenderNodeOutput(
393     const string_view renderNodeName, const uint32_t index) const
394 {
395     const uint32_t rnIdx = renderNodeGraphShareDataMgr_.GetRenderNodeIndex(renderNodeName);
396     const auto& ref = renderNodeGraphShareDataMgr_.GetRenderNodeOutputs(rnIdx);
397     return (index < ref.size()) ? ref[index].handle : RenderHandle {};
398 }
399 
GetRegisteredRenderNodeOutput(const string_view renderNodeName,const string_view resourceName) const400 RenderHandle RenderNodeGraphShareManager::GetRegisteredRenderNodeOutput(
401     const string_view renderNodeName, const string_view resourceName) const
402 {
403     const uint32_t rnIdx = renderNodeGraphShareDataMgr_.GetRenderNodeIndex(renderNodeName);
404     const auto& ref = renderNodeGraphShareDataMgr_.GetRenderNodeOutputs(rnIdx);
405     // check for name from the resources
406     for (const auto& r : ref) {
407         if (r.name == resourceName) {
408             return r.handle;
409         }
410     }
411     return RenderHandle {};
412 }
413 
GetRegisteredPrevRenderNodeOutput(const uint32_t index) const414 RenderHandle RenderNodeGraphShareManager::GetRegisteredPrevRenderNodeOutput(const uint32_t index) const
415 {
416     const uint32_t rnIdx = renderNodeIdx_ - 1u;
417     const auto& ref = renderNodeGraphShareDataMgr_.GetRenderNodeOutputs(rnIdx);
418     return (index < ref.size()) ? ref[index].handle : RenderHandle {};
419 }
420 
RegisterGlobalRenderNodeOutput(const BASE_NS::string_view name,const RenderHandle & handle)421 void RenderNodeGraphShareManager::RegisterGlobalRenderNodeOutput(
422     const BASE_NS::string_view name, const RenderHandle& handle)
423 {
424     renderNodeGraphShareDataMgr_.RegisterGlobalRenderNodeOutput(renderNodeIdx_, name, handle);
425 }
426 
427 BASE_NS::array_view<const IRenderNodeGraphShareManager::NamedResource>
GetRegisteredGlobalRenderNodeOutputs(const BASE_NS::string_view nodeName) const428 RenderNodeGraphShareManager::GetRegisteredGlobalRenderNodeOutputs(const BASE_NS::string_view nodeName) const
429 {
430     return renderNodeGraphShareDataMgr_.GetGlobalRenderNodeResources(nodeName);
431 }
432 
GetInterface(const BASE_NS::Uid & uid) const433 const CORE_NS::IInterface* RenderNodeGraphShareManager::GetInterface(const BASE_NS::Uid& uid) const
434 {
435     if ((uid == IRenderNodeGraphShareManager::UID) || (uid == IInterface::UID)) {
436         return this;
437     }
438     return nullptr;
439 }
440 
GetInterface(const BASE_NS::Uid & uid)441 CORE_NS::IInterface* RenderNodeGraphShareManager::GetInterface(const BASE_NS::Uid& uid)
442 {
443     if ((uid == IRenderNodeGraphShareManager::UID) || (uid == IInterface::UID)) {
444         return this;
445     }
446     return nullptr;
447 }
448 
Ref()449 void RenderNodeGraphShareManager::Ref() {}
450 
Unref()451 void RenderNodeGraphShareManager::Unref() {}
452 RENDER_END_NAMESPACE()
453