r.FlushRHIThreadOnSTreamingTextureLocks

r.FlushRHIThreadOnSTreamingTextureLocks

#Overview

name: r.FlushRHIThreadOnSTreamingTextureLocks

This variable is created as a Console Variable (cvar).

It is referenced in 8 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.FlushRHIThreadOnSTreamingTextureLocks is to control whether the RHI (Rendering Hardware Interface) thread should be flushed when locking or unlocking streaming textures. This setting is primarily related to the texture streaming and rendering systems in Unreal Engine 5.

This setting variable is mainly used in the Engine module, specifically in the texture streaming and rendering subsystems. The code references show that it’s used in texture mip allocation, locking, and unlocking operations.

The value of this variable is set through the console variable system in Unreal Engine. It’s defined as a TAutoConsoleVariable with a default value of 0, meaning by default, no flushing occurs for streaming textures.

The associated variable CVarFlushRHIThreadOnSTreamingTextureLocks directly interacts with r.FlushRHIThreadOnSTreamingTextureLocks. They share the same value and are used interchangeably in the code.

Developers must be aware that this variable affects performance and synchronization between the game thread and the RHI thread. When set to a value greater than 0, it causes the RHI thread to flush when locking or unlocking streaming textures, which can impact performance but may be necessary in some cases for synchronization.

Best practices when using this variable include:

  1. Keeping it at the default value (0) unless specific synchronization issues arise.
  2. If enabled, monitor performance carefully as it may introduce additional overhead.
  3. Use it in conjunction with other texture streaming settings for optimal results.

Regarding the associated variable CVarFlushRHIThreadOnSTreamingTextureLocks:

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture2D.cpp:79

Scope: file

Source code excerpt:


TAutoConsoleVariable<int32> CVarFlushRHIThreadOnSTreamingTextureLocks(
	TEXT("r.FlushRHIThreadOnSTreamingTextureLocks"),
	0,
	TEXT("If set to 0, we won't do any flushes for streaming textures. This is safe because the texture streamer deals with these hazards explicitly."),
	ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMobileReduceLoadedMips(
	TEXT("r.MobileReduceLoadedMips"),
	0,

#Associated Variable and Callsites

This variable is associated with another variable named CVarFlushRHIThreadOnSTreamingTextureLocks. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/Texture2DMipAllocator_AsyncReallocate.cpp:9

Scope: file

Source code excerpt:

#include "Streaming/TextureMipAllocator.h"

extern TAutoConsoleVariable<int32> CVarFlushRHIThreadOnSTreamingTextureLocks;

FTexture2DMipAllocator_AsyncReallocate::FTexture2DMipAllocator_AsyncReallocate(UTexture* Texture)
	: FTextureMipAllocator(Texture, ETickState::AllocateMips, ETickThread::Render)
{
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/Texture2DMipAllocator_AsyncReallocate.cpp:60

Scope (from outer to inner):

file
function     bool FTexture2DMipAllocator_AsyncReallocate::AllocateMips

Source code excerpt:

	else
	{
		const bool bFlushRHIThread = CVarFlushRHIThreadOnSTreamingTextureLocks.GetValueOnAnyThread() > 0;

		RHIFinalizeAsyncReallocateTexture2D(IntermediateTextureRHI, true);

		OutMipInfos.AddDefaulted(CurrentFirstLODIdx);

		for (int32 MipIndex = PendingFirstLODIdx; MipIndex < CurrentFirstLODIdx; ++MipIndex)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/Texture2DMipAllocator_AsyncReallocate.cpp:141

Scope (from outer to inner):

file
function     void FTexture2DMipAllocator_AsyncReallocate::UnlockNewMips

Source code excerpt:

	if (IntermediateTextureRHI)
	{
		const bool bFlushRHIThread = CVarFlushRHIThreadOnSTreamingTextureLocks.GetValueOnAnyThread() > 0;
		for (int32 MipIndex : LockedMipIndices)
		{
			RHIUnlockTexture2D(IntermediateTextureRHI, MipIndex, false, CVarFlushRHIThreadOnSTreamingTextureLocks.GetValueOnAnyThread() > 0 );
		}
		LockedMipIndices.Empty();
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/Texture2DStreamIn.cpp:72

Scope (from outer to inner):

file
function     void FTexture2DStreamIn::DoLockNewMips

Source code excerpt:

			check(MipData[MipIndex].Data == nullptr);
			uint32 DestPitch = -1;
			MipData[MipIndex].Data = RHILockTexture2D(IntermediateTextureRHI, MipIndex - MipOffset, RLM_WriteOnly, DestPitch, false, CVarFlushRHIThreadOnSTreamingTextureLocks.GetValueOnAnyThread() > 0);
			MipData[MipIndex].Pitch = DestPitch;
			// note: should store Size but RHILockTexture2D doesn't tell us size
			//MipData[MipIndex].Size

			UE_LOG(LogTextureUpload,Verbose,TEXT("FTexture2DStreamIn::DoLockNewMips( : Lock Mip %d Pitch=%d"),MipIndex,DestPitch);
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/Texture2DStreamIn.cpp:96

Scope (from outer to inner):

file
function     void FTexture2DStreamIn::DoUnlockNewMips

Source code excerpt:

			if (MipData[MipIndex].Data != nullptr)
			{
				RHIUnlockTexture2D(IntermediateTextureRHI, MipIndex - MipOffset, false, CVarFlushRHIThreadOnSTreamingTextureLocks.GetValueOnAnyThread() > 0 );
				MipData[MipIndex].Data = nullptr;
				MipData[MipIndex].Pitch = -1;
			}
		}
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/Texture2DUpdate.h:12

Scope: file

Source code excerpt:

#include "Async/AsyncFileHandle.h"

extern TAutoConsoleVariable<int32> CVarFlushRHIThreadOnSTreamingTextureLocks;

/**
* A context used to update or proceed with the next update step.
* The texture and resource references could be stored in the update object
* but are currently kept outside to avoid lifetime management within the object.
*/

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture2D.cpp:78

Scope: file

Source code excerpt:

	ECVF_RenderThreadSafe | ECVF_Scalability);

TAutoConsoleVariable<int32> CVarFlushRHIThreadOnSTreamingTextureLocks(
	TEXT("r.FlushRHIThreadOnSTreamingTextureLocks"),
	0,
	TEXT("If set to 0, we won't do any flushes for streaming textures. This is safe because the texture streamer deals with these hazards explicitly."),
	ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMobileReduceLoadedMips(
	TEXT("r.MobileReduceLoadedMips"),