Getting started with Metal-cpp
Metal-cpp is a low-overhead C++ interface for Metal that helps you add Metal functionality to graphics apps, games, and game engines that are written in C++.
Highlights
- Drop in C++ alternative interface to the Metal Objective-C headers.
- Direct mapping of all Metal Objective-C classes, constants, and enums to C++ in the MTL C++ namespace.
- No measurable overhead compared to calling Metal Objective-C headers, due to inlining of C++ function calls.
- No usage of wrapper containers that require additional allocations.
- Identical header files and function/constant/enum availability for iOS, iPadOS, macOS, and tvOS.
- Backward compatibility: All
bool MTL::Device::supports...()
functions check if their required selectors exist and automatically returnfalse
if not. - String
(ErrorDomain)
constants are weak linked and automatically set tonullptr
if not available.
Installation instructions
1. Prepare your Mac.
- Open Xcode on your Mac. Xcode 9.3 or later includes C++17, which is the minimum required by Metal-cpp because of the use of
constexpr
inNS::Object
. - Download and extract the contents of this ZIP file.
metal-cpp_macOS12_iOS15.zip
metal-cpp_macOS13_iOS16.zip
metal-cpp_macOS13.3_iOS16.4.zip
metal-cpp_macOS14_iOS17-beta.zip
metal-cpp_macOS14.2_iOS17.2.zip
metal-cpp_macOS15_iOS18-beta
2. Add the metal-cpp folder to your build system’s header search path.
In Xcode:
- Click the Project Navigator.
- Click the Project.
- Click Build Settings.
- Search for Header Search Paths.
- Add the path to the extracted folder,
metal-cpp/
. - Search for C++ Language Dialect and make sure it’s set to C++17 or higher.
- Make sure to add the Foundation, QuartzCore, and Metal frameworks to the list of frameworks to be linked in the Build Phases tab.
3. Generate the implementation.
metal-cpp is a header-only library. To generate the implementation, add the following code in one of your .cpp files:
#define NS_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION
#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp>
Note: It’s also possible to include the metal-cpp headers with quotation marks.
4. Use metal-cpp.
From any files that need to reference metal-cpp objects or types, simply include the headers to make the symbols available.
#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp>
Important: Don’t define the NS, MTL, or CA _PRIVATE_IMPLEMENTATION macros more than once.
Metal-cpp single header alternative
For convenience, you can alternatively use metal-cpp as a single-header include in your project.
After you extract the ZIP file contents, run the following command from the terminal to generate a single include header.
./SingleHeader/MakeSingleHeader.py Foundation/Foundation.hpp QuartzCore/QuartzCore.hpp Metal/Metal.hpp
Once completed, the command will have generated a single file: ./SingleHeader/Metal.hpp
. This file includes everything you need to use metal-cpp in your project.
Remember to generate the implementation in one CPP file.
#define NS_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION
#include <Metal/Metal.hpp>
Memory management considerations
Metal-cpp follows the object allocation policies of Cocoa and Cocoa Touch. Understanding those rules is especially important when using metal-cpp because C++ objects aren’t eligible for automatic reference counting (ARC). For more information, refer to the Read Me file in the metal-cpp download.