r.GraphicsAdapter

r.GraphicsAdapter

#Overview

name: r.GraphicsAdapter

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

It is referenced in 11 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.GraphicsAdapter is to allow users to specify which graphics adapter to use when running an Unreal Engine application, particularly in systems with multiple graphics cards (e.g., integrated and discrete GPUs).

This setting variable is primarily used by the rendering subsystem, specifically in the D3D11RHI, D3D12RHI, and VulkanRHI modules. It’s also referenced in the DisplayClusterLaunch and DisplayClusterConfiguration plugins.

The value of this variable is set through various means:

  1. It can be set via console command or configuration file using the “r.GraphicsAdapter” syntax.
  2. It can be specified in the command line using “graphicsadapter=”.
  3. It’s initialized with a default value of -1 in the code.

The associated variable CVarGraphicsAdapter interacts directly with r.GraphicsAdapter, essentially serving as the in-code representation of the console variable.

Developers should be aware of the following when using this variable:

  1. The value -1 favors non-integrated GPUs (default behavior).
  2. A value of -2 selects the first adapter that meets the criteria.
  3. Values 0 or greater specify a particular adapter index.
  4. This setting takes precedence over other GPU preference settings when its value is >= 0.
  5. For Windows D3D, it affects the rejection of Microsoft adapters to avoid software emulation.

Best practices for using this variable include:

  1. Use it when you need to force the selection of a specific GPU in multi-GPU systems.
  2. Be cautious when setting a specific adapter index, as it may not exist on all systems.
  3. Consider the implications for VR applications, as it interacts with HMD adapter selection.
  4. When using it in cluster configurations, ensure consistent settings across all nodes.

Regarding the associated variable CVarGraphicsAdapter: Its purpose is to provide programmatic access to the r.GraphicsAdapter setting within the engine’s C++ code. It’s used in the same rendering subsystems as r.GraphicsAdapter and serves to retrieve the current value of the setting at runtime. Developers should use this variable when they need to access or modify the graphics adapter selection within C++ code, rather than directly manipulating the console variable.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/RHI/Private/RHI.cpp:57

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarGraphicsAdapter(
	TEXT("r.GraphicsAdapter"),
	-1,
	TEXT("User request to pick a specific graphics adapter (e.g. when using a integrated graphics card with a discrete one)\n")
	TEXT("For Windows D3D, unless a specific adapter is chosen we reject Microsoft adapters because we don't want the software emulation.\n")
	TEXT("This takes precedence over -prefer{AMD|NVidia|Intel} when the value is >= 0.\n")
	TEXT(" -2: Take the first one that fulfills the criteria\n")
	TEXT(" -1: Favour non integrated because there are usually faster (default)\n")

#Loc: <Workspace>/Engine/Plugins/Editor/DisplayClusterLaunch/Source/DisplayClusterLaunchEditor/Private/DisplayClusterLaunchEditorModule.cpp:518

Scope (from outer to inner):

file
function     void FDisplayClusterLaunchEditorModule::LaunchDisplayClusterProcess

Source code excerpt:

				if (NodePtr->GraphicsAdapter >= 0)
				{
					DPCvars.Add(FString::Printf(TEXT("r.GraphicsAdapter=%d"), NodePtr->GraphicsAdapter));
				}
			}
		}
		// Unreal Insights support
		if (ProjectSettings->bEnableUnrealInsights)
		{

#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayClusterConfiguration/Private/DisplayClusterConfigurationModule.cpp:25

Scope (from outer to inner):

file
function     void FDisplayClusterConfigurationModule::StartupModule

Source code excerpt:

	if (DisplayClusterHelpers::str::ExtractValue(ConfigLineStr, DisplayClusterConfigurationStrings::args::Gpu, GraphicsAdapter))
	{
		IConsoleVariable* const GpuCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.GraphicsAdapter"));
		if (GpuCVar)
		{
			UE_LOG(LogDisplayClusterConfiguration, Log, TEXT("Set custom GPU selection policy - r.GraphicsAdapter=%d"), GraphicsAdapter);
			GpuCVar->Set(GraphicsAdapter);
		}
	}

#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayClusterConfiguration/Public/DisplayClusterConfigurationTypes.h:337

Scope (from outer to inner):

file
function     class DISPLAYCLUSTERCONFIGURATION_API UDisplayClusterConfigurationClusterNode : public UDisplayClusterConfigurationData_Base { GENERATED_BODY

Source code excerpt:

	bool bRenderHeadless = false;

	/** Hint for setting the r.GraphicsAdapter CVar when launching this cluster node. Note that this is distinct from the GPU Node Indices assigned to viewports. */
	UPROPERTY(EditAnywhere, BlueprintReadonly, Category = "Configuration", meta = (DisplayName = "Graphics Adapter"))
	int32 GraphicsAdapter = -1;

	/** Enables texture sharing for this cluster node */
	UPROPERTY(EditAnywhere, BlueprintReadonly, Category = "Configuration", meta = (DisplayName = "Enable Texture Share"))
	bool bEnableTextureShare = false;

#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/Windows/WindowsD3D12Device.cpp:864

Scope (from outer to inner):

file
function     void FD3D12DynamicRHIModule::FindAdapter

Source code excerpt:

	uint64 HmdGraphicsAdapterLuid = IHeadMountedDisplayModule::IsAvailable() ? IHeadMountedDisplayModule::Get().GetGraphicsAdapterLuid() : 0;
	// Non-static as it is used only a few times
	auto* CVarGraphicsAdapter = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GraphicsAdapter"));
	int32 CVarExplicitAdapterValue = HmdGraphicsAdapterLuid == 0 ? (CVarGraphicsAdapter ? CVarGraphicsAdapter->GetValueOnGameThread() : -1) : -2;
	FParse::Value(FCommandLine::Get(), TEXT("graphicsadapter="), CVarExplicitAdapterValue);

	const bool bFavorDiscreteAdapter = CVarExplicitAdapterValue == -1;

	TRefCountPtr<IDXGIAdapter> TempAdapter;

#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp:194

Scope (from outer to inner):

file
function     static VkPhysicalDevice SelectPhysicalDevice

Source code excerpt:


	// Use the device as forced by CVar or CommandLine arg
	auto* CVarGraphicsAdapter = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GraphicsAdapter"));
	int32 ExplicitAdapterValue = CVarGraphicsAdapter ? CVarGraphicsAdapter->GetValueOnAnyThread() : -1;
	const bool bUsingCmdLine = FParse::Value(FCommandLine::Get(), TEXT("graphicsadapter="), ExplicitAdapterValue);
	const TCHAR* GraphicsAdapterOriginTxt = bUsingCmdLine ? TEXT("command line") : TEXT("'r.GraphicsAdapter'");
	if (ExplicitAdapterValue >= 0)  // Use adapter at the specified index
	{
		if (ExplicitAdapterValue >= PhysicalDeviceInfos.Num())
		{
			UE_LOG(LogVulkanRHI, Warning, TEXT("Tried to use graphics adapter at index %d as specified by %s, but only %d Adapter(s) found. Falling back to first device..."), 
				ExplicitAdapterValue, GraphicsAdapterOriginTxt, PhysicalDeviceInfos.Num());

#Loc: <Workspace>/Engine/Source/Runtime/Windows/D3D11RHI/Private/Windows/WindowsD3D11Device.cpp:998

Scope (from outer to inner):

file
function     void FD3D11DynamicRHIModule::FindAdapter

Source code excerpt:

	uint64 HmdGraphicsAdapterLuid  = IHeadMountedDisplayModule::IsAvailable() ? IHeadMountedDisplayModule::Get().GetGraphicsAdapterLuid() : 0;
	// Non-static as it is used only a few times
	auto* CVarGraphicsAdapter = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GraphicsAdapter"));
	int32 CVarExplicitAdapterValue = HmdGraphicsAdapterLuid == 0 ? (CVarGraphicsAdapter ? CVarGraphicsAdapter->GetValueOnGameThread() : -1) : -2;
	FParse::Value(FCommandLine::Get(), TEXT("graphicsadapter="), CVarExplicitAdapterValue);

	const bool bFavorDiscreteAdapter = CVarExplicitAdapterValue == -1;

	TRefCountPtr<IDXGIAdapter> TempAdapter;

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/Windows/WindowsD3D12Device.cpp:864

Scope (from outer to inner):

file
function     void FD3D12DynamicRHIModule::FindAdapter

Source code excerpt:

	uint64 HmdGraphicsAdapterLuid = IHeadMountedDisplayModule::IsAvailable() ? IHeadMountedDisplayModule::Get().GetGraphicsAdapterLuid() : 0;
	// Non-static as it is used only a few times
	auto* CVarGraphicsAdapter = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GraphicsAdapter"));
	int32 CVarExplicitAdapterValue = HmdGraphicsAdapterLuid == 0 ? (CVarGraphicsAdapter ? CVarGraphicsAdapter->GetValueOnGameThread() : -1) : -2;
	FParse::Value(FCommandLine::Get(), TEXT("graphicsadapter="), CVarExplicitAdapterValue);

	const bool bFavorDiscreteAdapter = CVarExplicitAdapterValue == -1;

	TRefCountPtr<IDXGIAdapter> TempAdapter;
	const D3D_FEATURE_LEVEL MinRequiredFeatureLevel = GetRequiredD3DFeatureLevel();

#Loc: <Workspace>/Engine/Source/Runtime/RHI/Private/RHI.cpp:56

Scope: file

Source code excerpt:

	ECVF_Default);

static TAutoConsoleVariable<int32> CVarGraphicsAdapter(
	TEXT("r.GraphicsAdapter"),
	-1,
	TEXT("User request to pick a specific graphics adapter (e.g. when using a integrated graphics card with a discrete one)\n")
	TEXT("For Windows D3D, unless a specific adapter is chosen we reject Microsoft adapters because we don't want the software emulation.\n")
	TEXT("This takes precedence over -prefer{AMD|NVidia|Intel} when the value is >= 0.\n")
	TEXT(" -2: Take the first one that fulfills the criteria\n")

#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp:194

Scope (from outer to inner):

file
function     static VkPhysicalDevice SelectPhysicalDevice

Source code excerpt:


	// Use the device as forced by CVar or CommandLine arg
	auto* CVarGraphicsAdapter = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GraphicsAdapter"));
	int32 ExplicitAdapterValue = CVarGraphicsAdapter ? CVarGraphicsAdapter->GetValueOnAnyThread() : -1;
	const bool bUsingCmdLine = FParse::Value(FCommandLine::Get(), TEXT("graphicsadapter="), ExplicitAdapterValue);
	const TCHAR* GraphicsAdapterOriginTxt = bUsingCmdLine ? TEXT("command line") : TEXT("'r.GraphicsAdapter'");
	if (ExplicitAdapterValue >= 0)  // Use adapter at the specified index
	{
		if (ExplicitAdapterValue >= PhysicalDeviceInfos.Num())
		{

#Loc: <Workspace>/Engine/Source/Runtime/Windows/D3D11RHI/Private/Windows/WindowsD3D11Device.cpp:998

Scope (from outer to inner):

file
function     void FD3D11DynamicRHIModule::FindAdapter

Source code excerpt:

	uint64 HmdGraphicsAdapterLuid  = IHeadMountedDisplayModule::IsAvailable() ? IHeadMountedDisplayModule::Get().GetGraphicsAdapterLuid() : 0;
	// Non-static as it is used only a few times
	auto* CVarGraphicsAdapter = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GraphicsAdapter"));
	int32 CVarExplicitAdapterValue = HmdGraphicsAdapterLuid == 0 ? (CVarGraphicsAdapter ? CVarGraphicsAdapter->GetValueOnGameThread() : -1) : -2;
	FParse::Value(FCommandLine::Get(), TEXT("graphicsadapter="), CVarExplicitAdapterValue);

	const bool bFavorDiscreteAdapter = CVarExplicitAdapterValue == -1;

	TRefCountPtr<IDXGIAdapter> TempAdapter;
	D3D_FEATURE_LEVEL MinAllowedFeatureLevel = GetMinAllowedD3DFeatureLevel();