Optimize Streaming service with Task Graph to use async update on a Job System

This commit is contained in:
Wojtek Figat
2021-07-02 14:56:46 +02:00
parent 22f4137703
commit 891961b03b

View File

@@ -4,9 +4,11 @@
#include "StreamableResource.h" #include "StreamableResource.h"
#include "StreamingGroup.h" #include "StreamingGroup.h"
#include "StreamingSettings.h" #include "StreamingSettings.h"
#include "Engine/Engine/Engine.h"
#include "Engine/Engine/EngineService.h" #include "Engine/Engine/EngineService.h"
#include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Threading/Threading.h" #include "Engine/Threading/Threading.h"
#include "Engine/Threading/TaskGraph.h"
#include "Engine/Threading/Task.h" #include "Engine/Threading/Task.h"
#include "Engine/Graphics/GPUDevice.h" #include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/Textures/GPUSampler.h" #include "Engine/Graphics/Textures/GPUSampler.h"
@@ -14,7 +16,6 @@
namespace StreamingManagerImpl namespace StreamingManagerImpl
{ {
DateTime LastUpdateTime(0);
int32 LastUpdateResourcesIndex = 0; int32 LastUpdateResourcesIndex = 0;
CriticalSection ResourcesLock; CriticalSection ResourcesLock;
Array<StreamableResource*> Resources; Array<StreamableResource*> Resources;
@@ -24,19 +25,31 @@ namespace StreamingManagerImpl
using namespace StreamingManagerImpl; using namespace StreamingManagerImpl;
class StreamingManagerService : public EngineService class StreamingService : public EngineService
{ {
public: public:
StreamingManagerService() StreamingService()
: EngineService(TEXT("Streaming Manager"), 100) : EngineService(TEXT("Streaming"), 100)
{ {
} }
void Update() override; bool Init() override;
void BeforeExit() override; void BeforeExit() override;
}; };
StreamingManagerService StreamingManagerServiceInstance; class StreamingSystem : public TaskGraphSystem
{
public:
void Job(int32 index);
void Execute(TaskGraph* graph) override;
};
namespace
{
TaskGraphSystem* System = nullptr;
}
StreamingService StreamingServiceInstance;
Array<TextureGroup, InlinedAllocation<32>> Streaming::TextureGroups; Array<TextureGroup, InlinedAllocation<32>> Streaming::TextureGroups;
@@ -176,26 +189,33 @@ void UpdateResource(StreamableResource* resource, DateTime now, double currentTi
// low mem should be updated once per a few frames // low mem should be updated once per a few frames
} }
void StreamingManagerService::Update() bool StreamingService::Init()
{ {
// Configuration System = New<StreamingSystem>();
// TODO: use game settings Engine::UpdateGraph->AddSystem(System);
static TimeSpan ManagerUpdatesInterval = TimeSpan::FromMilliseconds(30); return false;
static TimeSpan ResourceUpdatesInterval = TimeSpan::FromMilliseconds(100); }
static int32 MaxResourcesPerUpdate = 50;
// Check if skip update void StreamingService::BeforeExit()
auto now = DateTime::NowUTC(); {
auto delta = now - LastUpdateTime; SAFE_DELETE_GPU_RESOURCE(FallbackSampler);
ScopeLock lock(ResourcesLock); SAFE_DELETE_GPU_RESOURCES(TextureGroupSamplers);
const int32 resourcesCount = Resources.Count(); TextureGroupSamplers.Resize(0);
if (resourcesCount == 0 || delta < ManagerUpdatesInterval || GPUDevice::Instance->GetState() != GPUDevice::DeviceState::Ready) SAFE_DELETE(System);
return; }
LastUpdateTime = now;
PROFILE_CPU(); void StreamingSystem::Job(int32 index)
{
PROFILE_CPU_NAMED("Streaming.Job");
// TODO: use streaming settings
TimeSpan ResourceUpdatesInterval = TimeSpan::FromMilliseconds(100);
int32 MaxResourcesPerUpdate = 50;
// Start update // Start update
ScopeLock lock(ResourcesLock);
auto now = DateTime::NowUTC();
const int32 resourcesCount = Resources.Count();
int32 resourcesUpdates = Math::Min(MaxResourcesPerUpdate, resourcesCount); int32 resourcesUpdates = Math::Min(MaxResourcesPerUpdate, resourcesCount);
double currentTime = Platform::GetTimeSeconds(); double currentTime = Platform::GetTimeSeconds();
@@ -223,11 +243,15 @@ void StreamingManagerService::Update()
// TODO: add StreamingManager stats, update time per frame, updates per frame, etc. // TODO: add StreamingManager stats, update time per frame, updates per frame, etc.
} }
void StreamingManagerService::BeforeExit() void StreamingSystem::Execute(TaskGraph* graph)
{ {
SAFE_DELETE_GPU_RESOURCE(FallbackSampler); if (Resources.Count() == 0 || GPUDevice::Instance->GetState() != GPUDevice::DeviceState::Ready)
SAFE_DELETE_GPU_RESOURCES(TextureGroupSamplers); return;
TextureGroupSamplers.Resize(0);
// Schedule work to update all storage containers in async
Function<void(int32)> job;
job.Bind<StreamingSystem, &StreamingSystem::Job>(this);
graph->DispatchJob(job, 1);
} }
void Streaming::RequestStreamingUpdate() void Streaming::RequestStreamingUpdate()