// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #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; } /// /// GPU resources types. /// API_ENUM() enum class GPUResourceType { // GPU render target texture RenderTarget = 0, // GPU texture Texture, // GPU cube texture (cubemap) CubeTexture, // GPU volume texture (3D) VolumeTexture, // GPU buffer Buffer, // GPU shader Shader, // GPU pipeline state object (PSO) PipelineState, // GPU binding descriptor Descriptor, // GPU timer query Query, // GPU texture sampler Sampler, MAX }; /// /// The base class for all GPU resources. /// API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API GPUResource : public ScriptingObject { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResource); protected: uint64 _memoryUsage = 0; #if GPU_ENABLE_RESOURCE_NAMING Char* _namePtr = nullptr; int32 _nameSize = 0, _nameCapacity = 0; #endif 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 GPU resource type. /// API_PROPERTY() virtual GPUResourceType GetResourceType() const = 0; /// /// 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 !BUILD_RELEASE /// /// Gets the resource name. /// API_PROPERTY() StringView GetName() const; /// /// Sets the resource name. /// API_PROPERTY() void SetName(const StringView& name); #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; public: /// /// Initializes a new instance of the class. /// /// The graphics device. /// The resource name. GPUResourceBase(DeviceType* device, const StringView& name) noexcept : BaseType() , _device(device) { #if GPU_ENABLE_RESOURCE_NAMING if (name.HasChars()) GPUResource::SetName(name); #endif device->AddResource(this); } /// /// Finalizes an instance of the class. /// virtual ~GPUResourceBase() { if (_device) _device->RemoveResource(this); } public: /// /// Gets the graphics device. /// FORCE_INLINE DeviceType* GetDevice() const { return _device; } public: // [GPUResource] 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; GPUResource* _parent = nullptr; 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 parent GPU resource owning that view. /// API_PROPERTY() FORCE_INLINE GPUResource* GetParent() const { return _parent; } /// /// Gets the native pointer to the underlying view. It's a platform-specific handle. /// virtual void* GetNativePtr() const = 0; };