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 DEVICE_DEVICE_H 17 #define DEVICE_DEVICE_H 18 19 #include <atomic> 20 #include <cstdint> 21 #include <mutex> 22 23 #include <base/containers/string.h> 24 #include <base/containers/unique_ptr.h> 25 #include <base/containers/vector.h> 26 #include <base/util/formats.h> 27 #include <core/namespace.h> 28 #include <core/threading/intf_thread_pool.h> 29 #include <render/device/intf_device.h> 30 #include <render/device/pipeline_state_desc.h> 31 #include <render/namespace.h> 32 #include <render/resource_handle.h> 33 34 #include "device/shader_manager.h" 35 #include "device/swapchain.h" 36 37 RENDER_BEGIN_NAMESPACE() 38 class RenderContext; 39 class GpuResourceManager; 40 41 class ShaderModule; 42 class ComputePipelineStateObject; 43 class GpuBuffer; 44 class GpuComputeProgram; 45 class GpuImage; 46 class GpuSampler; 47 class GpuResourceManager; 48 class GpuComputeProgram; 49 class GpuShaderProgram; 50 class GraphicsPipelineStateObject; 51 class PlatformGpuMemoryAllocator; 52 class RenderBackend; 53 class RenderFrameSync; 54 class NodeContextDescriptorSetManager; 55 class NodeContextPoolManager; 56 class ShaderModule; 57 class Swapchain; 58 class GpuSemaphore; 59 struct BackendSpecificImageDesc; 60 struct GpuAccelerationStructureDesc; 61 struct GpuBufferDesc; 62 struct GpuComputeProgramCreateData; 63 struct GpuImageDesc; 64 struct GpuImagePlatformData; 65 struct GpuSamplerDesc; 66 struct GpuShaderProgramCreateData; 67 struct PipelineLayout; 68 struct ShaderModuleCreateInfo; 69 struct SwapchainCreateInfo; 70 71 struct LowLevelRenderPassData {}; 72 struct LowLevelPipelineLayoutData {}; 73 74 struct DeviceFormatSupportConstants { 75 static constexpr uint32_t ALL_FLAGS_SUPPORTED { 0xFFFFu }; 76 static constexpr uint32_t LINEAR_FORMAT_MAX_IDX { BASE_NS::Format::BASE_FORMAT_ASTC_12x12_SRGB_BLOCK }; 77 static constexpr uint32_t LINEAR_FORMAT_MAX_COUNT { LINEAR_FORMAT_MAX_IDX + 1u }; 78 static constexpr uint32_t ADDITIONAL_FORMAT_START_NUMBER { BASE_NS::Format::BASE_FORMAT_G8B8G8R8_422_UNORM }; 79 static constexpr uint32_t ADDITIONAL_FORMAT_END_NUMBER { BASE_NS::Format::BASE_FORMAT_G8_B8_R8_3PLANE_444_UNORM }; 80 static constexpr uint32_t ADDITIONAL_FORMAT_MAX_COUNT { 81 (ADDITIONAL_FORMAT_END_NUMBER - ADDITIONAL_FORMAT_START_NUMBER) + 1u 82 }; 83 static constexpr uint32_t ADDITIONAL_FORMAT_BASE_IDX { LINEAR_FORMAT_MAX_COUNT }; 84 }; 85 86 struct DeviceConstants { 87 static constexpr uint32_t MAX_SWAPCHAIN_COUNT { 8U }; 88 }; 89 90 class Device : public IDevice { 91 public: 92 Device(RenderContext& renderContext, const DeviceCreateInfo& deviceCreateInfo); 93 94 Device(const Device&) = delete; 95 Device& operator=(const Device&) = delete; 96 97 virtual PlatformGpuMemoryAllocator* GetPlatformGpuMemoryAllocator() = 0; 98 99 // Activate context 100 virtual void Activate() = 0; 101 // Deactivate context 102 virtual void Deactivate() = 0; 103 104 // Allow parallel render node processing (on GLES checks that coherent mapping allowed) 105 virtual bool AllowThreadedProcessing() const = 0; 106 107 // Generally set once to true when device is created. 108 // Set to false e.g. when device is lost. 109 // Set and Get uses atomics if needed by the platform. 110 void SetDeviceStatus(const bool status); 111 bool GetDeviceStatus() const; 112 113 // (re-)create swapchain 114 void CreateSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) override; 115 RenderHandleReference CreateSwapchainHandle(const SwapchainCreateInfo& swapchainCreateInfo, 116 const RenderHandleReference& replacedHandle, const BASE_NS::string_view name) override; 117 RenderHandleReference CreateSwapchainHandle(const SwapchainCreateInfo& swapchainCreateInfo) override; 118 void DestroySwapchain() override; 119 void DestroySwapchain(const RenderHandleReference& handle) override; 120 // device specific preparation 121 virtual BASE_NS::unique_ptr<Swapchain> CreateDeviceSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) = 0; 122 virtual void DestroyDeviceSwapchain() = 0; 123 124 RenderHandleReference CreateSwapchainImpl(const SwapchainCreateInfo& swapchainCreateInfo, 125 const RenderHandleReference& replacedHandle, const BASE_NS::string_view name); 126 void DestroySwapchainImpl(const RenderHandleReference& handle); 127 128 SurfaceTransformFlags GetSurfaceTransformFlags(const RenderHandle& handle) const; 129 130 // Lock/Unlock access for this frame's GPU resources (for safety reasons) 131 void SetLockResourceBackendAccess(bool value); 132 // Set render backend running 133 void SetRenderBackendRunning(bool value); 134 bool GetLockResourceBackendAccess() const; 135 136 // Set to true when RenderFrame called 137 // Set to false when coming out of RenderFrame 138 void SetRenderFrameRunning(bool value); 139 bool GetRenderFrameRunning() const; 140 141 // Marks the beginning of a frame rendering. Expected to at least increment frame counter. 142 void FrameStart(); 143 void FrameEnd(); 144 145 IGpuResourceManager& GetGpuResourceManager() const override; 146 IShaderManager& GetShaderManager() const override; 147 148 void SetBackendConfig(const BackendConfig& config) override; 149 150 uint64_t GetFrameCount() const override; 151 152 const CommonDeviceProperties& GetCommonDeviceProperties() const override; 153 154 DeviceConfiguration GetDeviceConfiguration() const override; 155 156 bool HasSwapchain() const; 157 // get swapchain with shallow 158 const Swapchain* GetSwapchain(const RenderHandle handle) const; 159 160 struct SwapchainData { 161 static constexpr uint32_t MAX_IMAGE_VIEW_COUNT { 5U }; 162 163 RenderHandle remappableSwapchainImage {}; 164 RenderHandle imageViews[MAX_IMAGE_VIEW_COUNT]; 165 uint32_t imageViewCount { 0U }; 166 }; 167 168 struct InternalSwapchainData { 169 static constexpr uint32_t MAX_IMAGE_VIEW_COUNT { 5U }; 170 171 uint64_t surfaceHandle { 0 }; 172 uintptr_t window { 0 }; 173 174 BASE_NS::string globalName; 175 BASE_NS::string name; 176 RenderHandleReference remappableSwapchainImage {}; 177 RenderHandleReference additionalDepthBufferHandle {}; 178 RenderHandle remappableAdditionalSwapchainImage {}; // Not owned 179 RenderHandleReference imageViews[MAX_IMAGE_VIEW_COUNT]; 180 uint32_t imageViewCount { 0U }; 181 182 BASE_NS::unique_ptr<Swapchain> swapchain; 183 }; 184 SwapchainData GetSwapchainData(const RenderHandle handle) const; 185 186 // Number of command buffers to allocate for each node 187 uint32_t GetCommandBufferingCount() const; 188 // Get ANDed memory property flags from all memory pools 189 MemoryPropertyFlags GetSharedMemoryPropertyFlags() const; 190 191 BASE_NS::Format GetFormatOrFallback(BASE_NS::Format format) const; 192 193 // Platform specific creation 194 195 virtual BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuBufferDesc& desc) = 0; 196 virtual BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuAccelerationStructureDesc& desc) = 0; 197 198 // Create gpu image resources 199 virtual BASE_NS::unique_ptr<GpuImage> CreateGpuImage(const GpuImageDesc& desc) = 0; 200 /** Creates a engine GpuImage resource with platform resources. 201 * Does not own the platform resources nor does not destroy them. 202 */ 203 virtual BASE_NS::unique_ptr<GpuImage> CreateGpuImageView( 204 const GpuImageDesc& desc, const GpuImagePlatformData& platformData) = 0; 205 virtual BASE_NS::unique_ptr<GpuImage> CreateGpuImageView( 206 const GpuImageDesc& desc, const BackendSpecificImageDesc& platformData) = 0; 207 virtual BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>> CreateGpuImageViews(const Swapchain& platformData) = 0; 208 209 virtual BASE_NS::unique_ptr<GpuSampler> CreateGpuSampler(const GpuSamplerDesc& desc) = 0; 210 211 virtual BASE_NS::unique_ptr<RenderFrameSync> CreateRenderFrameSync() = 0; 212 virtual BASE_NS::unique_ptr<RenderBackend> CreateRenderBackend( 213 GpuResourceManager& gpuResourceMgr, const CORE_NS::IParallelTaskQueue::Ptr& queue) = 0; 214 215 virtual BASE_NS::unique_ptr<ShaderModule> CreateShaderModule(const ShaderModuleCreateInfo& data) = 0; 216 virtual BASE_NS::unique_ptr<ShaderModule> CreateComputeShaderModule(const ShaderModuleCreateInfo& data) = 0; 217 virtual BASE_NS::unique_ptr<GpuShaderProgram> CreateGpuShaderProgram(GpuShaderProgramCreateData const& data) = 0; 218 virtual BASE_NS::unique_ptr<GpuComputeProgram> CreateGpuComputeProgram(GpuComputeProgramCreateData const& data) = 0; 219 220 virtual BASE_NS::unique_ptr<NodeContextDescriptorSetManager> CreateNodeContextDescriptorSetManager() = 0; 221 virtual BASE_NS::unique_ptr<NodeContextPoolManager> CreateNodeContextPoolManager( 222 class GpuResourceManager& gpuResourceMgr, const GpuQueue& gpuQueue) = 0; 223 224 virtual BASE_NS::unique_ptr<GraphicsPipelineStateObject> CreateGraphicsPipelineStateObject( 225 const GpuShaderProgram& gpuProgram, const GraphicsState& graphicsState, const PipelineLayout& pipelineLayout, 226 const VertexInputDeclarationView& vertexInputDeclarationView, 227 const ShaderSpecializationConstantDataView& shaderSpecializationConstantDataView, 228 const BASE_NS::array_view<const DynamicStateEnum> dynamicStates, const RenderPassDesc& renderPassDesc, 229 const BASE_NS::array_view<const RenderPassSubpassDesc>& renderPassSubpassDesc, const uint32_t subpassIndex, 230 const LowLevelRenderPassData* renderPassData, const LowLevelPipelineLayoutData* pipelineLayoutData) = 0; 231 232 virtual BASE_NS::unique_ptr<ComputePipelineStateObject> CreateComputePipelineStateObject( 233 const GpuComputeProgram& gpuProgram, const PipelineLayout& pipelineLayout, 234 const ShaderSpecializationConstantDataView& shaderSpecializationConstantDataView, 235 const LowLevelPipelineLayoutData* pipelineLayoutData) = 0; 236 237 virtual BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphore() = 0; 238 virtual BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphoreView(const uint64_t handle) = 0; 239 240 // returns a valid queue from the same family or default queue 241 virtual GpuQueue GetValidGpuQueue(const GpuQueue& gpuQueue) const = 0; 242 virtual uint32_t GetGpuQueueCount() const = 0; 243 244 /** Initialize cache for accelerating pipeline state object creation. Caching is not used unless this function is 245 * called. 246 * @param initialData Optional cache content returned by GetPipelineCache. 247 */ 248 virtual void InitializePipelineCache(BASE_NS::array_view<const uint8_t> initialData) = 0; 249 virtual BASE_NS::vector<uint8_t> GetPipelineCache() const = 0; 250 251 protected: 252 RenderContext& renderContext_; 253 DeviceConfiguration deviceConfiguration_; 254 255 BASE_NS::unique_ptr<GpuResourceManager> gpuResourceMgr_; 256 BASE_NS::unique_ptr<ShaderManager> shaderMgr_; 257 258 // multi-swapchain, the built-in default is only with swapchain_ and swapchainData_ 259 BASE_NS::vector<InternalSwapchainData> swapchains_; 260 RenderHandleReference defaultSwapchainHandle_; 261 262 std::atomic<bool> deviceStatus_ { false }; 263 uint64_t frameCount_ { 0 }; 264 265 bool isRenderbackendRunning_ { false }; 266 bool isBackendResourceAccessLocked_ { false }; 267 bool isRenderFrameRunning_ { false }; 268 269 MemoryPropertyFlags deviceSharedMemoryPropertyFlags_ { 0 }; 270 CommonDeviceProperties commonDeviceProperties_; 271 }; 272 273 // Plaform specific helper 274 GpuImageDesc GetImageDescFromHwBufferDesc(uintptr_t platformHwBuffer); 275 RENDER_END_NAMESPACE() 276 277 #endif // DEVICE_DEVICE_H 278