// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Common.h" #include "Engine/Core/NonCopyable.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; } /// /// The base class for all GPU resources. /// API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API GPUResource : public PersistentScriptingObject, public NonCopyable { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResource); public: /// /// GPU Resources types. /// DECLARE_ENUM_9(ResourceType, RenderTarget, Texture, CubeTexture, VolumeTexture, Buffer, Shader, PipelineState, Descriptor, Query); /// /// 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: /// /// Initializes a new instance of the class. /// GPUResource() : PersistentScriptingObject(SpawnParams(Guid::New(), GPUResource::TypeInitializer)) { } /// /// Initializes a new instance of the class. /// /// The object initialization parameters. GPUResource(const SpawnParams& params) : PersistentScriptingObject(params) { } /// /// Finalizes an instance of the class. /// virtual ~GPUResource() { #if !BUILD_RELEASE ASSERT(_memoryUsage == 0); #endif } public: /// /// 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. /// /// The type. virtual ResourceType GetResourceType() const = 0; /// /// Gets resource object type. /// /// The object type. virtual ObjectType GetObjectType() const { return ObjectType::Other; } /// /// 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). /// /// The current memory usage. API_PROPERTY() FORCE_INLINE uint64 GetMemoryUsage() const { return _memoryUsage; } #if GPU_ENABLE_RESOURCE_NAMING /// /// Gets the resource name. /// /// The name of the resource. virtual String GetName() const { return String::Empty; } #endif /// /// Releases GPU resource data. /// API_FUNCTION() void ReleaseGPU() { if (_memoryUsage != 0) { Releasing(); OnReleaseGPU(); _memoryUsage = 0; } } /// /// Action called when GPU device is disposing. /// virtual void OnDeviceDispose() { // By default we want to release resource data but keep it alive ReleaseGPU(); } protected: /// /// Releases GPU resource data (implementation). /// virtual void OnReleaseGPU() { } public: // [PersistentScriptingObject] String ToString() const override { #if GPU_ENABLE_RESOURCE_NAMING return GetName(); #else return TEXT("GPU Resource"); #endif } void OnDeleteObject() override { ReleaseGPU(); PersistentScriptingObject::OnDeleteObject(); } }; /// /// 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 { ASSERT(device); // Register device->Resources.Add(this); } /// /// Finalizes an instance of the class. /// virtual ~GPUResourceBase() { // Unregister if (_device) _device->Resources.Remove(this); } public: /// /// Gets the graphics device. /// /// The 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 { // Base GPUResource::OnDeviceDispose(); // Unlink device handle _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 PersistentScriptingObject { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResourceView); protected: explicit GPUResourceView(const SpawnParams& params) : PersistentScriptingObject(params) { } public: /// /// Gets the native pointer to the underlying view. It's a platform-specific handle. /// /// The pointer. virtual void* GetNativePtr() const = 0; };