// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#pragma once
#include "../GPUTask.h"
#include "../GPUTasksContext.h"
#include "Engine/Graphics/GPUBuffer.h"
#include "Engine/Graphics/GPUResourceProperty.h"
#include "Engine/Core/Types/DataContainer.h"
///
/// GPU buffer upload task.
///
class GPUUploadBufferTask : public GPUTask
{
protected:
BufferReference _buffer;
int32 _offset;
BytesContainer _data;
public:
///
/// Initializes a new instance of the class.
///
/// The target buffer.
/// The target buffer offset to copy data to. The default value is 0.
/// The data to upload.
/// True if copy data to the temporary buffer, otherwise the input data will be used directly. Then ensure it is valid during the copy operation period (for the next few frames).
GPUUploadBufferTask(GPUBuffer* buffer, int32 offset, Span data, bool copyData)
: GPUTask(Type::UploadBuffer)
, _buffer(buffer)
, _offset(offset)
{
_buffer.OnUnload.Bind(this);
if (copyData)
_data.Copy(data);
else
_data.Link(data);
}
private:
void OnResourceUnload(BufferReference* ref)
{
Cancel();
}
public:
// [GPUTask]
bool HasReference(Object* resource) const override
{
return _buffer == resource;
}
protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
if (_buffer.IsMissing())
return Result::MissingResources;
context->GPU->UpdateBuffer(_buffer, _data.Get(), _data.Length(), _offset);
return Result::Ok;
}
void OnEnd() override
{
_buffer.Unlink();
// Base
GPUTask::OnEnd();
}
};