• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "device.h"
17 
18 #include <algorithm>
19 #include <cstdint>
20 
21 #include <render/datastore/intf_render_data_store_manager.h>
22 #include <render/datastore/intf_render_data_store_pod.h>
23 #include <render/device/pipeline_layout_desc.h>
24 #include <render/namespace.h>
25 
26 #include "default_engine_constants.h"
27 #include "device/gpu_resource_manager.h"
28 #include "device/shader_manager.h"
29 #include "device/swapchain.h"
30 #include "render_context.h"
31 #include "util/log.h"
32 #include "util/string_util.h"
33 
34 #if (RENDER_HAS_VULKAN_BACKEND)
35 #include "vulkan/device_vk.h"
36 #endif
37 
38 #if (RENDER_HAS_GL_BACKEND) || (RENDER_HAS_GLES_BACKEND)
39 #include "gles/device_gles.h"
40 #include "gles/swapchain_gles.h"
41 #endif
42 
43 using namespace BASE_NS;
44 
45 RENDER_BEGIN_NAMESPACE()
46 namespace {
47 static constexpr uint32_t MIN_BUFFERING_COUNT { 2 };
48 static constexpr uint32_t MAX_BUFFERING_COUNT { 4 };
49 
CreateDepthBuffer(const DeviceBackendType backendType,const Swapchain & swapchain,GpuResourceManager & gpuResourceManager,vector<RenderHandleReference> & defaultGpuResources)50 void CreateDepthBuffer(const DeviceBackendType backendType, const Swapchain& swapchain,
51     GpuResourceManager& gpuResourceManager, vector<RenderHandleReference>& defaultGpuResources)
52 {
53 // NOTE: special handling of CORE_DEFAULT_BACKBUFFER_DEPTH for different backend types.
54 #if (RENDER_HAS_VULKAN_BACKEND)
55     if (backendType == DeviceBackendType::VULKAN) {
56         gpuResourceManager.Create(
57             DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER_DEPTH, swapchain.GetDescDepthBuffer());
58     }
59 #endif
60 #if (RENDER_HAS_GL_BACKEND) || (RENDER_HAS_GLES_BACKEND)
61     if ((backendType == DeviceBackendType::OPENGL) || (backendType == DeviceBackendType::OPENGLES)) {
62         auto& platformData = static_cast<const SwapchainGLES&>(swapchain).GetPlatformData();
63         defaultGpuResources.emplace_back(
64             gpuResourceManager.CreateView(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER_DEPTH,
65                 swapchain.GetDescDepthBuffer(), platformData.depthPlatformData));
66     }
67 #endif
68 }
69 } // namespace
70 
Device(RenderContext & renderContext,const DeviceCreateInfo & deviceCreateInfo)71 Device::Device(RenderContext& renderContext, const DeviceCreateInfo& deviceCreateInfo) : renderContext_(renderContext)
72 {
73     if ((deviceConfiguration_.bufferingCount < MIN_BUFFERING_COUNT) ||
74         (deviceConfiguration_.bufferingCount > MAX_BUFFERING_COUNT)) {
75         deviceConfiguration_.bufferingCount =
76             std::clamp(deviceConfiguration_.bufferingCount, MIN_BUFFERING_COUNT, MAX_BUFFERING_COUNT);
77         PLUGIN_LOG_D("buffering count clamped to: %u", deviceConfiguration_.bufferingCount);
78     }
79 }
80 
CreateSwapchain(const SwapchainCreateInfo & swapchainCreateInfo)81 void Device::CreateSwapchain(const SwapchainCreateInfo& swapchainCreateInfo)
82 {
83     Activate();
84     CreateDeviceSwapchain(swapchainCreateInfo);
85     if (!swapchain_) {
86         Deactivate();
87         return;
88     }
89 
90     {
91         vector<unique_ptr<GpuImage>> swapchainGpuImages = CreateGpuImageViews(*swapchain_);
92         Deactivate();
93         for (uint32_t idx = 0; idx < swapchainGpuImages.size(); ++idx) {
94             const auto& ref = swapchainGpuImages[idx];
95             defaultGpuResources_.emplace_back(
96                 gpuResourceMgr_->CreateView(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SWAPCHAIN + to_string(idx),
97                     ref->GetDesc(), ref->GetBasePlatformData()));
98         }
99         Activate();
100     }
101     {
102         Deactivate();
103         const RenderHandle firstSwapchain = gpuResourceMgr_->GetImageRawHandle(
104             DefaultEngineGpuResourceConstants::CORE_DEFAULT_SWAPCHAIN + string_view("0"));
105         const RenderHandle shallowHandle =
106             gpuResourceMgr_->GetImageRawHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER);
107         gpuResourceMgr_->RemapGpuImageHandle(shallowHandle, firstSwapchain);
108         SetBackbufferHandle(shallowHandle); // store backbuffer client handle
109     }
110 
111     // configure automatically backbuffer as swapchain
112     {
113         IRenderDataStoreManager& rdsm = renderContext_.GetRenderDataStoreManager();
114         auto dataStorePod = static_cast<IRenderDataStorePod*>(rdsm.GetRenderDataStore("RenderDataStorePod"));
115         if (dataStorePod) {
116             auto const dataView = dataStorePod->Get("NodeGraphBackBufferConfiguration");
117             PLUGIN_ASSERT(dataView.size_bytes() == sizeof(NodeGraphBackBufferConfiguration));
118             NodeGraphBackBufferConfiguration ngbbc = *(const NodeGraphBackBufferConfiguration*)dataView.data();
119             StringUtil::CopyStringToArray(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER,
120                 ngbbc.backBufferName, NodeGraphBackBufferConfiguration::CORE_MAX_BACK_BUFFER_NAME_LENGTH);
121             ngbbc.backBufferType = NodeGraphBackBufferConfiguration::BackBufferType::SWAPCHAIN;
122             ngbbc.present = true;
123             dataStorePod->Set("NodeGraphBackBufferConfiguration", arrayviewU8(ngbbc));
124         }
125     }
126 
127     if (swapchainCreateInfo.swapchainFlags & SwapchainFlagBits::CORE_SWAPCHAIN_DEPTH_BUFFER_BIT) {
128         CreateDepthBuffer(GetBackendType(), *swapchain_, *gpuResourceMgr_, defaultGpuResources_);
129     }
130 }
131 
DestroySwapchain()132 void Device::DestroySwapchain()
133 {
134     // NOTE: Clear image resource handles.
135     Activate();
136     DestroyDeviceSwapchain();
137     SetBackbufferHandle({});
138     // remove swapchain configuration from the backbuffer
139     {
140         IRenderDataStoreManager& rdsm = renderContext_.GetRenderDataStoreManager();
141         auto dataStorePod = static_cast<IRenderDataStorePod*>(rdsm.GetRenderDataStore("RenderDataStorePod"));
142         if (dataStorePod) {
143             auto const dataView = dataStorePod->Get("NodeGraphBackBufferConfiguration");
144             PLUGIN_ASSERT(dataView.size_bytes() == sizeof(NodeGraphBackBufferConfiguration));
145             NodeGraphBackBufferConfiguration ngbbc = *(const NodeGraphBackBufferConfiguration*)dataView.data();
146             if (ngbbc.backBufferType == NodeGraphBackBufferConfiguration::BackBufferType::SWAPCHAIN) {
147                 ngbbc.backBufferType = NodeGraphBackBufferConfiguration::BackBufferType::UNDEFINED;
148                 ngbbc.present = false;
149             }
150             dataStorePod->Set("NodeGraphBackBufferConfiguration", arrayviewU8(ngbbc));
151         }
152     }
153     Deactivate();
154 }
155 
FrameStart()156 void Device::FrameStart()
157 {
158     ++frameCount_;
159 }
160 
FrameEnd()161 void Device::FrameEnd() {}
162 
SetDeviceStatus(const bool status)163 void Device::SetDeviceStatus(const bool status)
164 {
165     deviceStatus_.store(status);
166 }
167 
GetDeviceStatus() const168 bool Device::GetDeviceStatus() const
169 {
170     return deviceStatus_.load();
171 }
172 
GetFrameCount() const173 uint64_t Device::GetFrameCount() const
174 {
175     return frameCount_;
176 }
177 
GetSharedMemoryPropertyFlags() const178 MemoryPropertyFlags Device::GetSharedMemoryPropertyFlags() const
179 {
180     return deviceSharedMemoryPropertyFlags_;
181 }
182 
GetDeviceConfiguration() const183 DeviceConfiguration Device::GetDeviceConfiguration() const
184 {
185     return deviceConfiguration_;
186 }
187 
GetCommandBufferingCount() const188 uint32_t Device::GetCommandBufferingCount() const
189 {
190     return deviceConfiguration_.bufferingCount;
191 }
192 
HasSwapchain() const193 bool Device::HasSwapchain() const
194 {
195     return (swapchain_) ? true : false;
196 }
197 
GetSwapchain() const198 const Swapchain* Device::GetSwapchain() const
199 {
200     return swapchain_.get();
201 }
202 
SetBackbufferHandle(const RenderHandle handle)203 void Device::SetBackbufferHandle(const RenderHandle handle)
204 {
205     backbufferHandle_ = handle;
206 }
207 
GetBackbufferHandle() const208 RenderHandle Device::GetBackbufferHandle() const
209 {
210     return backbufferHandle_;
211 }
212 
SetLockResourceBackendAccess(const bool value)213 void Device::SetLockResourceBackendAccess(const bool value)
214 {
215     isBackendResourceAccessLocked_ = value;
216 }
217 
GetLockResourceBackendAccess() const218 bool Device::GetLockResourceBackendAccess() const
219 {
220     return isBackendResourceAccessLocked_;
221 }
222 
SetRenderBackendRunning(const bool value)223 void Device::SetRenderBackendRunning(const bool value)
224 {
225     isRenderbackendRunning_ = value;
226 }
227 
GetGpuResourceManager() const228 IGpuResourceManager& Device::GetGpuResourceManager() const
229 {
230     return *gpuResourceMgr_;
231 }
232 
GetShaderManager() const233 IShaderManager& Device::GetShaderManager() const
234 {
235     return *shaderMgr_;
236 }
237 RENDER_END_NAMESPACE()
238