Widget Virtual Texture Streaming Issue

Hi all

Our map widget uses 4 8192x8192 textures stacked on top of each other. To avoid keeping all of that in memory we use them as virtual textures. Before UE 5.6.0 we streamed the needed tiles in manualy:

void RequestVirtualTextureTiles(const FGeometry& Geometry, const FSlateRect& CullingRect, const FSlateBrush& Brush)
{
	UTexture2D* Texture = Cast<UTexture2D>(Brush.GetResourceObject());
	if (!Texture || !Texture->IsCurrentlyVirtualTextured())
	{
		return;
	}
 
	FVirtualTexture2DResource* VTResource = static_cast<FVirtualTexture2DResource*>(Texture->GetResource());
	const FVector2D ScreenSpaceSize = Geometry.GetAbsoluteSize();
	const FVector2D ViewportPositon = Geometry.GetAbsolutePosition() - CullingRect.GetTopLeft();
	const FVector2D ViewportSize = CullingRect.GetSize();
 
	const FVector2D UV0 = ((FBox2D) Brush.GetUVRegion()).Min;
	const FVector2D UV1 = ((FBox2D) Brush.GetUVRegion()).Max;
 
	const ERHIFeatureLevel::Type InFeatureLevel = GMaxRHIFeatureLevel;
	const int32 MipLevel = -1;
 
	UE::RenderCommandPipe::FSyncScope SyncScope;
	
	ENQUEUE_RENDER_COMMAND(MakeTilesResident)(
		[InFeatureLevel, VTResource, ScreenSpaceSize, ViewportPositon, ViewportSize, UV0, UV1, MipLevel] (FRHICommandListImmediate& RHICmdList)
		{
			IAllocatedVirtualTexture* AllocatedVT = VTResource->AcquireAllocatedVT();
 
			IRendererModule& RenderModule = GetRendererModule();
			RenderModule.FlushVirtualTextureCache(AllocatedVT, FVector2f(0.0f), FVector2f(1.0f));
			RenderModule.RequestVirtualTextureTiles(AllocatedVT, ScreenSpaceSize, ViewportPositon, ViewportSize, UV0, UV1, MipLevel);
			RenderModule.LoadPendingVirtualTextureTiles(RHICmdList, InFeatureLevel);
		}
	);
}

This solution worked pretty well, with the streaming only taking 2 seconds maximum. But after we switched to 5.6.0 the streaming takes 5-times more time than it used to. Even with the highest StreamingPriority, even disabling manual streaming and just relying on the new Feedback stuff, we can’t seem to arive at an acceptable streaming time.

So can you help with our streaming issue and/or say what we are doing wrong?

Thank you for your help.

Igor.

Hi there,

It might be good if you could provide a minimal reproduction project for this issue. This will avoid a lot of guesswork on my side.

Ideally a repro project would be made for the earlier version of the engine you previously used, and exhibit the slow down when upgrading it to 5.6.

As a quick sanity check though, I note you’re passing in -1 as the MipLevel, and getting the UV range from the brush. This will trigger RequestVirtualTextureTiles to calculate the correct mip level to stream from the requested screen space size. However, it looks like the calculation here will be incorrect if the supplied UVs aren’t (0,0), (1,1) from the following code in FVirtualTextureSystem::RequestTiles:

const float vLevel = ComputeMipLevel(AllocatedVT, InScreenSpaceSize); // TODO: ComputeMipLevel() is incorrect if not using the whole UV range

Regards,

Lance Chaney