Game Mode

The Game Mode APIs for the Universal Windows Platform (UWP) allow you to produce the most optimized gaming experience by taking advantage of Game Mode in Windows 10. These APIs are located in the <expandedresources.h> header.

Note  These are Win32 APIs that are supported in UWP desktop and Xbox apps, as well as Win32 apps (except for ReleaseExclusiveCpuSets, which isn't supported in Win32 apps).
 

Game Mode provides customers with the best possible gaming experience by fully utilizing the capacity of their current hardware. It does this by granting a game exclusive or priority access to hardware resources. These resources being dedicated to the game help it hit performance targets more consistently. The performance increase that comes from Game Mode is directly related to the number and impact of other activities running on the device.

Note  The app must be in the foreground and have focus before exclusive resources are granted.
 

Game Mode works by default for most Windows games, requiring no action or opt-in by the customer, and no work by the game developer. However, you can use the Game Mode API to take it a step further and programmatically query for available system resources, determining whether the operating system considers each resource as shared or exclusive. You can leverage the available system resources in a way that best fits your game design and the configuration of the customer's system.

By using the expandedResources capability, you can explicitly declare that the game will work with Game Mode. As part of launching the game, the process will go into Game Mode with a set of defaults, and you can use the APIs to see what resources are available on the customer's device.

The Game Mode API has the following members:

  • GetExpandedResourceExclusiveCpuCount: Query for details of exclusive hardware, such as cache topology, in order to rank resources.
  • HasExpandedResources: Know when the game enters and exits Game Mode. When the game enters Game Mode, it can provide a tailored experience. When the game exits Game Mode, it can scale back the usage of resources. The general pattern is to poll once per frame.
  • ReleaseExclusiveCpuSets: Opt out of CPU exclusivity.
Note  

ReleaseExclusiveCpuSets requires the expandedResources restricted capability, which you can select by opening Package.appxmanifest in Visual Studio and navigating to the Capabilities tab. Alternatively, you can edit the file's code directly:



<Package
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces=" rescap">
	...
	<Capabilities>
		<rescap:Capability Name="expandedResources" />
	</Capabilities>
	...
</Package>

This capability is granted on a per-title basis; contact your account manager for more information. You can publish a UWP app with this capability to the Store if it targets desktop, but if it targets Xbox it will be rejected in certification.

 

Games should call HasExpandedResources once per frame or game tick to determine whether exclusive resources have been granted. When they have been granted, the game can call GetSystemCpuSetInformation to understand what cores the game is eligible to use. Using this function, deeper inspection, such as getting cache details, can be achieved to rank the cores for performance. The SYSTEM_CPU_SET_INFORMATION structure returned by GetSystemCpuSetInformation exposes details that the game can use to scale the number of threads it runs, and give threads the affinity for the appropriate cores using SetThreadSelectedCpuSets.

When exclusive resources are revoked, such as when the game loses focus, the game will discover this by polling with HasExpandedResources, and can re-scale as appropriate. Some games may reduce the level of detail or use other tactics to maintain performance.

A small number of games may choose to call GetExpandedResourceExclusiveCpuCount to determine what CPU resources are available for exclusive use. Based on the developer's judgment, they may opt-out of CPU exclusivity by calling ReleaseExclusiveCpuSets to get access to all cores, but at a higher latency due to other processes and system activities being scheduled on the same cores as the game. However, the game would still get access to other Game Mode resources, such as increased GPU prioritization. As with SetProcessDefaultCpuSets, ReleaseExclusiveCpuSets applies to the whole process.

While CPU resources may be revoked if the game exits Game Mode, memory resources, once granted, will never be revoked. Games can use APIs such as AppMemoryUsageLimit to understand what is available.

Example: Benchmark on startup

Games often do system inspection on startup to match the game experience against the system resources. Often, the methods used would involve some combination of how many CPUs are available, to scale the count of work queue threads appropriately.



void Game::Benchmark()
{
	ULONG exclusiveCpuCount;

	// FastFailOnError is a user-defined function that fails fast if the given function gives an error.
	FastFailOnError(GetExpandedResourceExclusiveCpuCount(&exclusiveCpuCount));

	// This sample requires 6 cores to run in Game Mode, but other games may have different requirements.
	// Another approach may be to wait until the exclusive CPUs are given, do a cache inspection, and 
	// then decide whether to enter Game Mode.
	// This block works even if the app isn't currently in Game Mode.
	if (exclusiveCpuCount >= 6)
	{
		// m_exclusiveCapable is a user-defined boolean member variable that is true if the game can 
		// run in Game Mode and false otherwise.
		m_exclusiveCapable = true;
	}
	else
	{
		FastFailOnError(ReleaseExclusiveCpuSets());
		m_exclusiveCapable = false;
	}

	// Assume shared state by default, and let the game loop update it if it's wrong. For shared mode, 
	// the game should apply the resource set it would apply if Game Mode weren't available.

	// m_hasExpandedResources is a user-defined boolean member variable that is true if the game is 
	// running in Game Mode and false if it's running in shared mode.
	m_hasExpandedResources = FALSE;

	// m_main is a user-defined member variable that points to the main game instance. 
	// ApplySharedModeResourceSet is a user-defined function that applies shared
	// mode presets, possibly reducing the level of detail.
	m_main->ApplySharedModeResourceSet();
}

Example: Game loop

HasExpandedResources should be called once per frame to detect state changes. This can be called in the main game loop that performs functions like collating inputs from devices and updating the world state.


void Game::Run()
{
	// m_windowClosed is a user-defined boolean member variable that is true if the app is closed and/or 
	// in the background, and false if it's open and in the foreground.
	while (!m_windowClosed)
	{
		// If the app decided that shared mode is fine, ignore game mode transitions.
		if (m_exclusiveCapable)
		{
			BOOL hasExpandedResources;
			FastFailOnError(HasExpandedResources(&hasExpandedResources));

			// The app has entered or exited Game Mode.
			if (hasExpandedResources != m_hasExpandedResources)
			{
				if (hasExpandedResources)
				{
					m_main->ApplySharedModeResourceSet();
				}
				else
				{
					// Games in exclusive mode can use SetProcessDefaultCpuSets and 
					// SetThreadSelectedCpuSets, in combination with cache information 
					// from GetSystemCpuSetInformation, to put busy threads on
					// allocated cores that have dedicated cache.

					// ApplyExclusiveModeResourcesSet is a user-defined function that 
					// applies Game Mode presets, perhaps increasing graphical fidelity.
					m_main->ApplyExclusiveModeResourcesSet();
				}

				m_hasExpandedResources = hasExpandedResources;
			}
		}

		// User-defined game loop functions.
		GameTick();
		ProcessEvents();
	}
}

In this section

TopicDescription

GetExpandedResourceExclusiveCpuCount

Gets the expected number of exclusive CPU sets that are available to the app when in Game Mode.

HasExpandedResources

Gets the current resource state (that is, whether the app is running in Game Mode or shared mode).

ReleaseExclusiveCpuSets

Opts out of CPU exclusivity, giving the app access to all cores, but at the cost of having to share them with other processes.

 

 

 

Show: