// 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;
};