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_data_store_default_staging.h"
17
18 #include <cstdint>
19
20 #include <render/datastore/intf_render_data_store_default_staging.h>
21 #include <render/device/gpu_resource_desc.h>
22 #include <render/device/intf_device.h>
23 #include <render/device/intf_gpu_resource_manager.h>
24 #include <render/intf_render_context.h>
25 #include <render/namespace.h>
26 #include <render/resource_handle.h>
27
28 #include "device/gpu_resource_manager.h"
29 #include "util/log.h"
30
31 using namespace BASE_NS;
32
RENDER_BEGIN_NAMESPACE()33 RENDER_BEGIN_NAMESPACE()
34 RenderDataStoreDefaultStaging::RenderDataStoreDefaultStaging(IRenderContext& renderContext, const string_view name)
35 : gpuResourceMgr_(renderContext.GetDevice().GetGpuResourceManager()), name_(name)
36 {}
37
~RenderDataStoreDefaultStaging()38 RenderDataStoreDefaultStaging::~RenderDataStoreDefaultStaging() {}
39
PreRender()40 void RenderDataStoreDefaultStaging::PreRender()
41 {
42 // get stuff ready for render nodes
43
44 std::lock_guard<std::mutex> lock(mutex_);
45
46 frameStagingConsumeData_ = move(stagingConsumeData_);
47 frameStagingConsumeGpuBuffers_ = move(stagingGpuBuffers_);
48 }
49
PostRender()50 void RenderDataStoreDefaultStaging::PostRender()
51 {
52 std::lock_guard<std::mutex> lock(mutex_);
53
54 // destroy already consumed staging buffers
55 frameStagingConsumeGpuBuffers_.clear();
56 }
57
Clear()58 void RenderDataStoreDefaultStaging::Clear()
59 {
60 // The data cannot be automatically cleared here
61 }
62
CopyImageToBuffer(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const BufferImageCopy & bufferImageCopy,const ResourceCopyInfo copyInfo)63 void RenderDataStoreDefaultStaging::CopyImageToBuffer(const RenderHandleReference& srcHandle,
64 const RenderHandleReference& dstHandle, const BufferImageCopy& bufferImageCopy, const ResourceCopyInfo copyInfo)
65 {
66 if (gpuResourceMgr_.IsGpuImage(srcHandle) && gpuResourceMgr_.IsGpuBuffer(dstHandle)) {
67 std::lock_guard<std::mutex> lock(mutex_);
68
69 auto& staging =
70 (copyInfo == ResourceCopyInfo::BEGIN_FRAME) ? stagingConsumeData_.beginFrame : stagingConsumeData_.endFrame;
71 const uint32_t beginIndex = static_cast<uint32_t>(staging.bufferImageCopies.size());
72 staging.bufferImageCopies.push_back(bufferImageCopy);
73
74 staging.imageToBuffer.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_SRC_TO_DST_COPY,
75 srcHandle, dstHandle, beginIndex, 1u, {}, nullptr });
76 }
77 }
78
CopyImageToImage(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const ImageCopy & imageCopy,const ResourceCopyInfo copyInfo)79 void RenderDataStoreDefaultStaging::CopyImageToImage(const RenderHandleReference& srcHandle,
80 const RenderHandleReference& dstHandle, const ImageCopy& imageCopy, const ResourceCopyInfo copyInfo)
81 {
82 if (gpuResourceMgr_.IsGpuImage(srcHandle) && gpuResourceMgr_.IsGpuImage(dstHandle)) {
83 std::lock_guard<std::mutex> lock(mutex_);
84
85 auto& staging =
86 (copyInfo == ResourceCopyInfo::BEGIN_FRAME) ? stagingConsumeData_.beginFrame : stagingConsumeData_.endFrame;
87 const uint32_t beginIndex = static_cast<uint32_t>(staging.imageCopies.size());
88 staging.imageCopies.push_back(imageCopy);
89
90 staging.imageToImage.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_SRC_TO_DST_COPY,
91 srcHandle, dstHandle, beginIndex, 1u, {}, nullptr });
92 }
93 }
94
CopyBufferToBuffer(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const BufferCopy & bufferCopy,const ResourceCopyInfo copyInfo)95 void RenderDataStoreDefaultStaging::CopyBufferToBuffer(const RenderHandleReference& srcHandle,
96 const RenderHandleReference& dstHandle, const BufferCopy& bufferCopy, const ResourceCopyInfo copyInfo)
97 {
98 if (gpuResourceMgr_.IsGpuBuffer(srcHandle) && gpuResourceMgr_.IsGpuBuffer(dstHandle)) {
99 std::lock_guard<std::mutex> lock(mutex_);
100
101 auto& staging =
102 (copyInfo == ResourceCopyInfo::BEGIN_FRAME) ? stagingConsumeData_.beginFrame : stagingConsumeData_.endFrame;
103 const uint32_t beginIndex = static_cast<uint32_t>(staging.bufferCopies.size());
104 staging.bufferCopies.push_back(bufferCopy);
105
106 staging.bufferToBuffer.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_DIRECT_SRC_COPY,
107 srcHandle, dstHandle, beginIndex, 1u, {}, nullptr });
108 }
109 }
110
CopyBufferToImage(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const BufferImageCopy & bufferImageCopy,const ResourceCopyInfo copyInfo)111 void RenderDataStoreDefaultStaging::CopyBufferToImage(const RenderHandleReference& srcHandle,
112 const RenderHandleReference& dstHandle, const BufferImageCopy& bufferImageCopy, const ResourceCopyInfo copyInfo)
113 {
114 if (gpuResourceMgr_.IsGpuBuffer(srcHandle) && gpuResourceMgr_.IsGpuImage(dstHandle)) {
115 std::lock_guard<std::mutex> lock(mutex_);
116
117 auto& staging =
118 (copyInfo == ResourceCopyInfo::BEGIN_FRAME) ? stagingConsumeData_.beginFrame : stagingConsumeData_.endFrame;
119 const uint32_t beginIndex = static_cast<uint32_t>(staging.bufferImageCopies.size());
120 staging.bufferImageCopies.push_back(bufferImageCopy);
121
122 staging.bufferToImage.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_DIRECT_SRC_COPY,
123 srcHandle, dstHandle, beginIndex, 1u, {}, nullptr });
124 }
125 }
126
ClearColorImage(const RenderHandleReference & handle,const ClearColorValue color)127 void RenderDataStoreDefaultStaging::ClearColorImage(const RenderHandleReference& handle, const ClearColorValue color)
128 {
129 if (gpuResourceMgr_.IsGpuImage(handle) && (!RenderHandleUtil::IsDepthImage(handle.GetHandle()))) {
130 std::lock_guard<std::mutex> lock(mutex_);
131
132 stagingConsumeData_.beginFrameClear.clears.push_back({ handle, color });
133 }
134 }
135
CopyDataToBuffer(const array_view<const uint8_t> & dat,const RenderHandleReference & dstHandle,const BufferCopy & bufferCopy)136 void RenderDataStoreDefaultStaging::CopyDataToBuffer(
137 const array_view<const uint8_t>& dat, const RenderHandleReference& dstHandle, const BufferCopy& bufferCopy)
138 {
139 if ((dat.size_bytes() > 0) && gpuResourceMgr_.IsGpuBuffer(dstHandle)) {
140 // NOTE: validation
141 // create staging buffer
142 const GpuBufferDesc stagingBufferDesc =
143 GpuResourceManager::GetStagingBufferDesc(static_cast<uint32_t>(dat.size_bytes()));
144 const RenderHandleReference stagingBufferHandle = gpuResourceMgr_.Create(stagingBufferDesc);
145
146 std::lock_guard<std::mutex> lock(mutex_);
147
148 stagingGpuBuffers_.push_back(stagingBufferHandle);
149
150 auto& staging = stagingConsumeData_.beginFrame;
151 const uint32_t beginIndex = static_cast<uint32_t>(staging.bufferCopies.size());
152 staging.bufferCopies.push_back(BufferCopy { 0, 0, static_cast<uint32_t>(dat.size_bytes()) });
153
154 vector<uint8_t> copiedData(dat.cbegin().ptr(), dat.cend().ptr());
155 staging.bufferToBuffer.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_VECTOR,
156 stagingBufferHandle, dstHandle, beginIndex, 1, move(copiedData), nullptr });
157 }
158 }
159
CopyDataToBufferOnCpu(const array_view<const uint8_t> & dat,const RenderHandleReference & dstHandle,const BufferCopy & bufferCopy)160 void RenderDataStoreDefaultStaging::CopyDataToBufferOnCpu(
161 const array_view<const uint8_t>& dat, const RenderHandleReference& dstHandle, const BufferCopy& bufferCopy)
162 {
163 if ((dat.size_bytes() > 0) && gpuResourceMgr_.IsGpuBuffer(dstHandle)) {
164 const GpuBufferDesc bufDesc = gpuResourceMgr_.GetBufferDescriptor(dstHandle);
165 if ((bufDesc.memoryPropertyFlags & CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&
166 (bufDesc.memoryPropertyFlags & CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
167 PLUGIN_ASSERT(bufferCopy.size <= static_cast<uint32_t>(dat.size()));
168
169 std::lock_guard<std::mutex> lock(mutex_);
170
171 vector<uint8_t> copiedData(dat.cbegin().ptr(), dat.cend().ptr());
172 stagingConsumeData_.beginFrameDirect.dataCopies.push_back(
173 DirectDataCopyOnCpu { dstHandle, bufferCopy, move(copiedData) });
174 } else {
175 PLUGIN_LOG_E("CopyDataToBufferOnCpu invalid buffer given (needs host_visibile and host_coherent).");
176 }
177 }
178 }
179
CopyDataToImage(const array_view<const uint8_t> & dat,const RenderHandleReference & dstHandle,const BufferImageCopy & bufferImageCopy)180 void RenderDataStoreDefaultStaging::CopyDataToImage(const array_view<const uint8_t>& dat,
181 const RenderHandleReference& dstHandle, const BufferImageCopy& bufferImageCopy)
182 {
183 if ((dat.size_bytes() > 0) && gpuResourceMgr_.IsGpuImage(dstHandle)) {
184 // NOTE: validation
185 // create staging buffer
186 const GpuBufferDesc stagingBufferDesc =
187 GpuResourceManager::GetStagingBufferDesc(static_cast<uint32_t>(dat.size_bytes()));
188 const RenderHandleReference& stagingBufferHandle = gpuResourceMgr_.Create(stagingBufferDesc);
189
190 std::lock_guard<std::mutex> lock(mutex_);
191
192 stagingGpuBuffers_.push_back(stagingBufferHandle);
193
194 auto& staging = stagingConsumeData_.beginFrame;
195 const uint32_t beginIndex = static_cast<uint32_t>(staging.bufferImageCopies.size());
196 staging.bufferImageCopies.push_back(bufferImageCopy);
197
198 vector<uint8_t> copiedData(dat.cbegin().ptr(), dat.cend().ptr());
199 staging.bufferToImage.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_VECTOR,
200 stagingBufferHandle, dstHandle, beginIndex, 1, move(copiedData), nullptr });
201 }
202 }
203
CopyBufferToImage(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,BASE_NS::array_view<const BufferImageCopy> bufferImageCopies)204 void RenderDataStoreDefaultStaging::CopyBufferToImage(const RenderHandleReference& srcHandle,
205 const RenderHandleReference& dstHandle, BASE_NS::array_view<const BufferImageCopy> bufferImageCopies)
206 {
207 if (gpuResourceMgr_.IsGpuBuffer(srcHandle) && gpuResourceMgr_.IsGpuImage(dstHandle)) {
208 std::lock_guard<std::mutex> lock(mutex_);
209
210 auto& staging = stagingConsumeData_.beginFrame;
211 const uint32_t beginIndex = static_cast<uint32_t>(staging.bufferImageCopies.size());
212 staging.bufferImageCopies.insert(
213 staging.bufferImageCopies.end(), bufferImageCopies.begin(), bufferImageCopies.end());
214
215 staging.bufferToImage.push_back(StagingCopyStruct { StagingCopyStruct::DataType::DATA_TYPE_DIRECT_SRC_COPY,
216 srcHandle, dstHandle, beginIndex, static_cast<uint32_t>(bufferImageCopies.size()), {}, nullptr });
217 }
218 }
219
CopyBufferToBuffer(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const BufferCopy & bufferCopy)220 void RenderDataStoreDefaultStaging::CopyBufferToBuffer(
221 const RenderHandleReference& srcHandle, const RenderHandleReference& dstHandle, const BufferCopy& bufferCopy)
222 {
223 CopyBufferToBuffer(srcHandle, dstHandle, bufferCopy, ResourceCopyInfo::BEGIN_FRAME);
224 }
225
CopyBufferToImage(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const BufferImageCopy & bufferImageCopy)226 void RenderDataStoreDefaultStaging::CopyBufferToImage(const RenderHandleReference& srcHandle,
227 const RenderHandleReference& dstHandle, const BufferImageCopy& bufferImageCopy)
228 {
229 CopyBufferToImage(srcHandle, dstHandle, bufferImageCopy, ResourceCopyInfo::BEGIN_FRAME);
230 }
231
CopyImageToBuffer(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const BufferImageCopy & bufferImageCopy)232 void RenderDataStoreDefaultStaging::CopyImageToBuffer(const RenderHandleReference& srcHandle,
233 const RenderHandleReference& dstHandle, const BufferImageCopy& bufferImageCopy)
234 {
235 CopyImageToBuffer(srcHandle, dstHandle, bufferImageCopy, ResourceCopyInfo::BEGIN_FRAME);
236 }
237
CopyImageToImage(const RenderHandleReference & srcHandle,const RenderHandleReference & dstHandle,const ImageCopy & imageCopy)238 void RenderDataStoreDefaultStaging::CopyImageToImage(
239 const RenderHandleReference& srcHandle, const RenderHandleReference& dstHandle, const ImageCopy& imageCopy)
240 {
241 CopyImageToImage(srcHandle, dstHandle, imageCopy, ResourceCopyInfo::BEGIN_FRAME);
242 }
243
HasBeginStagingData() const244 bool RenderDataStoreDefaultStaging::HasBeginStagingData() const
245 {
246 const auto& staging = frameStagingConsumeData_;
247 const auto& begStaging = staging.beginFrame;
248 const bool noBeginStaging = begStaging.bufferToBuffer.empty() && begStaging.bufferToImage.empty() &&
249 begStaging.imageToBuffer.empty() && begStaging.imageToImage.empty() &&
250 begStaging.cpuToBuffer.empty() && begStaging.bufferCopies.empty() &&
251 begStaging.bufferImageCopies.empty() && begStaging.imageCopies.empty();
252 const bool noBeginDirectCopy = staging.beginFrameDirect.dataCopies.empty();
253 const bool noBeginClear = staging.beginFrameClear.clears.empty();
254 if (noBeginStaging && noBeginDirectCopy && noBeginClear) {
255 return false;
256 } else {
257 return true;
258 }
259 }
260
HasEndStagingData() const261 bool RenderDataStoreDefaultStaging::HasEndStagingData() const
262 {
263 const auto& endStaging = frameStagingConsumeData_.endFrame;
264 const bool noEndStaging = endStaging.bufferToBuffer.empty() && endStaging.bufferToImage.empty() &&
265 endStaging.imageToBuffer.empty() && endStaging.imageToImage.empty() &&
266 endStaging.cpuToBuffer.empty() && endStaging.bufferCopies.empty() &&
267 endStaging.bufferImageCopies.empty() && endStaging.imageCopies.empty();
268 if (noEndStaging) {
269 return false;
270 } else {
271 return true;
272 }
273 }
274
ConsumeBeginStagingData()275 StagingConsumeStruct RenderDataStoreDefaultStaging::ConsumeBeginStagingData()
276 {
277 StagingConsumeStruct scs = move(frameStagingConsumeData_.beginFrame);
278 return scs;
279 }
280
ConsumeBeginStagingDirectDataCopy()281 StagingDirectDataCopyConsumeStruct RenderDataStoreDefaultStaging::ConsumeBeginStagingDirectDataCopy()
282 {
283 StagingDirectDataCopyConsumeStruct scs = move(frameStagingConsumeData_.beginFrameDirect);
284 return scs;
285 }
286
ConsumeBeginStagingImageClears()287 StagingImageClearConsumeStruct RenderDataStoreDefaultStaging::ConsumeBeginStagingImageClears()
288 {
289 StagingImageClearConsumeStruct scs = move(frameStagingConsumeData_.beginFrameClear);
290 return scs;
291 }
292
ConsumeEndStagingData()293 StagingConsumeStruct RenderDataStoreDefaultStaging::ConsumeEndStagingData()
294 {
295 StagingConsumeStruct scs = move(frameStagingConsumeData_.endFrame);
296 return scs;
297 }
298
GetImageClearByteSize() const299 uint32_t RenderDataStoreDefaultStaging::GetImageClearByteSize() const
300 {
301 uint32_t byteSize = 0;
302 for (const auto& ref : frameStagingConsumeData_.beginFrameClear.clears) {
303 const GpuImageDesc desc = gpuResourceMgr_.GetImageDescriptor(ref.handle);
304 const uint32_t pixelBytes = gpuResourceMgr_.GetFormatProperties(ref.handle).bytesPerPixel;
305 byteSize += (pixelBytes * desc.width * desc.height); // no 3D supported
306 }
307 return byteSize;
308 }
309
310 // for plugin / factory interface
Create(IRenderContext & renderContext,char const * name)311 IRenderDataStore* RenderDataStoreDefaultStaging::Create(IRenderContext& renderContext, char const* name)
312 {
313 return new RenderDataStoreDefaultStaging(renderContext, name);
314 }
315
Destroy(IRenderDataStore * instance)316 void RenderDataStoreDefaultStaging::Destroy(IRenderDataStore* instance)
317 {
318 delete static_cast<RenderDataStoreDefaultStaging*>(instance);
319 }
320 RENDER_END_NAMESPACE()
321