// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Enums.h" #include "Engine/Scripting/ScriptingObject.h" #include "Config.h" /// /// Releases GPU resource memory and deletes object. /// #define SAFE_DELETE_GPU_RESOURCE(x) if (x) { (x)->DeleteObjectNow(); (x) = nullptr; } #define SAFE_DELETE_GPU_RESOURCES(x) for (auto& e : (x)) if (e) { e->DeleteObjectNow(); e = nullptr; } /// /// The base class for all GPU resources. /// API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API GPUResource : public ScriptingObject { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResource); public: /// /// GPU Resources types. /// DECLARE_ENUM_10(ResourceType, RenderTarget, Texture, CubeTexture, VolumeTexture, Buffer, Shader, PipelineState, Descriptor, Query, Sampler); /// /// GPU Resources object types. Used to detect Texture objects from subset of Types: RenderTarget, Texture, CubeTexture, VolumeTexture which use the same API object. /// DECLARE_ENUM_3(ObjectType, Texture, Buffer, Other); protected: uint64 _memoryUsage = 0; public: NON_COPYABLE(GPUResource); /// /// Initializes a new instance of the class. /// GPUResource(); /// /// Initializes a new instance of the class. /// /// The object initialization parameters. GPUResource(const SpawnParams& params); /// /// Finalizes an instance of the class. /// virtual ~GPUResource(); public: // Points to the cache used by the resource for the resource visibility/usage detection. Written during rendering when resource is used. double LastRenderTime = -1; /// /// Action fired when resource GPU state gets released. All objects and async tasks using this resource should release references to this object nor use its data. /// Action Releasing; public: /// /// Gets the resource type. /// virtual ResourceType GetResourceType() const = 0; /// /// Gets resource object type. /// virtual ObjectType GetObjectType() const; /// /// Gets amount of GPU memory used by this resource (in bytes). It's a rough estimation. GPU memory may be fragmented, compressed or sub-allocated so the actual memory pressure from this resource may vary (also depends on the current graphics backend). /// API_PROPERTY() uint64 GetMemoryUsage() const; #if GPU_ENABLE_RESOURCE_NAMING /// /// Gets the resource name. /// virtual String GetName() const; #endif /// /// Releases GPU resource data. /// API_FUNCTION() void ReleaseGPU(); /// /// Action called when GPU device is disposing. /// virtual void OnDeviceDispose(); protected: /// /// Releases GPU resource data (implementation). /// virtual void OnReleaseGPU(); public: // [ScriptingObject] String ToString() const override; void OnDeleteObject() override; }; /// /// Describes base implementation of Graphics Device resource for rendering back-ends. /// /// /// DeviceType is GPU device typename, BaseType must be GPUResource type to inherit from). /// template class GPUResourceBase : public BaseType { protected: DeviceType* _device; private: #if GPU_ENABLE_RESOURCE_NAMING String _name; #endif public: /// /// Initializes a new instance of the class. /// /// The graphics device. /// The resource name. GPUResourceBase(DeviceType* device, const StringView& name) noexcept : _device(device) #if GPU_ENABLE_RESOURCE_NAMING , _name(name.Get(), name.Length()) #endif { device->Resources.Add(this); } /// /// Finalizes an instance of the class. /// virtual ~GPUResourceBase() { if (_device) _device->Resources.Remove(this); } public: /// /// Gets the graphics device. /// FORCE_INLINE DeviceType* GetDevice() const { return _device; } public: // [GPUResource] #if GPU_ENABLE_RESOURCE_NAMING String GetName() const override { return _name; } #endif void OnDeviceDispose() override { GPUResource::OnDeviceDispose(); _device = nullptr; } }; /// /// Interface for GPU resources views. Shared base class for texture and buffer views. /// API_CLASS(Abstract, NoSpawn, Attributes="HideInEditor") class FLAXENGINE_API GPUResourceView : public ScriptingObject { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResourceView); protected: static double DummyLastRenderTime; explicit GPUResourceView(const SpawnParams& params) : ScriptingObject(params) , LastRenderTime(&DummyLastRenderTime) { } public: // Points to the cache used by the resource for the resource visibility/usage detection. Written during rendering when resource view is used. double* LastRenderTime; /// /// Gets the native pointer to the underlying view. It's a platform-specific handle. /// virtual void* GetNativePtr() const = 0; };