// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Platform/Platform.h" #include "Engine/Platform/CriticalSection.h" #include "Engine/Core/NonCopyable.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Scripting/ScriptingObject.h" #include "GPUAdapter.h" #include "GPULimits.h" #include "Enums.h" #include "Config.h" class ITextureOwner; class RenderTask; class GPUResource; class GPUContext; class GPUShader; class GPUTimerQuery; class GPUTexture; class GPUBuffer; class GPUSampler; class GPUPipelineState; class GPUConstantBuffer; class GPUTasksContext; class GPUTasksExecutor; class GPUSwapChain; class GPUTasksManager; class Shader; class Model; class Material; class MaterialBase; /// /// Graphics device object for rendering on GPU. /// API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUDevice : public ScriptingObject { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUDevice); public: /// /// Graphics Device states that describe its lifetime. /// enum class DeviceState { Missing = 0, Created, Ready, Removed, Disposing, Disposed }; /// /// Describes a video output display mode. /// API_STRUCT() struct VideoOutputMode { DECLARE_SCRIPTING_TYPE_NO_SPAWN(VideoOutputMode); /// /// The resolution width (in pixel). /// API_FIELD() uint32 Width; /// /// The resolution height (in pixel). /// API_FIELD() uint32 Height; /// /// The screen refresh rate (in hertz). /// API_FIELD() uint32 RefreshRate; }; /// /// The singleton instance of the graphics device. /// API_FIELD(ReadOnly) static GPUDevice* Instance; protected: // State DeviceState _state; bool _isRendering; bool _wasVSyncUsed; int32 _drawGpuEventIndex; RendererType _rendererType; ShaderProfile _shaderProfile; FeatureLevel _featureLevel; // Private resources (hidden with declaration) struct PrivateData; PrivateData* _res; Array _resources; CriticalSection _resourcesLock; protected: /// /// Initializes a new instance of the class. /// /// The renderer type. /// The shader profile. GPUDevice(RendererType type, ShaderProfile profile); public: /// /// Finalizes an instance of the class. /// virtual ~GPUDevice(); public: /// /// The graphics device locking mutex. /// CriticalSection Locker; /// /// The total amount of graphics memory in bytes. /// API_FIELD(ReadOnly) uint64 TotalGraphicsMemory; /// /// The GPU limits. /// API_FIELD(ReadOnly) GPULimits Limits; /// /// The available video output modes. /// API_FIELD(ReadOnly) Array VideoOutputModes; /// /// Quad rendering shader /// API_FIELD(ReadOnly) GPUShader* QuadShader; /// /// The current task being executed. /// RenderTask* CurrentTask; /// /// The supported features for the specified format (index is the pixel format value). /// FormatFeatures FeaturesPerFormat[static_cast(PixelFormat::MAX)]; /// /// Gets the supported features for the specified format (index is the pixel format value). /// /// The format. /// The format features flags. API_FUNCTION() FormatFeatures GetFormatFeatures(const PixelFormat format) const { return FeaturesPerFormat[(int32)format]; } public: /// /// Gets current device state. /// FORCE_INLINE DeviceState GetState() const { return _state; } /// /// Returns true if device is during rendering state, otherwise false. /// API_PROPERTY() FORCE_INLINE bool IsRendering() const { return _isRendering; } /// /// Returns true if VSync was used during the last frame present. /// FORCE_INLINE bool WasVSyncUsed() const { return _wasVSyncUsed; } /// /// Gets the device renderer type. /// API_PROPERTY() FORCE_INLINE RendererType GetRendererType() const { return _rendererType; } /// /// Gets device shader profile type. /// API_PROPERTY() FORCE_INLINE ShaderProfile GetShaderProfile() const { return _shaderProfile; } /// /// Gets device feature level type. /// API_PROPERTY() FORCE_INLINE FeatureLevel GetFeatureLevel() const { return _featureLevel; } /// /// Gets the main GPU context. /// API_PROPERTY() virtual GPUContext* GetMainContext() = 0; /// /// Gets the adapter device. /// API_PROPERTY() virtual GPUAdapter* GetAdapter() const = 0; /// /// Gets the native pointer to the underlying graphics device. It's a low-level platform-specific handle. /// API_PROPERTY() virtual void* GetNativePtr() const = 0; /// /// Gets the amount of memory usage by all the GPU resources (in bytes). /// API_PROPERTY() uint64 GetMemoryUsage() const; /// /// Gets the list with all active GPU resources. /// API_PROPERTY() Array GetResources() const; /// /// Gets the GPU asynchronous work manager. /// GPUTasksManager* GetTasksManager() const; /// /// Gets the default material. /// API_PROPERTY() MaterialBase* GetDefaultMaterial() const; /// /// Gets the default material (Deformable domain). /// MaterialBase* GetDefaultDeformableMaterial() const; /// /// Gets the default normal map texture. /// GPUTexture* GetDefaultNormalMap() const; /// /// Gets the default solid white texture. /// API_PROPERTY() GPUTexture* GetDefaultWhiteTexture() const; /// /// Gets the default solid black texture. /// API_PROPERTY() GPUTexture* GetDefaultBlackTexture() const; /// /// Gets the shader pipeline state object for linear, fullscreen texture copy. /// GPUPipelineState* GetCopyLinearPS() const; /// /// Gets the shader pipeline state object for solid-color texture clear. /// GPUPipelineState* GetClearPS() const; /// /// Gets the shader pipeline state object for YUY2 frame decoding to RGBA. /// GPUPipelineState* GetDecodeYUY2PS() const; /// /// Gets the shader pipeline state object for NV12 frame decoding to RGBA. /// GPUPipelineState* GetDecodeNV12PS() const; /// /// Gets the fullscreen-triangle vertex buffer. /// GPUBuffer* GetFullscreenTriangleVB() const; public: /// /// Init device resources /// /// True if cannot init, otherwise false. virtual bool Init(); /// /// Load private device content (called when Content Pool is created) /// /// True if cannot load data in a proper way, otherwise false. virtual bool LoadContent(); /// /// Checks if GPU can render frame now (all data is ready), otherwise will skip frame rendering. /// /// True if skip rendering, otherwise false. virtual bool CanDraw(); /// /// Call frame rendering and process data using GPU /// virtual void Draw(); /// /// Clean all allocated data by device /// virtual void Dispose(); /// /// Wait for GPU end doing submitted work /// virtual void WaitForGPU() = 0; public: void AddResource(GPUResource* resource); void RemoveResource(GPUResource* resource); /// /// Dumps all GPU resources information to the log. /// void DumpResourcesToLog() const; protected: virtual void preDispose(); /// /// Called during Draw method before any frame rendering initialization. Cannot be used to submit commands to GPU. /// virtual void DrawBegin(); /// /// Called during Draw method after rendering. Cannot be used to submit commands to GPU. /// virtual void DrawEnd(); /// /// Called during Draw method after rendering begin. Can be used to submit commands to the GPU after opening GPU command list. /// virtual void RenderBegin(); /// /// Called during Draw method before rendering end. Can be used to submit commands to the GPU before closing GPU command list. /// virtual void RenderEnd(); public: /// /// Creates the texture. /// /// The resource name. /// The texture. API_FUNCTION() virtual GPUTexture* CreateTexture(const StringView& name = StringView::Empty) = 0; /// /// Creates the shader. /// /// The resource name. /// The shader. virtual GPUShader* CreateShader(const StringView& name = StringView::Empty) = 0; /// /// Creates the GPU pipeline state object. /// /// The pipeline state. virtual GPUPipelineState* CreatePipelineState() = 0; /// /// Creates the timer query object. /// /// The timer query. virtual GPUTimerQuery* CreateTimerQuery() = 0; /// /// Creates the buffer. /// /// The resource name. /// The buffer. API_FUNCTION() virtual GPUBuffer* CreateBuffer(const StringView& name = StringView::Empty) = 0; /// /// Creates the texture sampler. /// /// The sampler. API_FUNCTION() virtual GPUSampler* CreateSampler() = 0; /// /// Creates the native window swap chain. /// /// The output window. /// The native window swap chain. virtual GPUSwapChain* CreateSwapChain(Window* window) = 0; /// /// Creates the constant buffer. /// /// The resource name. /// The buffer size (in bytes). /// The constant buffer. virtual GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name = StringView::Empty) = 0; /// /// Creates the GPU tasks context. /// /// The GPU tasks context. virtual GPUTasksContext* CreateTasksContext(); /// /// Creates the GPU tasks executor. /// /// The GPU tasks executor. virtual GPUTasksExecutor* CreateTasksExecutor(); }; /// /// Utility structure to safety graphics device locking. /// struct FLAXENGINE_API GPUDeviceLock : NonCopyable { const GPUDevice* Device; GPUDeviceLock(const GPUDevice* device) : Device(device) { Device->Locker.Lock(); } ~GPUDeviceLock() { Device->Locker.Unlock(); } };