Use the device object’s properties to determine how you perform tasks in Metal.
GPUs don’t support a single common feature set. Instead, different GPUs support different capabilities. Newer, more powerful GPUs support more advanced features, letting you perform more complex tasks or perform the same task using a different technique the GPU can process more efficiently.
You need to determine which Metal features that a specific device object supports and use that information to choose your app’s behavior. For example, you might:
Create multiple rendering or compute paths, and have your app dynamically choose the best option for each GPU.
Restrict some features to specific GPUs or implement different levels of functionality. For example, in a game, you might remove shadows or reduce the complexity of shadows on older GPUs.
Restrict your app so that it only runs when some GPUs are available; however, you should only use this option in extreme cases.
The version of Metal running on the system and the GPU you are targeting determine which features are available. The
MTLDevice object provides information about the software and hardware capabilities for a specific GPU. The Using Metal Feature Set Tables summarize the available features.
A new version of Metal adds multiple features to device object at the same time. You should design your app around collections of common functionality. For example, on iOS, you might design two major rendering paths: one for current and future GPUs, and one for earlier GPUs.
Determine GPU Feature Support
Metal organizes GPUs into four major families:
Use the Common family to create apps that target a range of GPUs on multiple platforms.
Use the Apple family to create apps that target Apple GPUs.
Use the Mac family to create apps that target GPUs on macOS systems.
Use the UIKit for Mac family when building for UIKit on the Mac.
A GPU can be a member of more than one family; in most cases, a GPU supports one of the Common families and then one or more families specific to the build target.
More recent GPUs have higher version numbers and support larger feature sets. A higher GPU version is always a superset of an earlier version in the same GPU family. For details on the individual families and version numbers, see
The code below shows how to test whether a GPU supports a particular GPU family:
Determine Metal Version Availability
Each new Metal release adds new features for supported GPUs. In addition to checking for a GPU with the correct family, ensure that the features your app needs are also there. Choose the specific version of Metal you are looking for, and query the device object for that version of Metal. For example, use the code below to detect support for Metal 3:
Always check for the Metal version number, rather than the operating system version. In some cases, the Metal framework may provide the API for some features but not be able to support them. For example, if you are using Simulator, the operating system running in Simulator may be newer than the host operating system. In situations like this, the device object may tell you that it doesn’t support the newer feature set.
Find Variations in a GPU Family
GPUs in the same family can vary in small ways. Some features aren’t supported uniformly across a family. Use the device object to test for the existence of these features using an API specific to each feature.
For example, Metal’s argument buffer feature has two tiers of support; the second tier is significantly better than the first. The code below shows how to test for tier 2 support:
Discover Feature Availability in Metal 2
If the Metal 3 API isn’t available, you can test for features using feature sets. A feature set combines a Metal GPU family number with a software revision number. For example, to test for the first release of Metal that supported Apple family 4 GPUs, use
MTLFeature, as shown here:
Metal added new feature set enumerations in new versions of Apple operating systems to support new software features and GPU families, so there are many different enumeration values representing different collections of features. If a GPU supports a feature set, it supports all features provided by earlier members of the same family, and all features in earlier software revisions. For example,
MTLFeature is version 2 of family 4, so it supports the same features as version 1, as well as all features supported by families 1, 2, and 3. You don’t need to test for those feature sets separately. Test for feature sets, from newest to oldest, until you successfully find a feature set that your app and the GPU both support.