Revert d3c49be80f and do it better

This commit is contained in:
Wojtek Figat
2025-04-17 10:52:00 +02:00
parent 414b229b27
commit ef188d06c4
4 changed files with 27 additions and 44 deletions

View File

@@ -58,8 +58,6 @@ protected:
{ {
} }
~GPUTask();
public: public:
/// <summary> /// <summary>
/// Gets a task type. /// Gets a task type.
@@ -142,24 +140,5 @@ protected:
return true; return true;
} }
void OnCancel() override void OnCancel() override;
{
// Check if task is waiting for sync (very likely situation)
if (IsSyncing())
{
// Task has been performed but is waiting for a CPU/GPU sync so we have to cancel that
ASSERT(_context != nullptr);
_context->OnCancelSync(this);
_context = nullptr;
SetState(TaskState::Canceled);
}
else
{
// Maybe we could also handle cancel event during running but not yet syncing
ASSERT(!IsRunning());
}
// Base
Task::OnCancel();
}
}; };

View File

@@ -10,8 +10,6 @@
#define GPU_TASKS_USE_DEDICATED_CONTEXT 0 #define GPU_TASKS_USE_DEDICATED_CONTEXT 0
GPUTasksContext::GPUTasksContext(GPUDevice* device) GPUTasksContext::GPUTasksContext(GPUDevice* device)
: _tasksDone(64)
, _totalTasksDoneCount(0)
{ {
// Bump it up to prevent initial state problems with frame index comparison // Bump it up to prevent initial state problems with frame index comparison
_currentSyncPoint = 10; _currentSyncPoint = 10;
@@ -30,8 +28,8 @@ GPUTasksContext::~GPUTasksContext()
ASSERT(IsInMainThread()); ASSERT(IsInMainThread());
// Cancel jobs to sync // Cancel jobs to sync
auto tasks = _tasksDone; auto tasks = _tasksSyncing;
_tasksDone.Clear(); _tasksSyncing.Clear();
for (int32 i = 0; i < tasks.Count(); i++) for (int32 i = 0; i < tasks.Count(); i++)
{ {
auto task = tasks[i]; auto task = tasks[i];
@@ -52,15 +50,16 @@ void GPUTasksContext::Run(GPUTask* task)
{ {
ASSERT(task != nullptr); ASSERT(task != nullptr);
_tasksDone.Add(task);
task->Execute(this); task->Execute(this);
if (task->IsSyncing())
_tasksSyncing.Add(task);
} }
void GPUTasksContext::OnCancelSync(GPUTask* task) void GPUTasksContext::OnCancelSync(GPUTask* task)
{ {
ASSERT(task != nullptr); ASSERT(task != nullptr);
_tasksDone.Remove(task); _tasksSyncing.Remove(task);
if (!Engine::IsRequestingExit) if (!Engine::IsRequestingExit)
LOG(Warning, "{0} has been canceled before a sync", task->ToString()); LOG(Warning, "{0} has been canceled before a sync", task->ToString());
@@ -76,9 +75,9 @@ void GPUTasksContext::OnFrameBegin()
++_currentSyncPoint; ++_currentSyncPoint;
// Try to flush done jobs // Try to flush done jobs
for (int32 i = 0; i < _tasksDone.Count(); i++) for (int32 i = 0; i < _tasksSyncing.Count(); i++)
{ {
auto task = _tasksDone[i]; auto task = _tasksSyncing[i];
auto state = task->GetState(); auto state = task->GetState();
if (task->GetSyncPoint() <= _currentSyncPoint && state != TaskState::Finished) if (task->GetSyncPoint() <= _currentSyncPoint && state != TaskState::Finished)
{ {
@@ -87,12 +86,12 @@ void GPUTasksContext::OnFrameBegin()
} }
if (state == TaskState::Failed || state == TaskState::Canceled) if (state == TaskState::Failed || state == TaskState::Canceled)
{ {
_tasksDone.RemoveAt(i); _tasksSyncing.RemoveAt(i);
i--; i--;
} }
if (state == TaskState::Finished) if (state == TaskState::Finished)
{ {
_tasksDone.RemoveAt(i); _tasksSyncing.RemoveAt(i);
i--; i--;
_totalTasksDoneCount++; _totalTasksDoneCount++;
} }

View File

@@ -17,8 +17,8 @@ class GPUTasksContext
protected: protected:
CriticalSection _locker; CriticalSection _locker;
GPUSyncPoint _currentSyncPoint; GPUSyncPoint _currentSyncPoint;
Array<GPUTask*> _tasksDone; int32 _totalTasksDoneCount = 0;
int32 _totalTasksDoneCount; Array<GPUTask*, InlinedAllocation<64>> _tasksSyncing;
public: public:
/// <summary> /// <summary>

View File

@@ -7,16 +7,6 @@
#include "Engine/Core/Types/String.h" #include "Engine/Core/Types/String.h"
#include "Engine/Graphics/GPUDevice.h" #include "Engine/Graphics/GPUDevice.h"
GPUTask::~GPUTask()
{
// Ensure to dereference task
if (auto context = _context)
{
_context = nullptr;
context->OnCancelSync(this);
}
}
void GPUTask::Execute(GPUTasksContext* context) void GPUTask::Execute(GPUTasksContext* context)
{ {
ASSERT(IsQueued() && _context == nullptr); ASSERT(IsQueued() && _context == nullptr);
@@ -58,6 +48,21 @@ void GPUTask::Enqueue()
GPUDevice::Instance->GetTasksManager()->_tasks.Add(this); GPUDevice::Instance->GetTasksManager()->_tasks.Add(this);
} }
void GPUTask::OnCancel()
{
// Check if task is waiting for sync (very likely situation)
if (IsSyncing())
{
// Task has been performed but is waiting for a CPU/GPU sync so we have to cancel that
ASSERT(_context != nullptr);
_context->OnCancelSync(this);
_context = nullptr;
}
// Base
Task::OnCancel();
}
GPUTasksManager::GPUTasksManager() GPUTasksManager::GPUTasksManager()
{ {
_buffers[0].EnsureCapacity(64); _buffers[0].EnsureCapacity(64);