Fix delay on virtual GPU texture upload

This commit is contained in:
2026-08-09 07:18:21 +02:00
parent 1bcc39179f
commit fff611e7d2
6 changed files with 46 additions and 29 deletions
@@ -75,30 +75,11 @@ protected:
dataSource += _slicePitch;
}
UpdateResidency(texture);
return Result::Ok;
}
void OnSync() override
{
auto texture = _texture.Get();
if (texture)
{
if (_mipIndex == texture->HighestResidentMipIndex() - 1)
{
// Mark the new mip as loaded
texture->SetResidentMipLevels(texture->ResidentMipLevels() + 1);
}
else
{
// Mark the new mip and all lower ones as loaded (eg. when loading Model SDF texture mips at once but out of order)
texture->SetResidentMipLevels(Math::Max(texture->ResidentMipLevels(), texture->MipLevels() - _mipIndex));
}
}
// Base
GPUTask::OnSync();
}
void OnEnd() override
{
_texture.Unlink();
@@ -106,4 +87,18 @@ protected:
// Base
GPUTask::OnEnd();
}
void UpdateResidency(GPUTexture* texture) const
{
if (_mipIndex == texture->HighestResidentMipIndex() - 1)
{
// Mark the new mip as loaded
texture->SetResidentMipLevels(texture->ResidentMipLevels() + 1);
}
else
{
// Mark the new mip and all lower ones as loaded (eg. when loading Model SDF texture mips at once but out of order)
texture->SetResidentMipLevels(Math::Max(texture->ResidentMipLevels(), texture->MipLevels() - _mipIndex));
}
}
};
@@ -252,6 +252,7 @@ protected:
void OnSync() override
{
// Update residency
_newTexture->SetResidentMipLevels(_uploadedMipCount);
Swap(_streamingTexture->_texture, _newTexture);
SAFE_DELETE_GPU_RESOURCE(_newTexture);
@@ -409,6 +410,8 @@ protected:
dataSource += dataPerSlice;
}
UpdateResidency(texture);
return Result::Ok;
}
@@ -13,6 +13,7 @@
#include "Engine/Content/Factories/BinaryAssetFactory.h"
#include "Engine/Graphics/PixelFormatSampler.h"
#include "Engine/Scripting/Enums.h"
#include "Engine/Streaming/Streaming.h"
#include "Engine/Tools/TextureTool/TextureTool.h"
#include "Engine/Threading/Threading.h"
#if GPU_ENABLE_RESOURCE_NAMING && !USE_EDITOR
@@ -706,6 +707,9 @@ bool TextureBase::Init(InitData* initData)
return true;
}
// Speed up update texture uplaod to GPU by alocating texture async task now to run before next frame rendering
Streaming::UpdateResource(&_texture);
return false;
}
@@ -25,17 +25,17 @@ API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API TextureBase : public BinaryAss
struct MipData
{
BytesContainer Data;
uint32 RowPitch;
uint32 SlicePitch;
uint32 RowPitch = 0;
uint32 SlicePitch = 0;
MipData() = default;
MipData(MipData&& other) noexcept;
};
PixelFormat Format;
int32 Width;
int32 Height;
int32 ArraySize;
PixelFormat Format = PixelFormat::Unknown;
int32 Width = 0;
int32 Height = 0;
int32 ArraySize = 1;
Array<MipData, FixedAllocation<14>> Mips;
InitData() = default;
+10 -2
View File
@@ -115,8 +115,6 @@ void StreamableResource::StopStreaming()
void UpdateResource(StreamableResource* resource, double currentTime)
{
ASSERT(resource && resource->CanBeUpdated());
// Pick group and handler dedicated for that resource
auto group = resource->GetGroup();
auto handler = group->GetHandler();
@@ -328,3 +326,13 @@ GPUSampler* Streaming::GetTextureGroupSampler(int32 index)
}
return sampler;
}
void Streaming::UpdateResource(StreamableResource* resource)
{
if (!resource || !resource->CanBeUpdated())
return;
PROFILE_MEM(ContentStreaming);
ScopeLock lock(ResourcesLock);
const double currentTime = Platform::GetTimeSeconds();
::UpdateResource(resource, currentTime);
}
+7
View File
@@ -7,6 +7,7 @@
#include "TextureGroup.h"
class GPUSampler;
class StreamableResource;
// Streaming service statistics container.
API_STRUCT(NoDefault) struct FLAXENGINE_API StreamingStats
@@ -46,4 +47,10 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Streaming);
/// <param name="index">The texture group index.</param>
/// <returns>The texture sampler (always valid).</returns>
API_FUNCTION() static GPUSampler* GetTextureGroupSampler(int32 index);
/// <summary>
/// Manually updates a specific resource (calculates capacity and spawns streaming in/out async tasks). Usefull to force stream speciifc resource without delay or waiting for the next streaming update.
/// </summary>
/// <param name="resource">The resource to update (eg. texture or mesh).</param>
static void UpdateResource(StreamableResource* resource);
};