bSupportsMetal

bSupportsMetal

#Overview

name: bSupportsMetal

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 13 C++ source files. Also referenced in 1 C# build file meaning it may affect the build system logic.

#Summary

#Usage in the C++ source code

The purpose of bSupportsMetal is to enable or disable support for the Metal graphics API in iOS projects using Unreal Engine 5. Metal is a low-level, low-overhead hardware-accelerated graphics and compute API developed by Apple for iOS, iPadOS, macOS, and tvOS.

This setting variable is primarily used by the rendering system in Unreal Engine 5, specifically for iOS development. It is referenced in several subsystems and modules, including:

  1. IOSPlatformEditor
  2. IOSTargetPlatform
  3. PIEPreviewDeviceProfileSelector
  4. MetalRHI
  5. ApplicationCore (iOS-specific)
  6. IOSRuntimeSettings
  7. WebBrowser (iOS-specific)

The value of this variable is set in the IOSRuntimeSettings class, which is part of the iOS runtime settings configuration. By default, it is set to true in the constructor of UIOSRuntimeSettings.

bSupportsMetal interacts with other variables, most notably bSupportsMetalMRT, which enables support for Metal with Multiple Render Targets (MRT). These two variables are often checked together to determine the level of Metal support for the project.

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

  1. It requires iOS 8+ and an A7 processor or later to function.
  2. Enabling Metal support may affect compatibility with older devices.
  3. At least one of bSupportsMetal or bSupportsMetalMRT must be true for the project to compile.

Best practices when using this variable include:

  1. Ensure that your target iOS devices meet the minimum requirements for Metal support.
  2. Test your game on various iOS devices to verify performance and compatibility when Metal is enabled.
  3. Consider providing fallback options for devices that don’t support Metal.
  4. Keep in mind that enabling Metal can improve performance but may also increase the complexity of your rendering pipeline.
  5. Regularly update your project to take advantage of the latest Metal features and optimizations in Unreal Engine.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:2985, section: [/Script/IOSRuntimeSettings.IOSRuntimeSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Developer/IOS/IOSPlatformEditor/Private/IOSTargetSettingsCustomization.cpp:809

Scope: file

Source code excerpt:

	SETUP_PLIST_PROP(bSupportsFilesApp, FileSystemCategory);
	
	SETUP_PLIST_PROP(bSupportsMetal, RenderCategory);
	
	MRTPropertyHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UIOSRuntimeSettings, bSupportsMetalMRT));
	MRTPropertyHandle->SetOnPropertyValueChanged(OnEnableMetalMRT);
	RenderCategory.AddProperty(MRTPropertyHandle);

	SETUP_SOURCEONLY_PROP(bEnableRemoteNotificationsSupport, OnlineCategory)

#Loc: <Workspace>/Engine/Source/Developer/IOS/IOSTargetPlatform/Private/IOSTargetPlatform.cpp:445

Scope (from outer to inner):

file
function     static bool SupportsMetal

Source code excerpt:

{
	// default to NOT supporting metal
	bool bSupportsMetal = false;
	GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetal"), bSupportsMetal, GEngineIni);
	return bSupportsMetal;
}

static bool SupportsMetalMRT()
{
	// default to NOT supporting metal MRT
	bool bSupportsMetalMRT = false;

#Loc: <Workspace>/Engine/Source/Editor/PIEPreviewDeviceProfileSelector/Private/PIEPreviewDevice.cpp:251

Scope (from outer to inner):

file
function     ERHIFeatureLevel::Type FPIEPreviewDevice::GetPreviewDeviceFeatureLevel

Source code excerpt:

		{
			bool bProjectBuiltForMetal = false, bProjectBuiltForMRTMetal = false;
			GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetal"), bProjectBuiltForMetal, GEngineIni);
			GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetalMRT"), bProjectBuiltForMRTMetal, GEngineIni);

			const bool bDeviceSupportsMetal = DeviceSpecs->IOSProperties.MetalRHIState.MaxTextureDimensions > 0;

			// not supporting preview for MRT metal 
			check(!bProjectBuiltForMRTMetal);

#Loc: <Workspace>/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRHI.cpp:62

Scope (from outer to inner):

file
function     static void ValidateTargetedRHIFeatureLevelExists

Source code excerpt:

	if (Platform == SP_METAL || Platform == SP_METAL_TVOS || Platform == SP_METAL_SIM)
	{
		GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetal"), bSupportsShaderPlatform, GEngineIni);
	}
	else if (Platform == SP_METAL_MRT || Platform == SP_METAL_MRT_TVOS)
	{
		GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetalMRT"), bSupportsShaderPlatform, GEngineIni);
	}
#endif

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSView.cpp:123

Scope: file

Source code excerpt:

	
	// make sure the project setting has enabled Metal support (per-project user settings in the editor)
	bool bSupportsMetal = false;
	bool bSupportsMetalMRT = false;
	GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetal"), bSupportsMetal, GEngineIni);
	GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetalMRT"), bSupportsMetalMRT, GEngineIni);

	bool bTriedToInit = false;

	// the check for the function pointer itself is to determine if the Metal framework exists, before calling it
	if ((bSupportsMetal || bSupportsMetalMRT) && MTLCreateSystemDefaultDevice != NULL)
	{
		SCOPED_BOOT_TIMING("CreateMetalDevice");
		// if the device is unable to run with Metal (pre-A7), this will return nullptr
		GMetalDevice = (__bridge MTL::Device*)MTLCreateSystemDefaultDevice();

		// just tracking for printout below

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSView.cpp:145

Scope: file

Source code excerpt:

	{
		FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Not using Metal because: [Project Settings Disabled Metal? %s :: Commandline Forced ES2? %s :: Older OS? %s :: Pre-A7 Device? %s]"),
			bSupportsMetal ? TEXT("No") : TEXT("Yes"),
			TEXT("No"),
			(MTLCreateSystemDefaultDevice == NULL) ? TEXT("Yes") : TEXT("No"),
			bTriedToInit ? TEXT("Yes") : TEXT("Unknown (didn't test)"));
	}
#endif

#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Classes/IOSRuntimeSettings.h:201

Scope (from outer to inner):

file
class        class UIOSRuntimeSettings : public UObject

Source code excerpt:

	// Whether or not to compile iOS Metal shaders for the Mobile renderer (requires iOS 8+ and an A7 processor).
	UPROPERTY(GlobalConfig, EditAnywhere, Category = Rendering, meta = (DisplayName = "Metal Mobile Renderer"))
	bool bSupportsMetal;

	// Whether or not to compile iOS Metal shaders for the desktop renderer (requires iOS 10+ and an A10 processor)
	UPROPERTY(GlobalConfig, EditAnywhere, Category = Rendering, meta = (DisplayName = "Metal Desktop Renderer"))
	bool bSupportsMetalMRT;
    
    // Should the app be compatible for high refresh rate (iPhone only)

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

Scope (from outer to inner):

file
function     UIOSRuntimeSettings::UIOSRuntimeSettings

Source code excerpt:

    bEnableRemoteNotificationsSupport = false;
    bEnableBackgroundFetch = false;
	bSupportsMetal = true;
	bSupportsMetalMRT = false;
    bSupportHighRefreshRates = false;
	bDisableHTTPS = false;
    bSupportsBackgroundAudio = false;
}

#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Private/IOSRuntimeSettings.cpp:88

Scope (from outer to inner):

file
function     void UIOSRuntimeSettings::PostEditChangeProperty

Source code excerpt:


	// Ensure that at least one API is supported
	if (!bSupportsMetal && !bSupportsMetalMRT)
	{
		bSupportsMetal = true;
		UpdateSinglePropertyInConfigFile(GetClass()->FindPropertyByName(GET_MEMBER_NAME_CHECKED(UIOSRuntimeSettings, bSupportsMetal)), GetDefaultConfigFilename());
	}

	// If iOS Simulator setting changed, need to rerun GPF to force xcconfig files to updated the supported platforms
	if (PropertyChangedEvent.GetPropertyName() == TEXT("bEnableSimulatorSupport") &&
		PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet)
	{

#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Private/IOSRuntimeSettings.cpp:173

Scope (from outer to inner):

file
function     void UIOSRuntimeSettings::PostInitProperties

Source code excerpt:

		UpdateSinglePropertyInConfigFile(GetClass()->FindPropertyByName(GET_MEMBER_NAME_CHECKED(UIOSRuntimeSettings, MinimumiOSVersion)), GetDefaultConfigFilename());
	}
	if (!bSupportsMetal && !bSupportsMetalMRT)
	{
		bSupportsMetal = true;
		UpdateSinglePropertyInConfigFile(GetClass()->FindPropertyByName(GET_MEMBER_NAME_CHECKED(UIOSRuntimeSettings, bSupportsMetal)), GetDefaultConfigFilename());
	}
}

#undef LOCTEXT_NAMESPACE

#endif

#Loc: <Workspace>/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.cpp:38

Scope (from outer to inner):

file
function     void Construct

Source code excerpt:

		GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetalMRT"), bSupportsMetalMRT, GEngineIni);

		bool bSupportsMetal = false;
		GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsMetal"), bSupportsMetal, GEngineIni);
		// At this point we MUST be a Metal renderer.
		check(bSupportsMetal);

		WebViewWrapper = [IOSWebViewWrapper alloc];
		[WebViewWrapper create : TSharedPtr<SIOSWebBrowserWidget>(this) useTransparency : Args._UseTransparency supportsMetal : bSupportsMetal supportsMetalMRT : bSupportsMetalMRT];

		WebBrowserWindowPtr = Args._WebBrowserWindow;
		IsIOS3DBrowser = false;

#if !PLATFORM_TVOS
		TextureSamplePool = new FWebBrowserTextureSamplePool();

#Loc: <Workspace>/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.cpp:464

Scope: file

Source code excerpt:

	IsIOS3DBrowser = false;
	bVideoTextureValid = false;
	bSupportsMetal = InSupportsMetal;
	bSupportsMetalMRT = InSupportsMetalMRT;

#if !PLATFORM_TVOS
	dispatch_async(dispatch_get_main_queue(), ^
	{
		WebViewContainer = [[UIView alloc]initWithFrame:CGRectMake(1, 1, 100, 100)];

#Loc: <Workspace>/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.h:37

Scope: file

Source code excerpt:

	bool IsIOS3DBrowser;
	bool bVideoTextureValid;
	bool bSupportsMetal;
	bool bSupportsMetalMRT;
}
#if !PLATFORM_TVOS
@property(strong) WKWebView* WebView;
@property(strong) UIView* WebViewContainer;
#endif

#References in C# build files

This variable is referenced in the following C# build files:

Location: <Workspace>/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEDeployIOS.cs:632

			string RequiredCaps = "\t\t<string>arm64</string>\n";

			Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsMetal", out bSupported);
			RequiredCaps += bSupported ? "\t\t<string>metal</string>\n" : "";

			// minimum iOS version
			string MinVersionSetting = "";
			Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersionSetting);
			string MinVersion = GetMinimumOSVersion(MinVersionSetting, Logger);