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 #ifndef API_RENDER_DEVICE_IDEVICE_H
17 #define API_RENDER_DEVICE_IDEVICE_H
18 
19 #include <cstdint>
20 
21 #include <render/device/gpu_resource_desc.h>
22 #include <render/device/pipeline_state_desc.h>
23 #include <render/namespace.h>
24 
25 RENDER_BEGIN_NAMESPACE()
26 class IGpuResourceManager;
27 class IShaderManager;
28 
29 struct BackendExtra {};
30 struct RenderBackendRecordingState {};
31 
32 /** Device configuration flag bits */
33 enum DeviceConfigurationFlagBits {
34     /** Enable pipeline caching */
35     CORE_DEVICE_CONFIGURATION_PIPELINE_CACHE_BIT = 1 << 0,
36 };
37 
38 /** Swapchain flag bits */
39 enum SwapchainFlagBits {
40     /** Color buffer */
41     CORE_SWAPCHAIN_COLOR_BUFFER_BIT = 0x00000001,
42     /** Depth buffer */
43     CORE_SWAPCHAIN_DEPTH_BUFFER_BIT = 0x00000002,
44     /** Enable v-sync */
45     CORE_SWAPCHAIN_VSYNC_BIT = 0x00000004,
46     /** Hint to prefer sRGB format */
47     CORE_SWAPCHAIN_SRGB_BIT = 0x00000008,
48 };
49 /** Container for swapchain flag bits */
50 using SwapchainFlags = uint32_t;
51 
52 /** Swapchain create info */
53 struct SwapchainCreateInfo {
54     /** Surface handle */
55     uint64_t surfaceHandle { 0 };
56     /** Swapchain flags */
57     SwapchainFlags swapchainFlags { SwapchainFlagBits::CORE_SWAPCHAIN_COLOR_BUFFER_BIT };
58     /** Needed image usage flags for swapchain color image. Checked against supported */
59     ImageUsageFlags imageUsageFlags { ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT };
60 
61     struct SwapchainWindow {
62         /** Platform window pointer */
63         uintptr_t window { 0 };
64         /** Platform instance (hInstance, connection, display) */
65         uintptr_t instance { 0 };
66     };
67     /** Window handles. Creates surface automatically.
68      * NOTE: do not create surface for surfaceHandle if the window and instance is provided
69      */
70     SwapchainWindow window;
71 };
72 
73 struct DeviceConfiguration {
74     /** Maps to buffering count e.g. coherent gpu buffers and command buffers (vulkan)
75      * default value is 3, supported values depends from the backend.
76      * Should always be bigger or equal to swapchain count. Waits earlier in the frame.
77      */
78     uint32_t bufferingCount { 3u };
79     /** Maps to desired swapchain count default value is 3,
80      * and supported values depend from the backend.
81      */
82     uint32_t swapchainImageCount { 3u };
83 
84     /**
85      * Integrated devices (mobile gpus, integrated desktop chips) expose all memory pools with host visible flags.
86      * If all pools have requiredIntegratedMemoryFlags then this optimization will be enabled and
87      * staging buffers are not used for this data. The data is directly mapped once for writing.
88      * Set to zero (0u) to disable all staging optimizations.
89      */
90     uint32_t requiredIntegratedMemoryFlags { CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
91                                              CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
92 
93     /** Additional options for device creation.
94      */
95     uint32_t configurationFlags { CORE_DEVICE_CONFIGURATION_PIPELINE_CACHE_BIT };
96 };
97 
98 /** Device backend type */
99 enum class DeviceBackendType {
100     /** Vulkan backend */
101     VULKAN,
102     /** GLES backend */
103     OPENGLES,
104     /** OpenGL backend */
105     OPENGL
106 };
107 
108 /** @ingroup group_idevice */
109 /** Device create info */
110 struct DeviceCreateInfo {
111     /** Backend type to be created */
112     DeviceBackendType backendType { DeviceBackendType::VULKAN };
113     /** Device configuration */
114     DeviceConfiguration deviceConfiguration;
115     /** Backend configuration pointer */
116     const BackendExtra* backendConfiguration { nullptr };
117 };
118 
119 /** Common device properties for various features */
120 struct CommonDeviceProperties {
121     /** Fragment shading rate properties */
122     FragmentShadingRateProperties fragmentShadingRateProperties;
123 };
124 
125 /** @ingroup group_gfx_ilowleveldevice */
126 /** ILowLevelDevice, to provide low-level access to platform device and resources. */
127 class ILowLevelDevice {
128 public:
129     /** Returns backend type */
130     virtual DeviceBackendType GetBackendType() const = 0;
131 
132 protected:
133     ILowLevelDevice() = default;
134     virtual ~ILowLevelDevice() = default;
135 };
136 
137 /** @ingroup group_idevice */
138 struct DevicePlatformData {};
139 
140 /** Settings which can be changed after device has been created. */
141 struct BackendConfig {};
142 
143 /** @ingroup group_idevice
144  * IDevice interface for accessing device.
145  * Not internally synchronized and therefore Create And Destroy -menthods
146  * need to be called from the rendering thread.
147  * NOTE: Even though CreateSwapchainHandle returns a reference counted image handle,
148  * one needs to explicitly destroy the swapchain with DestroySwapchain(handle)
149  */
150 class IDevice {
151 public:
152     /** Create a swapchain for graphics API use.
153      *  @param swapchainCreateInfo Swapchain creation info.
154      */
155     virtual void CreateSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) = 0;
156 
157     /** Destroys swapchain
158      */
159     virtual void DestroySwapchain() = 0;
160 
161     /** Create a swapchain for graphics API use. Prefer using this method.
162      * Replace handle to re-use the same shallow handle throughout the Render.
163      * Add global unique image name to get global access to the resource.
164      * @param swapchainCreateInfo Swapchain creation info.
165      * @param replacedHandle Handle to be used as a shallow render handle for swapchain images.
166      * @param name Optional unique global name for the image.
167      */
168     virtual RenderHandleReference CreateSwapchainHandle(const SwapchainCreateInfo& swapchainCreateInfo,
169         const RenderHandleReference& replacedHandle, const BASE_NS::string_view name) = 0;
170 
171     /** Create a swapchain for graphics API use.
172      *  @param swapchainCreateInfo Swapchain creation info.
173      */
174     virtual RenderHandleReference CreateSwapchainHandle(const SwapchainCreateInfo& swapchainCreateInfo) = 0;
175 
176     /** Destroys swapchain
177      */
178     virtual void DestroySwapchain(const RenderHandleReference& handle) = 0;
179 
180     /** Returns backend type (vulkan, gles, etc) */
181     virtual DeviceBackendType GetBackendType() const = 0;
182 
183     /** Returns device platform data which needs to be cast for correct device. */
184     virtual const DevicePlatformData& GetPlatformData() const = 0;
185 
186     /** Get GPU resource manager interface. */
187     virtual IGpuResourceManager& GetGpuResourceManager() const = 0;
188     /** Get shader manager interface. */
189     virtual IShaderManager& GetShaderManager() const = 0;
190 
191     /** Returns supported flags for given format. */
192     virtual FormatProperties GetFormatProperties(const BASE_NS::Format format) const = 0;
193 
194     /** Returns common device properties */
195     virtual const CommonDeviceProperties& GetCommonDeviceProperties() const = 0;
196 
197     /** Returns acceleration structure build sizes. Only a single geometry data should be valid.
198      *  @param geometryInfo Build geometry info for size calculations.
199      *  @param triangles Build geometry info for size calculations.
200      *  @param aabb Build geometry info for size calculations.
201      *  @param instances Build geometry info for size calculations.
202      */
203     virtual AccelerationStructureBuildSizes GetAccelerationStructureBuildSizes(
204         const AccelerationStructureBuildGeometryInfo& geometry,
205         BASE_NS::array_view<const AccelerationStructureGeometryTrianglesInfo> triangles,
206         BASE_NS::array_view<const AccelerationStructureGeometryAabbsInfo> aabbs,
207         BASE_NS::array_view<const AccelerationStructureGeometryInstancesInfo> instances) const = 0;
208 
209     /** Get frame count. */
210     virtual uint64_t GetFrameCount() const = 0;
211 
212     /** Wait for the GPU to become idle.
213      *  Needs to be called from render thread where renderFrame is called.
214      *
215      *  This is a hazardous method and should only be called with extreme caution.
216      *  Do not call this method per frame.
217      */
218     virtual void WaitForIdle() = 0;
219 
220     /** Get low level device interface. Needs to be cast to correct ILowLevelDeviceXX based on backend type. */
221     virtual ILowLevelDevice& GetLowLevelDevice() const = 0;
222 
223     /** Update backend configuration.
224      * @param config Backend type specific settings.
225      */
226     virtual void SetBackendConfig(const BackendConfig& config) = 0;
227 
228     /** Get device configuration.
229      * The device configuration is updated after creation, i.e. the config might not match the device creation struct.
230      * @return Returns device configuration.
231      */
232     virtual DeviceConfiguration GetDeviceConfiguration() const = 0;
233 
234 protected:
235     IDevice() = default;
236     virtual ~IDevice() = default;
237 };
238 
239 /** @ingroup group_idevice */
240 struct GpuBufferPlatformData {};
241 struct GpuImagePlatformData {};
242 struct GpuSamplerPlatformData {};
243 struct GpuAccelerationStructurePlatformData {};
244 RENDER_END_NAMESPACE()
245 
246 #endif // API_RENDER_DEVICE_IDEVICE_H
247