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