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_create_gpu_buffers.h"
17 
18 #include <render/device/intf_gpu_resource_manager.h>
19 #include <render/namespace.h>
20 #include <render/nodecontext/intf_render_command_list.h>
21 #include <render/nodecontext/intf_render_node_context_manager.h>
22 #include <render/nodecontext/intf_render_node_graph_share_manager.h>
23 #include <render/nodecontext/intf_render_node_parser_util.h>
24 #include <render/render_data_structures.h>
25 
26 #include "util/log.h"
27 
28 using namespace BASE_NS;
29 
30 RENDER_BEGIN_NAMESPACE()
31 namespace {
CheckForDescUpdates(const GpuBufferDesc & dependencyDesc,GpuBufferDesc & desc)32 bool CheckForDescUpdates(const GpuBufferDesc& dependencyDesc, GpuBufferDesc& desc)
33 {
34     bool needsUpdate = (dependencyDesc.byteSize != desc.byteSize);
35     needsUpdate = needsUpdate || (dependencyDesc.usageFlags != desc.usageFlags);
36     needsUpdate = needsUpdate || (dependencyDesc.memoryPropertyFlags != desc.memoryPropertyFlags);
37     needsUpdate = needsUpdate || (dependencyDesc.engineCreationFlags != desc.engineCreationFlags);
38     needsUpdate = needsUpdate || (dependencyDesc.format != desc.format);
39     if (needsUpdate) {
40         desc = dependencyDesc;
41     }
42     return needsUpdate;
43 }
44 } // namespace
45 
InitNode(IRenderNodeContextManager & renderNodeContextMgr)46 void RenderNodeCreateGpuBuffers::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
47 {
48     renderNodeContextMgr_ = &renderNodeContextMgr;
49     ParseRenderNodeInputs();
50 
51     if (jsonInputs_.gpuBufferDescs.empty()) {
52         PLUGIN_LOG_W("RenderNodeCreateGpuBuffers: No gpu buffer descs given");
53     }
54 
55     auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager();
56     descs_.reserve(jsonInputs_.gpuBufferDescs.size());
57     for (const auto& ref : jsonInputs_.gpuBufferDescs) {
58         GpuBufferDesc desc = ref.desc;
59 
60         RenderHandle dependencyHandle;
61         if (!ref.dependencyBufferName.empty()) {
62             dependencyHandle = gpuResourceMgr.GetBufferHandle(ref.dependencyBufferName);
63             if (RenderHandleUtil::IsValid(dependencyHandle)) {
64                 const GpuBufferDesc dependencyDesc = gpuResourceMgr.GetBufferDescriptor(dependencyHandle);
65 
66                 // update desc
67                 CheckForDescUpdates(dependencyDesc, desc);
68             } else {
69                 PLUGIN_LOG_E("GpuBuffer dependency name not found: %s", ref.dependencyBufferName.c_str());
70             }
71         }
72         dependencyHandles_.push_back(dependencyHandle);
73 
74         names_.push_back({ string(ref.name), string(ref.shareName) });
75         descs_.push_back(desc);
76         resourceHandles_.push_back(gpuResourceMgr.Create(ref.name, desc));
77     }
78 
79     // broadcast the resources
80     for (size_t idx = 0; idx < resourceHandles_.size(); ++idx) {
81         IRenderNodeGraphShareManager& rngShareMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
82         rngShareMgr.RegisterRenderNodeOutput(names_[idx].shareName, resourceHandles_[idx].GetHandle());
83     }
84 }
85 
PreExecuteFrame()86 void RenderNodeCreateGpuBuffers::PreExecuteFrame()
87 {
88     auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
89     for (size_t idx = 0; idx < resourceHandles_.size(); ++idx) {
90         const RenderHandle dependencyHandle = dependencyHandles_[idx];
91         if (gpuResourceMgr.IsValid(dependencyHandle)) {
92             const GpuBufferDesc& dependencyDesc = gpuResourceMgr.GetBufferDescriptor(dependencyHandle);
93             GpuBufferDesc& descRef = descs_[idx];
94 
95             const bool recreateBuffer = CheckForDescUpdates(dependencyDesc, descRef);
96             if (recreateBuffer) {
97                 // replace the handle
98                 resourceHandles_[idx] = gpuResourceMgr.Create(resourceHandles_[idx], descRef);
99             }
100         }
101     }
102 
103     // broadcast the resources
104     for (size_t idx = 0; idx < resourceHandles_.size(); ++idx) {
105         IRenderNodeGraphShareManager& rngShareMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
106         rngShareMgr.RegisterRenderNodeOutput(names_[idx].shareName, resourceHandles_[idx].GetHandle());
107     }
108 }
109 
ParseRenderNodeInputs()110 void RenderNodeCreateGpuBuffers::ParseRenderNodeInputs()
111 {
112     const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
113     const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
114     jsonInputs_.gpuBufferDescs = parserUtil.GetGpuBufferDescs(jsonVal, "gpuBufferDescs");
115 }
116 
117 // for plugin / factory interface
Create()118 IRenderNode* RenderNodeCreateGpuBuffers::Create()
119 {
120     return new RenderNodeCreateGpuBuffers();
121 }
122 
Destroy(IRenderNode * instance)123 void RenderNodeCreateGpuBuffers::Destroy(IRenderNode* instance)
124 {
125     delete static_cast<RenderNodeCreateGpuBuffers*>(instance);
126 }
127 RENDER_END_NAMESPACE()
128