From 5345d1f6856b2c0590b3ffd8d0a3d3dd9ed75fb8 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Thu, 21 Apr 2022 12:37:39 +0200 Subject: [PATCH] Add events for streamable resources residency changes tracking --- Source/Engine/Content/Assets/Model.cpp | 11 +++++++---- Source/Engine/Content/Assets/SkinnedModel.cpp | 9 ++++++--- Source/Engine/Graphics/Textures/GPUTexture.cpp | 1 + Source/Engine/Graphics/Textures/GPUTexture.h | 5 +++++ Source/Engine/Graphics/Textures/StreamingTexture.cpp | 2 ++ Source/Engine/Streaming/StreamableResource.h | 6 ++++++ 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Source/Engine/Content/Assets/Model.cpp b/Source/Engine/Content/Assets/Model.cpp index 8ee204e11..4512172f8 100644 --- a/Source/Engine/Content/Assets/Model.cpp +++ b/Source/Engine/Content/Assets/Model.cpp @@ -91,6 +91,7 @@ public: // Update residency level model->_loadedLODs++; + model->ResidencyChanged(); return false; } @@ -697,11 +698,8 @@ bool Model::Init(const Span& meshesCountPerLod) // Setup LODs for (int32 lodIndex = 0; lodIndex < LODs.Count(); lodIndex++) - { LODs[lodIndex].Dispose(); - } LODs.Resize(meshesCountPerLod.Length()); - _loadedLODs = meshesCountPerLod.Length(); // Setup meshes for (int32 lodIndex = 0; lodIndex < meshesCountPerLod.Length(); lodIndex++) @@ -720,6 +718,10 @@ bool Model::Init(const Span& meshesCountPerLod) } } + // Update resource residency + _loadedLODs = meshesCountPerLod.Length(); + ResidencyChanged(); + return false; } @@ -836,6 +838,7 @@ Task* Model::CreateStreamingTask(int32 residency) for (int32 i = HighestResidentLODIndex(); i < LODs.Count() - residency; i++) LODs[i].Unload(); _loadedLODs = residency; + ResidencyChanged(); } return result; @@ -945,7 +948,7 @@ Asset::LoadResult Model::load() sdfStream.Read(&data); if (!SDF.Texture) SDF.Texture = GPUTexture::New(); - if (SDF.Texture->Init(GPUTextureDescription::New3D(data.Width, data.Height, data.Depth, data.Format, GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess, data.MipLevels))) + if (SDF.Texture->Init(GPUTextureDescription::New3D(data.Width, data.Height, data.Depth, data.Format, GPUTextureFlags::ShaderResource, data.MipLevels))) return LoadResult::Failed; SDF.LocalToUVWMul = data.LocalToUVWMul; SDF.LocalToUVWAdd = data.LocalToUVWAdd; diff --git a/Source/Engine/Content/Assets/SkinnedModel.cpp b/Source/Engine/Content/Assets/SkinnedModel.cpp index e3e1339a1..f0cff64aa 100644 --- a/Source/Engine/Content/Assets/SkinnedModel.cpp +++ b/Source/Engine/Content/Assets/SkinnedModel.cpp @@ -85,6 +85,7 @@ protected: // Update residency level model->_loadedLODs++; + model->ResidencyChanged(); return false; } @@ -676,11 +677,8 @@ bool SkinnedModel::Init(const Span& meshesCountPerLod) // Setup LODs for (int32 lodIndex = 0; lodIndex < LODs.Count(); lodIndex++) - { LODs[lodIndex].Dispose(); - } LODs.Resize(meshesCountPerLod.Length()); - _loadedLODs = meshesCountPerLod.Length(); // Setup meshes for (int32 lodIndex = 0; lodIndex < meshesCountPerLod.Length(); lodIndex++) @@ -699,6 +697,10 @@ bool SkinnedModel::Init(const Span& meshesCountPerLod) } } + // Update resource residency + _loadedLODs = meshesCountPerLod.Length(); + ResidencyChanged(); + return false; } @@ -827,6 +829,7 @@ Task* SkinnedModel::CreateStreamingTask(int32 residency) for (int32 i = HighestResidentLODIndex(); i < LODs.Count() - residency; i++) LODs[i].Unload(); _loadedLODs = residency; + ResidencyChanged(); } return result; diff --git a/Source/Engine/Graphics/Textures/GPUTexture.cpp b/Source/Engine/Graphics/Textures/GPUTexture.cpp index bc5424223..69131efa7 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.cpp +++ b/Source/Engine/Graphics/Textures/GPUTexture.cpp @@ -814,4 +814,5 @@ void GPUTexture::SetResidentMipLevels(int32 count) return; _residentMipLevels = count; OnResidentMipsChanged(); + ResidentMipsChanged(this); } diff --git a/Source/Engine/Graphics/Textures/GPUTexture.h b/Source/Engine/Graphics/Textures/GPUTexture.h index a51d4418b..3e6893008 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.h +++ b/Source/Engine/Graphics/Textures/GPUTexture.h @@ -568,6 +568,11 @@ public: /// API_PROPERTY() void SetResidentMipLevels(int32 count); + /// + /// Event called when texture residency gets changed. Texture Mip gets loaded into GPU memory and is ready to use. + /// + Delegate ResidentMipsChanged; + protected: virtual bool OnInit() = 0; diff --git a/Source/Engine/Graphics/Textures/StreamingTexture.cpp b/Source/Engine/Graphics/Textures/StreamingTexture.cpp index 0290048fc..96a023c3b 100644 --- a/Source/Engine/Graphics/Textures/StreamingTexture.cpp +++ b/Source/Engine/Graphics/Textures/StreamingTexture.cpp @@ -233,6 +233,7 @@ protected: { Swap(_streamingTexture->_texture, _newTexture); _streamingTexture->GetTexture()->SetResidentMipLevels(_uploadedMipCount); + _streamingTexture->ResidencyChanged(); SAFE_DELETE_GPU_RESOURCE(_newTexture); // Base @@ -447,6 +448,7 @@ Task* StreamingTexture::CreateStreamingTask(int32 residency) { // Do the quick data release _texture->ReleaseGPU(); + ResidencyChanged(); } else { diff --git a/Source/Engine/Streaming/StreamableResource.h b/Source/Engine/Streaming/StreamableResource.h index 233663a66..b63a65356 100644 --- a/Source/Engine/Streaming/StreamableResource.h +++ b/Source/Engine/Streaming/StreamableResource.h @@ -2,6 +2,7 @@ #pragma once +#include "Engine/Core/Delegate.h" #include "Engine/Core/Collections/SamplesBuffer.h" class StreamingGroup; @@ -111,6 +112,11 @@ public: }; StreamingCache Streaming; + + /// + /// Event called when current resource residency gets changed (eg. model LOD or texture MIP gets loaded). Usually called from async thread. + /// + Action ResidencyChanged; /// /// Requests the streaming update for this resource during next streaming manager update.