In this article we will get Vulkan running on iOS. This is a pivot point for our iOS platform target - in order to compile an iOS application to use Vulkan it will need to be capable of running Apple’s Metal framework.
If you check the following table: https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html you can see that only iPhone 5s or later - or effectively 64 bit devices - can run Metal. So by introducing Vulkan to our iOS platform, we will have to say goodbye to older iOS devices prior to the 5s (my poor iPad mini!) It should be noted also that the MoltenVK framework needed for Vulkan support cannot compile for the iOS simulator either - so pretty much you have to deploy code to a real iOS device during development.
The iOS platform target is very similar to the MacOS app so once again we’ll get a good amount of reuse from our existing setup scripts.
Open up the ios/setup.sh
script and add the following command directly beneath the existing fetch_third_party_lib_tiny_obj_loader
command:
fetch_third_party_lib_vulkan_macos
This will download the Vulkan SDK for MacOS if necessary, which also contains the iOS MoltenVK libraries.
Next we need to copy the iOS MoltenVK framework and dynamic library into our ios/Frameworks
folder so they can be linked and included in our build. This differs from the MacOS and console application which only used dynamic libraries.
Add the following script to ios/setup.sh
just before the xcodegen
command:
# Check to see if we have the MoltenVK framework and dynamic library
verify_frameworks_folder_exists
pushd "Frameworks"
if [ ! -d "MoltenVK.framework" ]; then
cp -R ../../../third-party/vulkan-mac/MoltenVK/iOS/framework/MoltenVK.framework .
fi
if [ ! -e "libMoltenVK.dylib" ]; then
cp ../../../third-party/vulkan-mac/MoltenVK/iOS/dynamic/libMoltenVK.dylib .
fi
popd
Run the setup script in Terminal in the ios
folder then observe the new files and folders that were generated:
: root
+ ios
+ Frameworks
libMoltenVK.dylib
MoltenVK.framework
We now need to update the project.yml
file to stitch the libraries into our Xcode project. Open the ios/project.yml
file for editing.
Target SDK
To use MoltenVK we’ll need to include the Metal
framework and due to the way we are statically linking the MoltenVK libraries we will need to drop support for non 64 bit iOS devices - anything prior to the iPhone 5s. So we may as well also lift our minimum iOS version to 10 to filter devices to that level. Update the deploymentTarget
to do this:
deploymentTarget:
iOS: "10.0"
Vulkan SDK headers
To include the Vulkan headers we will update the HEADER_SEARCH_PATHS
section - observe the additional Vulkan include path:
HEADER_SEARCH_PATHS:
- $(PROJECT_DIR)/../../third-party/SDL/include
- $(PROJECT_DIR)/../../third-party/glm
- $(PROJECT_DIR)/../../third-party/tiny-obj-loader
- $(PROJECT_DIR)/../../third-party/SDL2_image
- $(PROJECT_DIR)/../../third-party/vulkan-mac/macOS/include
Link MoltenVK framework and dynamic library files
Next we need to link the MoltenVK files into our Xcode project - edit the LIBRARY_SEARCH_PATHS
to include the new Frameworks
folder we created:
LIBRARY_SEARCH_PATHS:
- $(inherited)
- $(PROJECT_DIR)
- $(PROJECT_DIR)/Libs
- $(PROJECT_DIR)/Frameworks
Then edit the dependencies
section and add the two MoltenVK entries and the Metal SDK framework like this:
Important: The order of these dependencies matters - make sure you get them in the same order as shown below.
dependencies:
- framework: Frameworks/libMoltenVK.dylib
embed: true
- framework: Frameworks/MoltenVK.framework
embed: false
- sdk: Metal.framework
- framework: Libs/libSDL2.a
embed: false
- framework: Libs/libSDL2_image.a
embed: false
- sdk: MobileCoreServices.framework
- sdk: CoreMotion.framework
- sdk: CoreGraphics.framework
- sdk: AudioToolbox.framework
- sdk: CoreAudio.framework
- sdk: QuartzCore.framework
- sdk: GameController.framework
- sdk: Foundation.framework
- sdk: OpenGLES.framework
- sdk: UIKit.framework
- sdk: AVFoundation.framework
- sdk: ImageIO.framework
Save and close your project.yml
file, then run the setup.sh
script in your ios
folder to regenerate the Xcode project. When its done, open the project in Xcode run the application on a physical iOS device.
Note: You will need to update the application signing configuration using whatever Apple developer account you normally use. If you are not a registered Apple developer then I don’t think you can actually run iOS apps on a physical device. To avoid configuring the signing every time you regenerate the Xcode project you could include the signing information in the
project.yml
file.
The following screenshot shows the expected output when you run the app - note that I’m running it on a physical device which is why you can’t see a device in the picture.
The setup for MacOS/console and iOS ended up being pretty straight forward but it took me ages to figure out the correct incantations to apply to get it working.
Next up we’ll wrangle Vulkan on Android which is anything but straight forward!
The code for this article can be found here.
Continue to Part 17: Vulkan setup Android.
End of part 16