Refactor GPUResourceProperty

This commit is contained in:
Wojtek Figat
2023-11-04 20:04:40 +01:00
parent 22e34cb2b4
commit 4a10878b45
8 changed files with 111 additions and 113 deletions

View File

@@ -9,9 +9,6 @@
/// </summary>
class FLAXENGINE_API AssetReferenceBase
{
public:
typedef Delegate<> EventType;
protected:
Asset* _asset = nullptr;
@@ -19,17 +16,17 @@ public:
/// <summary>
/// The asset loaded event (fired when asset gets loaded or is already loaded after change).
/// </summary>
EventType Loaded;
Action Loaded;
/// <summary>
/// The asset unloading event (should cleanup refs to it).
/// </summary>
EventType Unload;
Action Unload;
/// <summary>
/// Action fired when field gets changed (link a new asset or change to the another value).
/// </summary>
EventType Changed;
Action Changed;
public:
NON_COPYABLE(AssetReferenceBase);

View File

@@ -26,12 +26,12 @@ public:
, _srcResource(src)
, _dstResource(dst)
{
_srcResource.OnUnload.Bind<GPUCopyResourceTask, &GPUCopyResourceTask::OnResourceUnload>(this);
_dstResource.OnUnload.Bind<GPUCopyResourceTask, &GPUCopyResourceTask::OnResourceUnload>(this);
_srcResource.Released.Bind<GPUCopyResourceTask, &GPUCopyResourceTask::OnResourceReleased>(this);
_dstResource.Released.Bind<GPUCopyResourceTask, &GPUCopyResourceTask::OnResourceReleased>(this);
}
private:
void OnResourceUnload(GPUResourceReference* ref)
void OnResourceReleased()
{
Cancel();
}
@@ -47,14 +47,11 @@ protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
if (_srcResource.IsMissing() || _dstResource.IsMissing())
if (!_srcResource || !_dstResource)
return Result::MissingResources;
context->GPU->CopyResource(_dstResource, _srcResource);
return Result::Ok;
}
void OnEnd() override
{
_srcResource.Unlink();

View File

@@ -31,12 +31,12 @@ public:
, _srcSubresource(srcSubresource)
, _dstSubresource(dstSubresource)
{
_srcResource.OnUnload.Bind<GPUCopySubresourceTask, &GPUCopySubresourceTask::OnResourceUnload>(this);
_dstResource.OnUnload.Bind<GPUCopySubresourceTask, &GPUCopySubresourceTask::OnResourceUnload>(this);
_srcResource.Released.Bind<GPUCopySubresourceTask, &GPUCopySubresourceTask::OnResourceReleased>(this);
_dstResource.Released.Bind<GPUCopySubresourceTask, &GPUCopySubresourceTask::OnResourceReleased>(this);
}
private:
void OnResourceUnload(GPUResourceReference* ref)
void OnResourceReleased()
{
Cancel();
}
@@ -52,14 +52,11 @@ protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
if (_srcResource.IsMissing() || _dstResource.IsMissing())
if (!_srcResource || !_dstResource)
return Result::MissingResources;
context->GPU->CopySubresource(_dstResource, _dstSubresource, _srcResource, _srcSubresource);
return Result::Ok;
}
void OnEnd() override
{
_srcResource.Unlink();

View File

@@ -31,7 +31,7 @@ public:
, _buffer(buffer)
, _offset(offset)
{
_buffer.OnUnload.Bind<GPUUploadBufferTask, &GPUUploadBufferTask::OnResourceUnload>(this);
_buffer.Released.Bind<GPUUploadBufferTask, &GPUUploadBufferTask::OnResourceReleased>(this);
if (copyData)
_data.Copy(data);
@@ -40,7 +40,7 @@ public:
}
private:
void OnResourceUnload(BufferReference* ref)
void OnResourceReleased()
{
Cancel();
}
@@ -56,14 +56,11 @@ protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
if (_buffer.IsMissing())
if (!_buffer)
return Result::MissingResources;
context->GPU->UpdateBuffer(_buffer, _data.Get(), _data.Length(), _offset);
return Result::Ok;
}
void OnEnd() override
{
_buffer.Unlink();

View File

@@ -35,7 +35,7 @@ public:
, _rowPitch(rowPitch)
, _slicePitch(slicePitch)
{
_texture.OnUnload.Bind<GPUUploadTextureMipTask, &GPUUploadTextureMipTask::OnResourceUnload>(this);
_texture.Released.Bind<GPUUploadTextureMipTask, &GPUUploadTextureMipTask::OnResourceReleased>(this);
if (copyData)
_data.Copy(data);
@@ -44,7 +44,7 @@ public:
}
private:
void OnResourceUnload(GPUTextureReference* ref)
void OnResourceReleased()
{
Cancel();
}

View File

@@ -3,6 +3,7 @@
#include "GPUDevice.h"
#include "RenderTargetPool.h"
#include "GPUPipelineState.h"
#include "GPUResourceProperty.h"
#include "GPUSwapChain.h"
#include "RenderTask.h"
#include "RenderTools.h"
@@ -25,6 +26,39 @@
#include "Engine/Renderer/RenderList.h"
#include "Engine/Scripting/Enums.h"
GPUResourcePropertyBase::~GPUResourcePropertyBase()
{
const auto e = _resource;
if (e)
{
_resource = nullptr;
e->Releasing.Unbind<GPUResourcePropertyBase, &GPUResourcePropertyBase::OnReleased>(this);
}
}
void GPUResourcePropertyBase::OnSet(GPUResource* resource)
{
auto e = _resource;
if (e != resource)
{
if (e)
e->Releasing.Unbind<GPUResourcePropertyBase, &GPUResourcePropertyBase::OnReleased>(this);
_resource = e = resource;
if (e)
e->Releasing.Bind<GPUResourcePropertyBase, &GPUResourcePropertyBase::OnReleased>(this);
}
}
void GPUResourcePropertyBase::OnReleased()
{
auto e = _resource;
if (e)
{
_resource = nullptr;
e->Releasing.Unbind<GPUResourcePropertyBase, &GPUResourcePropertyBase::OnReleased>(this);
}
}
GPUPipelineState* GPUPipelineState::Spawn(const SpawnParams& params)
{
return GPUDevice::Instance->CreatePipelineState();

View File

@@ -8,28 +8,39 @@
/// <summary>
/// GPU Resource container utility object.
/// </summary>
template<typename T = GPUResource>
class GPUResourceProperty
class FLAXENGINE_API GPUResourcePropertyBase
{
private:
T* _resource;
protected:
GPUResource* _resource = nullptr;
private:
// Disable copy actions
GPUResourceProperty(const GPUResourceProperty& other) = delete;
public:
NON_COPYABLE(GPUResourcePropertyBase);
GPUResourcePropertyBase() = default;
~GPUResourcePropertyBase();
public:
/// <summary>
/// Action fired when resource gets unloaded (reference gets cleared bu async tasks should stop execution).
/// Action fired when resource gets released (reference gets cleared bu async tasks should stop execution).
/// </summary>
Delegate<GPUResourceProperty*> OnUnload;
Action Released;
protected:
void OnSet(GPUResource* resource);
void OnReleased();
};
/// <summary>
/// GPU Resource container utility object.
/// </summary>
template<typename T = GPUResource>
class GPUResourceProperty : public GPUResourcePropertyBase
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUResourceProperty"/> class.
/// </summary>
GPUResourceProperty()
: _resource(nullptr)
{
}
@@ -38,9 +49,37 @@ public:
/// </summary>
/// <param name="resource">The resource.</param>
GPUResourceProperty(T* resource)
: _resource(nullptr)
{
Set(resource);
OnSet(resource);
}
/// <summary>
/// Initializes a new instance of the <see cref="GPUResourceProperty"/> class.
/// </summary>
/// <param name="other">The other value.</param>
GPUResourceProperty(const GPUResourceProperty& other)
{
OnSet(other.Get());
}
/// <summary>
/// Initializes a new instance of the <see cref="GPUResourceProperty"/> class.
/// </summary>
/// <param name="other">The other value.</param>
GPUResourceProperty(GPUResourceProperty&& other)
{
OnSet(other.Get());
other.OnSet(nullptr);
}
GPUResourceProperty& operator=(GPUResourceProperty&& other)
{
if (&other != this)
{
OnSet(other._resource);
other.OnSet(nullptr);
}
return *this;
}
/// <summary>
@@ -48,13 +87,6 @@ public:
/// </summary>
~GPUResourceProperty()
{
// Check if object has been binded
if (_resource)
{
// Unlink
_resource->Releasing.template Unbind<GPUResourceProperty, &GPUResourceProperty::onResourceUnload>(this);
_resource = nullptr;
}
}
public:
@@ -63,43 +95,34 @@ public:
return Get() == other;
}
FORCE_INLINE bool operator==(GPUResourceProperty& other) const
FORCE_INLINE bool operator==(const GPUResourceProperty& other) const
{
return Get() == other.Get();
}
GPUResourceProperty& operator=(const GPUResourceProperty& other)
{
if (this != &other)
Set(other.Get());
return *this;
}
FORCE_INLINE GPUResourceProperty& operator=(T& other)
{
Set(&other);
OnSet(&other);
return *this;
}
FORCE_INLINE GPUResourceProperty& operator=(T* other)
{
Set(other);
OnSet(other);
return *this;
}
/// <summary>
/// Implicit conversion to GPU Resource
/// </summary>
/// <returns>Resource</returns>
FORCE_INLINE operator T*() const
{
return _resource;
return (T*)_resource;
}
/// <summary>
/// Implicit conversion to resource
/// </summary>
/// <returns>True if resource has been binded, otherwise false</returns>
FORCE_INLINE operator bool() const
{
return _resource != nullptr;
@@ -108,37 +131,17 @@ public:
/// <summary>
/// Implicit conversion to resource
/// </summary>
/// <returns>Resource</returns>
FORCE_INLINE T* operator->() const
{
return _resource;
return (T*)_resource;
}
/// <summary>
/// Gets linked resource
/// </summary>
/// <returns>Resource</returns>
FORCE_INLINE T* Get() const
{
return _resource;
}
/// <summary>
/// Checks if resource has been binded
/// </summary>
/// <returns>True if resource has been binded, otherwise false</returns>
FORCE_INLINE bool IsBinded() const
{
return _resource != nullptr;
}
/// <summary>
/// Checks if resource is missing
/// </summary>
/// <returns>True if resource is missing, otherwise false</returns>
FORCE_INLINE bool IsMissing() const
{
return _resource == nullptr;
return (T*)_resource;
}
public:
@@ -148,19 +151,7 @@ public:
/// <param name="value">Value to assign</param>
void Set(T* value)
{
if (_resource != value)
{
// Remove reference from the old one
if (_resource)
_resource->Releasing.template Unbind<GPUResourceProperty, &GPUResourceProperty::onResourceUnload>(this);
// Change referenced object
_resource = value;
// Add reference to the new one
if (_resource)
_resource->Releasing.template Bind<GPUResourceProperty, &GPUResourceProperty::onResourceUnload>(this);
}
OnSet(value);
}
/// <summary>
@@ -168,22 +159,7 @@ public:
/// </summary>
void Unlink()
{
if (_resource)
{
// Remove reference from the old one
_resource->Releasing.template Unbind<GPUResourceProperty, &GPUResourceProperty::onResourceUnload>(this);
_resource = nullptr;
}
}
private:
void onResourceUnload()
{
if (_resource)
{
_resource = nullptr;
OnUnload(this);
}
OnSet(nullptr);
}
};

View File

@@ -329,11 +329,11 @@ public:
, _dataLock(_streamingTexture->GetOwner()->LockData())
{
_streamingTexture->_streamingTasks.Add(this);
_texture.OnUnload.Bind<StreamTextureMipTask, &StreamTextureMipTask::onResourceUnload2>(this);
_texture.Released.Bind<StreamTextureMipTask, &StreamTextureMipTask::OnResourceReleased2>(this);
}
private:
void onResourceUnload2(GPUTextureReference* ref)
void OnResourceReleased2()
{
// Unlink texture
if (_streamingTexture)