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 return false if not.
  • String (ErrorDomain) constants are weak linked and automatically set to nullptr if not available.

Installation instructions

1. Prepare your Mac.

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/. Screenshot of path being entered in Xcode
  • Search for C++ Language Dialect and make sure it’s set to C++17 or higher. Screenshot of highlighted setting in Xcode
  • Make sure to add the Foundation, QuartzCore, and Metal frameworks to the list of frameworks to be linked in the Build Phases tab. Screenshot of highlighted library in Xcode

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.