• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "render_node_staging.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 
21 #include <render/datastore/intf_render_data_store_manager.h>
22 #include <render/device/intf_gpu_resource_manager.h>
23 #include <render/namespace.h>
24 #include <render/nodecontext/intf_node_context_pso_manager.h>
25 #include <render/nodecontext/intf_render_command_list.h>
26 #include <render/nodecontext/intf_render_node_context_manager.h>
27 
28 #include "datastore/render_data_store_default_staging.h"
29 #include "default_engine_constants.h"
30 #include "util/log.h"
31 
32 using namespace BASE_NS;
33 
34 RENDER_BEGIN_NAMESPACE()
35 namespace {
CopyHostDirectlyToBuffer(const IRenderNodeGpuResourceManager & gpuResourceMgr,const StagingConsumeStruct & stagingConsumeStruct)36 void CopyHostDirectlyToBuffer(
37     const IRenderNodeGpuResourceManager& gpuResourceMgr, const StagingConsumeStruct& stagingConsumeStruct)
38 {
39     for (const auto& ref : stagingConsumeStruct.cpuToBuffer) {
40         if (ref.invalidOperation) {
41             continue;
42         }
43         uint8_t* baseDstDataBegin = static_cast<uint8_t*>(gpuResourceMgr.MapBuffer(ref.dstHandle.GetHandle()));
44         if (!baseDstDataBegin) {
45             PLUGIN_LOG_E("staging: direct dstHandle %" PRIu64, ref.dstHandle.GetHandle().id);
46             return;
47         }
48         auto const& bufferDesc = gpuResourceMgr.GetBufferDescriptor(ref.dstHandle.GetHandle());
49         const uint8_t* baseDstDataEnd = baseDstDataBegin + bufferDesc.byteSize;
50 
51         const auto* baseSrcDataBegin = static_cast<const uint8_t*>(ref.stagingData.data());
52         const uint32_t bufferBeginIndex = ref.beginIndex;
53         const uint32_t bufferEndIndex = bufferBeginIndex + ref.count;
54         for (uint32_t bufferIdx = bufferBeginIndex; bufferIdx < bufferEndIndex; ++bufferIdx) {
55             PLUGIN_ASSERT(bufferIdx < stagingConsumeStruct.bufferCopies.size());
56             const BufferCopy& currBufferCopy = stagingConsumeStruct.bufferCopies[bufferIdx];
57             uint8_t* dstData = baseDstDataBegin + currBufferCopy.dstOffset;
58             const uint8_t* srcPtr = nullptr;
59             size_t srcSize = 0;
60             if (ref.dataType == StagingCopyStruct::DataType::DATA_TYPE_VECTOR) {
61                 srcPtr = baseSrcDataBegin + currBufferCopy.srcOffset;
62                 srcSize = currBufferCopy.size;
63             }
64             if ((srcPtr) && (srcSize > 0)) {
65                 PLUGIN_ASSERT(bufferDesc.byteSize >= srcSize);
66                 if (!CloneData(dstData, size_t(baseDstDataEnd - dstData), srcPtr, srcSize)) {
67                     PLUGIN_LOG_E("Copying of CPU data directly failed");
68                 }
69             }
70         }
71         gpuResourceMgr.UnmapBuffer(ref.dstHandle.GetHandle());
72     }
73 }
74 
CopyHostDirectlyToBuffer(const IRenderNodeGpuResourceManager & gpuResourceMgr,const StagingDirectDataCopyConsumeStruct & stagingData)75 void CopyHostDirectlyToBuffer(
76     const IRenderNodeGpuResourceManager& gpuResourceMgr, const StagingDirectDataCopyConsumeStruct& stagingData)
77 {
78     for (const auto& ref : stagingData.dataCopies) {
79         uint8_t* data = static_cast<uint8_t*>(gpuResourceMgr.MapBuffer(ref.dstHandle.GetHandle()));
80         if (!data) {
81             PLUGIN_LOG_E("staging: dstHandle %" PRIu64, ref.dstHandle.GetHandle().id);
82             return;
83         }
84         const size_t dstOffset = ref.bufferCopy.dstOffset;
85         data += dstOffset;
86         auto const& bufferDesc = gpuResourceMgr.GetBufferDescriptor(ref.dstHandle.GetHandle());
87         const uint8_t* srcPtr = ref.data.data() + ref.bufferCopy.srcOffset;
88         const size_t copySize =
89             std::min(ref.data.size() - size_t(ref.bufferCopy.srcOffset), size_t(ref.bufferCopy.size));
90         if ((srcPtr) && (copySize > 0)) {
91             PLUGIN_ASSERT((size_t(bufferDesc.byteSize) - dstOffset) >= copySize);
92             if (!CloneData(data, bufferDesc.byteSize - dstOffset, srcPtr, copySize)) {
93                 PLUGIN_LOG_E("Copying of staging data failed");
94             }
95         }
96         gpuResourceMgr.UnmapBuffer(ref.dstHandle.GetHandle());
97     }
98 }
99 } // namespace
100 
InitNode(IRenderNodeContextManager & renderNodeContextMgr)101 void RenderNodeStaging::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
102 {
103     renderNodeContextMgr_ = &renderNodeContextMgr;
104     renderStaging.Init(*renderNodeContextMgr_);
105 
106     const auto& renderNodeGraphData = renderNodeContextMgr_->GetRenderNodeGraphData();
107     dataStoreNameStaging_ = renderNodeGraphData.renderNodeGraphName + "RenderDataStoreDefaultStaging";
108 }
109 
PreExecuteFrame()110 void RenderNodeStaging::PreExecuteFrame()
111 {
112     // re-create needed gpu resources
113     if (renderNodeContextMgr_->GetRenderNodeGraphData().renderingConfiguration.renderBackend ==
114         DeviceBackendType::OPENGLES) {
115         const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
116         if (auto* dataStoreDefaultStaging = static_cast<RenderDataStoreDefaultStaging*>(
117                 renderDataStoreMgr.GetRenderDataStore(dataStoreNameStaging_));
118             dataStoreDefaultStaging) {
119             renderStaging.PreExecuteFrame(dataStoreDefaultStaging->GetImageClearByteSize());
120         }
121     }
122 }
123 
ExecuteFrame(IRenderCommandList & cmdList)124 void RenderNodeStaging::ExecuteFrame(IRenderCommandList& cmdList)
125 {
126     const auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager();
127     auto& gpuResourceMgrImpl =
128         static_cast<RenderNodeGpuResourceManager&>(renderNodeContextMgr_->GetGpuResourceManager());
129     const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
130     bool hasData = gpuResourceMgrImpl.HasStagingData();
131 
132     StagingConsumeStruct renderDataStoreStaging;
133     StagingDirectDataCopyConsumeStruct renderDataStoreStagingDirectCopy;
134     StagingImageClearConsumeStruct renderDataStoreImageClear;
135     if (auto* dataStoreDefaultStaging =
136             static_cast<RenderDataStoreDefaultStaging*>(renderDataStoreMgr.GetRenderDataStore(dataStoreNameStaging_));
137         dataStoreDefaultStaging) {
138         hasData = hasData || dataStoreDefaultStaging->HasBeginStagingData();
139         renderDataStoreStaging = dataStoreDefaultStaging->ConsumeBeginStagingData();
140         renderDataStoreStagingDirectCopy = dataStoreDefaultStaging->ConsumeBeginStagingDirectDataCopy();
141         renderDataStoreImageClear = dataStoreDefaultStaging->ConsumeBeginStagingImageClears();
142     }
143 
144     // early out, no data
145     if (!hasData) {
146         return;
147     }
148 
149     RENDER_DEBUG_MARKER_COL_SCOPE(cmdList, "RenderStaging", DefaultDebugConstants::CORE_DEFAULT_DEBUG_COLOR);
150 
151     // memcpy to staging
152     const StagingConsumeStruct staging = gpuResourceMgrImpl.ConsumeStagingData();
153     if (RenderHandleUtil::IsValid(staging.stagingBuffer) && (staging.stagingByteSize > 0)) {
154         if (auto* dataPtr = static_cast<uint8_t*>(gpuResourceMgr.MapBufferMemory(staging.stagingBuffer)); dataPtr) {
155             RenderStaging::StagingMappedBuffer smb { staging.stagingBuffer, dataPtr, staging.stagingByteSize };
156             renderStaging.CopyHostToStaging(staging, smb);
157 
158             gpuResourceMgr.UnmapBuffer(staging.stagingBuffer);
159         }
160     }
161     renderStaging.CopyHostToStaging(gpuResourceMgr, renderDataStoreStaging);
162     // direct memcpy
163     CopyHostDirectlyToBuffer(gpuResourceMgr, staging);
164     CopyHostDirectlyToBuffer(gpuResourceMgr, renderDataStoreStagingDirectCopy);
165 
166     // images
167     renderStaging.ClearImages(cmdList, gpuResourceMgr, renderDataStoreImageClear);
168     renderStaging.CopyStagingToImages(cmdList, gpuResourceMgr, staging, renderDataStoreStaging);
169     renderStaging.CopyImagesToBuffers(cmdList, staging, renderDataStoreStaging);
170     renderStaging.CopyImagesToImages(cmdList, staging, renderDataStoreStaging);
171 
172     // buffers
173     renderStaging.CopyBuffersToBuffers(cmdList, staging, renderDataStoreStaging);
174 }
175 
176 // for plugin / factory interface
Create()177 IRenderNode* RenderNodeStaging::Create()
178 {
179     return new RenderNodeStaging();
180 }
181 
Destroy(IRenderNode * instance)182 void RenderNodeStaging::Destroy(IRenderNode* instance)
183 {
184     delete static_cast<RenderNodeStaging*>(instance);
185 }
186 RENDER_END_NAMESPACE()
187