Remove GPUResourcesCollection and use GPUDevice instead to simplify code

This commit is contained in:
Wojciech Figat
2022-12-07 15:32:23 +01:00
parent 3017010ef4
commit f2c594569d
5 changed files with 105 additions and 185 deletions

View File

@@ -10,18 +10,19 @@
#include "Shaders/GPUShader.h"
#include "Async/DefaultGPUTasksExecutor.h"
#include "Async/GPUTasksManager.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Utilities.h"
#include "Engine/Core/Types/StringBuilder.h"
#include "Engine/Content/Assets/Shader.h"
#include "Engine/Content/Assets/Material.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/SoftAssetReference.h"
#include "Engine/Core/Log.h"
#include "Engine/Render2D/Render2D.h"
#include "Engine/Engine/CommandLine.h"
#include "Engine/Engine/Engine.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Profiler/Profiler.h"
#include "Engine/Renderer/RenderList.h"
#include "Engine/Core/Utilities.h"
GPUPipelineState* GPUPipelineState::Spawn(const SpawnParams& params)
{
@@ -280,6 +281,7 @@ GPUDevice::GPUDevice(RendererType type, ShaderProfile profile)
, _shaderProfile(profile)
, _featureLevel(RenderTools::GetFeatureLevel(profile))
, _res(New<PrivateData>())
, _resources(1024)
, TotalGraphicsMemory(0)
, QuadShader(nullptr)
, CurrentTask(nullptr)
@@ -367,8 +369,69 @@ bool GPUDevice::CanDraw()
return true;
}
void GPUDevice::AddResource(GPUResource* resource)
{
Locker.Lock();
ASSERT(resource && !_resources.Contains(resource));
_resources.Add(resource);
Locker.Unlock();
}
void GPUDevice::RemoveResource(GPUResource* resource)
{
Locker.Lock();
ASSERT(resource && _resources.Contains(resource));
_resources.Remove(resource);
Locker.Unlock();
}
void GPUDevice::DumpResourcesToLog() const
{
StringBuilder output;
Locker.Lock();
output.AppendFormat(TEXT("GPU Resources dump. Count: {0}, total GPU memory used: {1}"), _resources.Count(), Utilities::BytesToText(GetMemoryUsage()));
output.AppendLine();
output.AppendLine();
for (int32 typeIndex = 0; typeIndex < GPUResource::ResourceType_Count; typeIndex++)
{
const auto type = static_cast<GPUResource::ResourceType>(typeIndex);
output.AppendFormat(TEXT("Group: {0}s"), GPUResource::ToString(type));
output.AppendLine();
int32 count = 0;
uint64 memUsage = 0;
for (int32 i = 0; i < _resources.Count(); i++)
{
const GPUResource* resource = _resources[i];
if (resource->GetResourceType() == type)
{
count++;
memUsage += resource->GetMemoryUsage();
auto str = resource->ToString();
if (str.HasChars())
{
output.Append(TEXT('\t'));
output.Append(str);
output.AppendLine();
}
}
}
output.AppendFormat(TEXT("Total count: {0}, memory usage: {1}"), count, Utilities::BytesToText(memUsage));
output.AppendLine();
output.AppendLine();
}
Locker.Unlock();
LOG_STR(Info, output.ToStringView());
}
void GPUDevice::preDispose()
{
Locker.Lock();
RenderTargetPool::Flush();
// Release resources
@@ -383,7 +446,12 @@ void GPUDevice::preDispose()
// Release GPU resources memory and unlink from device
// Note: after that no GPU resources should be used/created, only deleted
Resources.OnDeviceDispose();
for (int32 i = _resources.Count() - 1; i >= 0 && i < _resources.Count(); i--)
{
_resources[i]->OnDeviceDispose();
}
_resources.Clear();
Locker.Unlock();
}
void GPUDevice::DrawBegin()
@@ -520,7 +588,20 @@ void GPUDevice::Dispose()
uint64 GPUDevice::GetMemoryUsage() const
{
return Resources.GetMemoryUsage();
uint64 result = 0;
Locker.Lock();
for (int32 i = 0; i < _resources.Count(); i++)
result += _resources[i]->GetMemoryUsage();
Locker.Unlock();
return result;
}
Array<GPUResource*> GPUDevice::GetResources() const
{
Locker.Lock();
Array<GPUResource*> result = _resources;
Locker.Unlock();
return result;
}
GPUTasksManager* GPUDevice::GetTasksManager() const

View File

@@ -3,10 +3,11 @@
#pragma once
#include "Engine/Platform/Platform.h"
#include "Engine/Platform/CriticalSection.h"
#include "Engine/Core/Enums.h"
#include "Engine/Core/NonCopyable.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Scripting/ScriptingObject.h"
#include "GPUResourcesCollection.h"
#include "GPUAdapter.h"
#include "GPULimits.h"
#include "Enums.h"
@@ -14,6 +15,7 @@
class ITextureOwner;
class RenderTask;
class GPUResource;
class GPUContext;
class GPUShader;
class GPUTimerQuery;
@@ -84,6 +86,7 @@ protected:
// Private resources (hidden with declaration)
struct PrivateData;
PrivateData* _res;
Array<GPUResource*> _resources;
protected:
/// <summary>
@@ -105,12 +108,6 @@ public:
/// </summary>
CriticalSection Locker;
/// <summary>
/// The GPU resources collection.
/// </summary>
GPUResourcesCollection Resources;
public:
/// <summary>
/// The total amount of graphics memory in bytes.
/// </summary>
@@ -220,6 +217,11 @@ public:
/// </summary>
API_PROPERTY() uint64 GetMemoryUsage() const;
/// <summary>
/// Gets the list with all active GPU resources.
/// </summary>
API_PROPERTY() Array<GPUResource*> GetResources() const;
/// <summary>
/// Gets the GPU asynchronous work manager.
/// </summary>
@@ -299,6 +301,15 @@ public:
/// </summary>
virtual void WaitForGPU() = 0;
public:
void AddResource(GPUResource* resource);
void RemoveResource(GPUResource* resource);
/// <summary>
/// Dumps all GPU resources information to the log.
/// </summary>
void DumpResourcesToLog() const;
protected:
virtual void preDispose();

View File

@@ -137,7 +137,7 @@ public:
#if GPU_ENABLE_RESOURCE_NAMING
GPUResource::_name = name;
#endif
device->Resources.Add(this);
device->AddResource(this);
}
/// <summary>
@@ -146,7 +146,7 @@ public:
virtual ~GPUResourceBase()
{
if (_device)
_device->Resources.Remove(this);
_device->RemoveResource(this);
}
public:

View File

@@ -1,101 +0,0 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#include "GPUResourcesCollection.h"
#include "GPUResource.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Types/StringBuilder.h"
#include "Engine/Core/Utilities.h"
uint64 GPUResourcesCollection::GetMemoryUsage() const
{
uint64 result = 0;
_locker.Lock();
for (int32 i = 0; i < _collection.Count(); i++)
result += _collection[i]->GetMemoryUsage();
_locker.Unlock();
return result;
}
void GPUResourcesCollection::OnDeviceDispose()
{
_locker.Lock();
for (int32 i = _collection.Count() - 1; i >= 0 && i < _collection.Count(); i--)
{
_collection[i]->OnDeviceDispose();
}
_collection.Clear();
_locker.Unlock();
}
void GPUResourcesCollection::DumpToLog() const
{
StringBuilder sb;
DumpToLog(sb);
LOG_STR(Info, sb.ToString());
}
void GPUResourcesCollection::DumpToLog(StringBuilder& output) const
{
_locker.Lock();
output.AppendFormat(TEXT("GPU Resources dump. Count: {0}, total GPU memory used: {1}"), _collection.Count(), Utilities::BytesToText(GetMemoryUsage()));
output.AppendLine();
output.AppendLine();
for (int32 typeIndex = 0; typeIndex < GPUResource::ResourceType_Count; typeIndex++)
{
const auto type = static_cast<GPUResource::ResourceType>(typeIndex);
output.AppendFormat(TEXT("Group: {0}s"), GPUResource::ToString(type));
output.AppendLine();
int32 count = 0;
uint64 memUsage = 0;
for (int32 i = 0; i < _collection.Count(); i++)
{
const auto resource = _collection[i];
if (resource->GetResourceType() == type)
{
count++;
memUsage += resource->GetMemoryUsage();
auto str = resource->ToString();
if (str.HasChars())
{
output.Append(TEXT('\t'));
output.Append(str);
output.AppendLine();
}
}
}
output.AppendFormat(TEXT("Total count: {0}, memory usage: {1}"), count, Utilities::BytesToText(memUsage));
output.AppendLine();
output.AppendLine();
}
_locker.Unlock();
}
void GPUResourcesCollection::Add(GPUResource* resource)
{
_locker.Lock();
ASSERT(resource && _collection.Contains(resource) == false);
_collection.Add(resource);
_locker.Unlock();
}
void GPUResourcesCollection::Remove(GPUResource* resource)
{
_locker.Lock();
ASSERT(resource && _collection.Contains(resource) == true);
_collection.Remove(resource);
_locker.Unlock();
}

View File

@@ -1,71 +0,0 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Platform/Platform.h"
#include "Engine/Platform/CriticalSection.h"
class GPUResource;
class StringBuilder;
/// <summary>
/// GPU Resources collection container
/// </summary>
class GPUResourcesCollection
{
private:
CriticalSection _locker;
Array<GPUResource*> _collection;
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUResourcesCollection"/> class.
/// </summary>
GPUResourcesCollection()
: _collection(1024)
{
}
/// <summary>
/// Finalizes an instance of the <see cref="GPUResourcesCollection"/> class.
/// </summary>
~GPUResourcesCollection()
{
}
public:
/// <summary>
/// Gets the total memory usage (in bytes).
/// </summary>
/// <returns>GPU memory usage (in bytes).</returns>
uint64 GetMemoryUsage() const;
/// <summary>
/// Called when device is being disposed.
/// </summary>
void OnDeviceDispose();
/// <summary>
/// Dumps all resources information to the log.
/// </summary>
void DumpToLog() const;
/// <summary>
/// Dumps all resources information to the log.
/// </summary>
void DumpToLog(StringBuilder& output) const;
public:
/// <summary>
/// Adds the specified resource to the collection.
/// </summary>
/// <param name="resource">The resource.</param>
void Add(GPUResource* resource);
/// <summary>
/// Removes the specified resource from the collection.
/// </summary>
/// <param name="resource">The resource.</param>
void Remove(GPUResource* resource);
};