2017-11-17 11:14:29 -05:00
< a class = "site-logo" href = "https://github.com/KhronosGroup/MoltenVK" title = "MoltenVK" >
< img src = "images/MoltenVK-Logo-Banner.png" alt = "MoltenVK" style = "width:256px;height:auto" >
< / a >
MoltenVK Runtime User Guide
===========================
2020-01-07 16:47:29 -05:00
Copyright (c) 2015-2020 [The Brenwill Workshop Ltd. ](http://www.brenwill.com )
2017-11-17 11:14:29 -05:00
*This document is written in [Markdown ](http://en.wikipedia.org/wiki/Markdown ) format.
For best results, use a Markdown reader.*
Table of Contents
-----------------
- [About This Document ](#about_this )
- [About **MoltenVK** ](#about_moltenvk )
- [Installing **MoltenVK** in Your *Vulkan* Application ](#install )
2018-03-01 19:42:15 -05:00
- [Build and Runtime Requirements ](#requirements )
2018-10-30 23:16:12 -04:00
- [Install as Static Framework, Static Library, or Dynamic Library ](#install_lib )
2017-11-17 11:14:29 -05:00
- [Interacting with the **MoltenVK** Runtime ](#interaction )
2019-01-12 12:19:01 -05:00
- [MoltenVK `VK_MVK_moltenvk` Extension ](#moltenvk_extension )
- [Configuring MoltenVK ](#moltenvk_config )
2017-11-17 11:14:29 -05:00
- [*Metal Shading Language* Shaders ](#shaders )
- [MoltenVKShaderConverter Shader Converter Tool ](#shader_converter_tool )
- [Troubleshooting Shader Conversion ](#spv_vs_msl )
- [Performance Considerations ](#performance )
- [Shader Loading Time ](#shader_load_time )
2020-01-07 13:50:35 -05:00
- [Swapchains ](#swapchains )
2017-11-17 11:14:29 -05:00
- [Xcode Configuration ](#xcode_config )
- [Metal System Trace Tool ](#trace_tool )
- [Known **MoltenVK** Limitations ](#limitations )
< a name = "about_this" > < / a >
About This Document
-------------------
This document describes how to integrate the **MoltenVK** runtime distribution package into a game
or application, once **MoltenVK** has been built into a framework or library for *iOS* or *macOS* .
To learn how to use the **MoltenVK** open-source repository to build a **MoltenVK** runtime
2018-03-06 14:07:06 -05:00
distribution package, see the main [`README.md` ](../README.md ) document in the `MoltenVK` repository.
2017-11-17 11:14:29 -05:00
< a name = "about_moltenvk" > < / a >
About **MoltenVK**
------------------
2020-03-19 18:01:05 -04:00
**MoltenVK** is a layered implementation of [*Vulkan 1.0* ](https://www.khronos.org/vulkan )
graphics and compute functionality, that is built on Apple's [*Metal* ](https://developer.apple.com/metal )
graphics and compute framework on both *iOS* and *macOS* . **MoltenVK** allows you to use *Vulkan* graphics
and compute functionality to develop modern, cross-platform, high-performance graphical games and applications,
and to run them across many platforms, including both *iOS* and *macOS* .
2017-11-17 11:14:29 -05:00
*Metal* uses a different shading language, the *Metal Shading Language (MSL)* , than
2018-07-23 20:12:57 -04:00
*Vulkan*, which uses *SPIR-V* . **MoltenVK** automatically converts your *SPIR-V* shaders
to their *MSL* equivalents. This can be performed transparently at run time, using the
**Runtime Shader Conversion** feature of **MoltenVK** , or at development time using the
2020-05-30 15:45:29 +10:00
[**MoltenVKShaderConverter** ](#shader_converter_tool ) tool provided with this **MoltenVK**
2018-07-23 20:12:57 -04:00
distribution package.
To provide *Vulkan* capability to the *iOS* and *macOS* platforms, **MoltenVK** uses *Apple's*
publicly available API's, including *Metal* . **MoltenVK** does **_not_** use any private or
undocumented API calls or features, so your app will be compatible with all standard distribution
channels, including *Apple's App Store* .
2017-11-17 11:14:29 -05:00
< a name = "install" > < / a >
Installing **MoltenVK** in Your *Vulkan* Application
----------------------------------------------------
2018-03-01 19:42:15 -05:00
< a name = "requirements" > < / a >
### Build and Runtime Requirements
2019-02-13 14:34:55 -05:00
**MoltenVK** references the latest *Apple SDK* frameworks. To access these frameworks when building
your app, and to avoid build errors, be sure to use the latest publicly available version of *Xcode* .
2018-03-01 19:42:15 -05:00
2019-02-13 14:34:55 -05:00
>***Note:*** To support `IOSurfaces` , any app that uses **MoltenVK** , must be built with a minimum
**iOS Deployment Target** (aka `IPHONEOS_DEPLOYMENT_TARGET ` ) build setting of `iOS 11.0` or greater.
2018-03-01 19:42:15 -05:00
2019-02-13 14:34:55 -05:00
Once built, your app integrating the **MoltenVK** libraries can be run on *iOS* or *macOS* devices
that support *Metal* .
- At runtime, **MoltenVK** requires at least *macOS 10.11* or *iOS 9* (or *iOS 11* if using `IOSurfaces` ).
2018-03-01 19:42:15 -05:00
- Information on *macOS* devices that are compatible with *Metal* can be found in
[this article ](http://www.idownloadblog.com/2015/06/22/how-to-find-mac-el-capitan-metal-compatible ).
2019-02-13 14:34:55 -05:00
- Information on *iOS* devices that are compatible with *Metal* can be found in
2018-03-01 19:42:15 -05:00
[this article ](https://developer.apple.com/library/content/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/HardwareGPUInformation/HardwareGPUInformation.html ).
2017-11-17 11:14:29 -05:00
2019-02-13 14:34:55 -05:00
2018-10-30 23:16:12 -04:00
< a name = "install_lib" > < / a >
### Install as Static Framework, Static Library, or Dynamic Library
2017-11-17 11:14:29 -05:00
Installation of **MoltenVK** is straightforward and easy!
2018-10-30 23:16:12 -04:00
Depending on your build and deployment needs, you can install **MoltenVK** as a *static framework* ,
*static library*, or *dynamic library* , by following the steps in this section. If you are unsure
about which linking and deployment option you need, follow the steps for installing a
*static framework*, as it is the simplest to install.
2019-09-25 19:04:33 -05:00
>**_Note:_** Distributing an app containing a dynamic library via the *iOS App Store* can require
specialized bundling. Unless you have specific needs for dynamic libraries, the recommended
approach on *iOS* is to link **MoltenVK** to your app as a static library.
2017-11-17 11:14:29 -05:00
1. Open your application in *Xcode* and select your application's target in the
*Project Navigator* panel.
2018-07-12 18:26:54 -04:00
2018-10-30 23:16:12 -04:00
2. Open the *Build Settings* tab.
- If installing **MoltenVK** as a *static framework* in your application:
1. In the **Framework Search Paths** (aka `FRAMEWORK_SEARCH_PATHS` )
setting, add an entry that points to **_one_** of the following folders:
- `MoltenVK/macOS/framework` *(macOS)*
- `MoltenVK/iOS/framework` *(iOS)*
- If installing **MoltenVK** as a *static library* in your application:
1. In the **Library Search Paths** (aka `LIBRARY_SEARCH_PATHS` ) setting,
add an entry that points to **_one_** of the following folders:
- `MoltenVK/macOS/static` *(macOS)*
- `MoltenVK/iOS/static` *(iOS)*
2019-10-01 00:25:09 -04:00
2018-10-30 23:16:12 -04:00
2. In the **Header Search Paths** (aka `HEADER_SEARCH_PATHS` ) setting,
add an entry that points to the `MoltenVK/include` folder.
- If installing **MoltenVK** as a *dynamic library* in your application:
1. In the **Library Search Paths** (aka `LIBRARY_SEARCH_PATHS` ) setting,
add an entry that points to **_one_** of the following folders:
- `MoltenVK/macOS/dynamic` *(macOS)*
- `MoltenVK/iOS/dynamic` *(iOS)*
2019-10-01 00:25:09 -04:00
2018-10-30 23:16:12 -04:00
2. In the **Header Search Paths** (aka `HEADER_SEARCH_PATHS` ) setting,
add an entry that points to the `MoltenVK/include` folder.
3. In the **Runpath Search Paths** (aka `LD_RUNPATH_SEARCH_PATHS` ) setting,
add an entry that matches where the dynamic library will be located in your runtime
environment. If the dynamic library is to be embedded within your application,
2019-10-01 00:25:09 -04:00
you would typically set this value to either:
- `@executable_path/../Frameworks` *(macOS)*
- `@executable_path/Frameworks` *(iOS)*
2018-10-30 23:16:12 -04:00
The `libMoltenVK.dylib` library is internally configured to be located at
`@rpath/libMoltenVK.dylib` .
3. With the *Build Settings* tab open, if using `IOSurfaces` on *iOS* , open the **iOS Deployment Target**
2018-07-12 18:26:54 -04:00
(aka `IPHONEOS_DEPLOYMENT_TARGET` ) setting, and ensure it is set to a value of `iOS 11.0` or greater.
4. On the *Build Phases* tab, open the *Link Binary With Libraries* list.
2018-10-30 23:16:12 -04:00
- For *macOS* , drag **_one_** of the following files to the *Link Binary With Libraries* list:
- `MoltenVK/macOS/framework/MoltenVK.framework ` *(static framework)*
- `MoltenVK/macOS/static/libMoltenVK.a` *(static library)*
- `MoltenVK/macOS/dynamic/libMoltenVK.dylib` *(dynamic library)*
- For *iOS* , drag **_one_** of the following files to the *Link Binary With Libraries* list:
- `MoltenVK/iOS/framework/MoltenVK.framework ` *(static framework)*
- `MoltenVK/iOS/static/libMoltenVK.a` *(static library)*
- `MoltenVK/iOS/dynamic/libMoltenVK.dylib` *(dynamic library)*
5. While in the *Link Binary With Libraries* list on the *Build Phases* tab, if you do **_not_**
have the **Link Frameworks Automatically** (aka `CLANG_MODULES_AUTOLINK` ) and
**Enable Modules (C and Objective-C)** (aka `CLANG_ENABLE_MODULES` ) settings enabled, click
the ** +** button, and (selecting from the list of system frameworks) add the following items:
- `libc++.tbd`
- `Metal.framework`
- `Foundation.framework` .
- `QuartzCore.framework`
- `IOKit.framework` (*macOS*)
- `UIKit.framework` (*iOS*)
- `IOSurface.framework` (*macOS*, or *iOS* if `IPHONEOS_DEPLOYMENT_TARGET` is at least `iOS 11.0` )
6. If installing **MoltenVK** as a *dynamic library* in your application, arrange to install
the `libMoltenVK.dylib` file in your application environment:
2017-11-17 11:14:29 -05:00
2018-10-30 23:16:12 -04:00
- To copy the `libMoltenVK.dylib` file into your application or component library:
2019-10-01 00:25:09 -04:00
2018-10-30 23:16:12 -04:00
1. On the *Build Phases* tab, add a new *Copy Files* build phase.
2019-10-01 00:25:09 -04:00
2018-10-30 23:16:12 -04:00
2. Set the *Destination* into which you want to place the `libMoltenVK.dylib` file.
2019-10-01 00:25:09 -04:00
Typically this will be *Frameworks* (and should match the **Runpath Search Paths**
(aka `LD_RUNPATH_SEARCH_PATHS` ) build setting you set above).
2018-10-30 23:16:12 -04:00
3. Drag **_one_** of the following files to the *Copy Files* list in this new build phase:
- `MoltenVK/macOS/dynamic/libMoltenVK.dylib` *(macOS)*
- `MoltenVK/iOS/dynamic/libMoltenVK.dylib` *(iOS)*
- Alternately, you may create your own installation mechanism to install either the
`MoltenVK/macOS/dynamic/libMoltenVK.dylib` or `MoltenVK/iOS/dynamic/libMoltenVK.dylib`
file into a standard *macOS* or *iOS* system library folder on the user's device.
7. When a *Metal* app is running from *Xcode* , the default ** *Scheme*** settings reduce
2017-11-17 11:14:29 -05:00
performance. To improve performance and gain the benefits of *Metal* , perform the
following in *Xcode* :
1. Open the ** *Scheme Editor*** for building your main application. You can do
this by selecting ** *Edit Scheme...*** from the ** *Scheme*** drop-down menu, or select
** *Product -> Scheme -> Edit Scheme...*** from the main menu.
2. On the ** *Info*** tab, set the ** *Build Configuration*** to ** *Release***, and disable the
** *Debug executable*** check-box.
3. On the ** *Options*** tab, disable both the ** *Metal API Validation*** and ** *GPU Frame Capture***
options. For optimal performance, you may also consider disabling the other simulation
and debugging options on this tab. For further information, see the
[Xcode Scheme Settings and Performance ](https://developer.apple.com/library/ios/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/Dev-Technique/Dev-Technique.html#//apple_ref/doc/uid/TP40014221-CH8-SW3 )
section of Apple's *Metal Programming Guide* documentation.
2018-10-30 23:16:12 -04:00
The demo apps, found in the `Demos.xcworkspace` , located in the `Demos` folder, demonstrate each
of the installation techniques discussed above:
2017-11-17 11:14:29 -05:00
2018-10-30 23:16:12 -04:00
- Static Framework: `API-Samples` .
- Static library: `Hologram` .
- Dynamic library: `Cube` .
2017-11-17 11:14:29 -05:00
< a name = "interaction" > < / a >
Interacting with the **MoltenVK** Runtime
-----------------------------------------
You programmatically configure and interact with the **MoltenVK** runtime through function
calls, enumeration values, and capabilities, in exactly the same way you do with other
2019-02-18 22:19:37 +00:00
*Vulkan* implementations. **MoltenVK** contains several header files that define access
to *Vulkan* and **MoltenVK** function calls.
2017-11-17 11:14:29 -05:00
In your application code, you access *Vulkan* features through the API defined in the standard
`vulkan.h` header file. This file is included in the **MoltenVK** framework, and can be included
in your source code files as follows:
#include < vulkan / vulkan . h >
2020-03-19 18:01:05 -04:00
In addition to core *Vulkan* functionality, **MoltenVK** also supports the following *Vulkan* extensions:
2017-11-17 11:14:29 -05:00
2018-12-04 15:55:18 -06:00
- `VK_KHR_16bit_storage`
2018-11-06 17:15:07 -06:00
- `VK_KHR_8bit_storage`
2018-12-06 09:52:17 -06:00
- `VK_KHR_bind_memory2`
2018-12-04 15:55:18 -06:00
- `VK_KHR_dedicated_allocation`
- `VK_KHR_descriptor_update_template`
2019-07-23 23:52:34 -05:00
- `VK_KHR_device_group`
- `VK_KHR_device_group_creation`
2018-12-04 15:55:18 -06:00
- `VK_KHR_get_memory_requirements2`
- `VK_KHR_get_physical_device_properties2`
2019-03-21 08:53:18 -04:00
- `VK_KHR_get_surface_capabilities2`
2018-12-04 15:55:18 -06:00
- `VK_KHR_image_format_list`
- `VK_KHR_maintenance1`
- `VK_KHR_maintenance2`
- `VK_KHR_maintenance3`
- `VK_KHR_push_descriptor`
- `VK_KHR_relaxed_block_layout`
2019-06-29 19:16:16 -05:00
- `VK_KHR_sampler_mirror_clamp_to_edge` *(macOS)*
2020-05-07 16:02:10 +02:00
- `VK_KHR_sampler_ycbcr_conversion`
2018-12-04 15:55:18 -06:00
- `VK_KHR_shader_draw_parameters`
2018-12-04 16:55:59 -06:00
- `VK_KHR_shader_float16_int8`
2018-12-04 15:55:18 -06:00
- `VK_KHR_storage_buffer_storage_class`
- `VK_KHR_surface`
- `VK_KHR_swapchain`
2018-12-04 23:39:12 -06:00
- `VK_KHR_swapchain_mutable_format`
2019-07-15 12:20:31 -05:00
- `VK_KHR_uniform_buffer_standard_layout`
2019-01-15 14:56:08 -06:00
- `VK_KHR_variable_pointers`
2019-06-30 11:16:08 -04:00
- `VK_EXT_debug_marker`
2019-05-01 22:27:03 -04:00
- `VK_EXT_debug_report`
2019-06-30 11:16:08 -04:00
- `VK_EXT_debug_utils`
2019-09-06 12:27:40 -05:00
- `VK_EXT_fragment_shader_interlock` *(requires Metal 2.0 and Raster Order Groups)*
2019-03-17 17:08:32 -05:00
- `VK_EXT_host_query_reset`
2019-11-25 21:35:38 +00:00
- `VK_EXT_inline_uniform_block`
2019-07-15 22:31:03 -05:00
- `VK_EXT_memory_budget` *(requires Metal 2.0)*
2019-07-03 20:23:43 -04:00
- `VK_EXT_metal_surface`
2019-07-17 10:52:16 -05:00
- `VK_EXT_post_depth_coverage` *(iOS, requires GPU family 4)*
2020-06-15 19:29:57 -05:00
- `VK_EXT_robustness2`
2019-07-17 10:34:47 -05:00
- `VK_EXT_scalar_block_layout`
2019-06-29 19:16:16 -05:00
- `VK_EXT_shader_stencil_export` *(requires Mac GPU family 2 or iOS GPU family 5)*
2018-12-04 15:55:18 -06:00
- `VK_EXT_shader_viewport_index_layer`
2019-03-19 19:35:03 -05:00
- `VK_EXT_swapchain_colorspace` *(macOS)*
2018-12-04 15:55:18 -06:00
- `VK_EXT_vertex_attribute_divisor`
2019-07-15 22:31:03 -05:00
- `VK_EXT_texel_buffer_alignment` *(requires Metal 2.0)*
2019-01-27 19:52:59 -05:00
- `VK_EXTX_portability_subset`
2019-07-03 20:23:43 -04:00
- `VK_MVK_ios_surface` *(iOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
- `VK_MVK_macos_surface` *(macOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
2019-01-12 12:19:01 -05:00
- `VK_MVK_moltenvk`
2018-12-04 16:08:46 -06:00
- `VK_AMD_gpu_shader_half_float`
2018-12-04 15:55:18 -06:00
- `VK_AMD_negative_viewport_height`
2019-07-17 10:57:08 -05:00
- `VK_AMD_shader_image_load_store_lod` *(iOS)*
- `VK_AMD_shader_trinary_minmax` *(requires Metal 2.1)*
2019-07-03 20:23:43 -04:00
- `VK_IMG_format_pvrtc` *(iOS)*
2019-07-17 11:06:05 -05:00
- `VK_INTEL_shader_integer_functions2`
2019-05-10 12:21:03 -04:00
- `VK_NV_glsl_shader`
2017-11-17 11:14:29 -05:00
2019-07-03 20:23:43 -04:00
In order to visibly display your content on *iOS* or *macOS* , you must enable the `VK_EXT_metal_surface`
extension, and use the function defined in that extension to create a *Vulkan* rendering surface.
You can enable the `VK_EXT_metal_surface` extension by defining the `VK_USE_PLATFORM_METAL_EXT`
guard macro in your compiler build settings. See the description of the `mvk_vulkan.h` file below for
a convenient way to enable this extension automatically.
2017-11-17 11:14:29 -05:00
2019-01-12 12:19:01 -05:00
2017-11-17 11:14:29 -05:00
< a name = "moltenvk_extension" > < / a >
2019-01-12 12:19:01 -05:00
### MoltenVK `VK_MVK_moltenvk` Extension
2017-11-17 11:14:29 -05:00
2020-03-19 18:01:05 -04:00
The `VK_MVK_moltenvk` *Vulkan* extension provides functionality beyond standard *Vulkan* functionality,
to support configuration options and behaviour that is specific to the **MoltenVK** implementation of *Vulkan*
functionality. You can access this functionality by including the `vk_mvk_moltenvk.h` header file in your code.
2019-01-12 12:19:01 -05:00
The `vk_mvk_moltenvk.h` file also includes the API documentation for this `VK_MVK_moltenvk` extension.
2017-11-17 11:14:29 -05:00
The following API header files are included in the **MoltenVK** package, each of which
can be included in your application source code as follows:
#include < MoltenVK / HEADER_FILE >
where `HEADER_FILE` is one of the following:
2018-05-24 13:20:51 +08:00
- `vk_mvk_moltenvk.h` - Contains declarations and documentation for the functions, structures,
2017-11-17 11:14:29 -05:00
and enumerations that define the behaviour of the `VK_MVK_moltenvk` *Vulkan* extension.
- `mvk_vulkan.h` - This is a convenience header file that loads the `vulkan.h` header file
with the appropriate **MoltenVK** *Vulkan* platform surface extension automatically
enabled for *iOS* or *macOS* . Use this header file in place of the `vulkan.h` header file,
where access to a **MoltenVK** platform surface extension is required.
2019-07-03 20:23:43 -04:00
The `mvk_vulkan.h` header file automatically enables the `VK_USE_PLATFORM_METAL_EXT`
build setting and `VK_EXT_metal_surface` *Vulkan* extension.
2017-11-17 11:14:29 -05:00
- `mvk_datatypes.h` - Contains helpful functions for converting between *Vulkan* and *Metal* data types.
You do not need to use this functionality to use **MoltenVK** , as **MoltenVK** converts between
*Vulkan* and *Metal* datatypes automatically (using the functions declared in this header).
These functions are exposed in this header for your own purposes such as interacting with *Metal*
directly, or simply logging data values.
2019-06-29 19:55:07 -04:00
>***Note:*** The functions in `vk_mvk_moltenvk.h` are not supported by the *Vulkan SDK Loader and Layers*
framework. The opaque Vulkan objects used by the functions in `vk_mvk_moltenvk.h` (`VkInstance` ,
`VkPhysicalDevice` , `VkShaderModule` , `VKImage` , ...), must have been retrieved directly from **MoltenVK** ,
and not through the *Vulkan SDK Loader and Layers* framework. The *Vulkan SDK Loader and Layers* framework
often changes these opaque objects, and passing them from a higher layer directly to **MoltenVK** will
result in undefined behaviour.
2017-11-17 11:14:29 -05:00
2019-01-12 12:19:01 -05:00
< a name = "moltenvk_config" > < / a >
### Configuring MoltenVK
The `VK_MVK_moltenvk` *Vulkan* extension provides the ability to configure and optimize
**MoltenVK** for your particular application runtime requirements.
There are three mechanisms for setting the values of the **MoltenVK** configuration parameters:
- Runtime API via the `vkGetMoltenVKConfigurationMVK()/vkSetMoltenVKConfigurationMVK()` functions.
- Application runtime environment variables.
- Build settings at **MoltenVK** build time.
2020-01-21 14:05:58 -05:00
To change some of the **MoltenVK** configuration settings at runtime using a programmatic API,
use the `vkGetMoltenVKConfigurationMVK()` and `vkSetMoltenVKConfigurationMVK()` functions to
retrieve, modify, and set a copy of the `MVKConfiguration` structure.
2019-01-12 12:19:01 -05:00
2020-01-21 14:05:58 -05:00
The initial value of each of the configuration settings can be established at runtime
2019-01-12 12:19:01 -05:00
by a corresponding environment variable, or if the environment variable is not set,
by a corresponding build setting at the time **MoltenVK** is compiled. The environment
variable and build setting for each configuration parameter share the same name.
2020-01-21 14:05:58 -05:00
There are also a number of additional runtime environment variables that are not included in the
`MVKConfiguration` structure, but that also control **MoltenVK** behaviour.
See the description of the environment variables and the `MVKConfiguration` structure parameters
in the `vk_mvk_moltenvk.h` file for more info about configuring and optimizing **MoltenVK**
at runtime or build time.
2019-01-12 12:19:01 -05:00
2017-11-17 11:14:29 -05:00
< a name = "shaders" > < / a >
*Metal Shading Language* Shaders
--------------------------------
*Metal* uses a different shader language than *Vulkan* . *Vulkan* uses the new
*SPIR-V Shading Language (SPIR-V)*, whereas *Metal* uses the *Metal Shading Language (MSL)* .
**MoltenVK** provides several options for creating and running *MSL* versions of your
existing *SPIR-V* shaders. The following options are presented in order of increasing
sophistication and difficulty:
- You can use the automatic **Runtime Shader Conversion** feature of **MoltenVK** to automatically
and transparently convert your *SPIR-V* shaders to *MSL* at runtime, by simply loading your
*SPIR-V* shaders as you always have, using the standard *Vulkan* `vkCreateShaderModule()`
function. **MoltenVK** will automatically convert the *SPIR-V* code to *MSL* at runtime.
- You can use the standard *Vulkan* `vkCreateShaderModule()` function to provide your own *MSL*
shader code. To do so, set the value of the *magic number* element of the *SPIR-V* stream to one
of the values in the `MVKMSLMagicNumber` enumeration found in the `vk_mvk_moltenvk.h` header file.
The *magic number* element of the *SPIR-V* stream is the first element of the stream,
and by setting the value of this element to either `kMVKMagicNumberMSLSourceCode` or
`kMVKMagicNumberMSLCompiledCode` , on *SPIR-V* code that you submit to the `vkCreateShaderModule()`
function, you are indicating that the remainder of the *SPIR-V* stream contains either
*MSL* source code, or *MSL* compiled code, respectively.
2018-05-24 13:20:51 +08:00
- You can use the `MoltenVKShaderConverter` command-line tool found in this **MoltenVK** distribution
2017-11-17 11:14:29 -05:00
package to convert your *SPIR-V* shaders to *MSL* source code, offline at development time,
in order to create the appropriate *MSL* code to load at runtime. The [section below ](#shaders )
discusses how to use this tool in more detail.
You can mix and match these options in your application. For example, a convenient approach is
to use **Runtime Shader Conversion** for most *SPIR-V* shaders, and provide pre-converted *MSL*
shader source code for the odd *SPIR-V* shader that proves problematic for runtime conversion.
< a name = "shader_converter_tool" > < / a >
2018-02-26 17:30:47 +01:00
### MoltenVKShaderConverter Shader Converter Tool
2017-11-17 11:14:29 -05:00
The **MoltenVK** distribution package includes the `MoltenVKShaderConverter` command line tool,
which allows you to convert your *SPIR-V* shader source code to *MSL* at development time, and
then supply the *MSL* code to **MoltenVK** using one of the methods described in the
[*Metal Shading Language* Shaders ](#shaders ) section above.
The `MoltenVKShaderConverter` tool uses the same conversion technology as the **Runtime Shader
Conversion** feature of **MoltenVK** .
The `MoltenVKShaderConverter` tool has a number of options available from the command line:
- The tool can be used to convert a single *SPIR-V* file to *MSL* , or an entire directory tree
of *SPIR-V* files to *MSL* .
- The tool can be used to convert a single *OpenGL GLSL* file, or an entire directory tree
of *GLSL* files to either *SPIR-V* or *MSL* .
To see a complete list of options, run the `MoltenVKShaderConverter` tool from the command
line with no arguments.
< a name = "spv_vs_msl" > < / a >
2018-02-26 17:30:47 +01:00
### Troubleshooting Shader Conversion
2017-11-17 11:14:29 -05:00
The shader converter technology in **MoltenVK** is quite robust, and most *SPIR-V* shaders
can be converted to *MSL* without any problems. In the case where a conversion issue arises,
you can address the issue as follows:
- Errors encountered during **Runtime Shader Conversion** are logged to the console.
2019-01-12 12:19:01 -05:00
- To help understand conversion issues during **Runtime Shader Conversion** , you can enable the
logging of the *SPIR-V* and *MSL* shader source code during shader conversion, by turning on
the `MVKConfiguration::debugMode` configuration parameter, or setting the value of the `MVK_DEBUG`
runtime environment variable to `1` . See the [*MoltenVK Configuration* ](#moltenvk_config )
description above.
Enabling debug mode in **MoltenVK** includes shader conversion logging, which causes both
the incoming *SPIR-V* code and the converted *MSL* source code to be logged to the console
in human-readable form. This allows you to manually verify the conversions, and can help
you diagnose issues that might occur during shader conversion.
2017-11-17 11:14:29 -05:00
- For minor issues, you may be able to adjust your *SPIR-V* code so that it behaves the same
under *Vulkan* , but is easier to automatically convert to *MSL* .
- For more significant issues, you can use the `MoltenVKShaderConverter` tool to convert the
shaders at development time, adjust the *MSL* code manually so that it compiles correctly,
and use the *MSL* shader code instead of the *SPIR-V* code, using the techniques described
in the [*Metal Shading Language* Shaders ](#shaders ) section above.
- You are also encouraged to report issues with shader conversion to the
[*SPIRV-Cross* ](https://github.com/KhronosGroup/SPIRV-Cross/issues ) project. **MoltenVK** and
**MoltenVKShaderConverter** make use of *SPIRV-Cross* to convert *SPIR-V* shaders to *MSL* shaders.
< a name = "performance" > < / a >
Performance Considerations
--------------------------
This section discusses various options for improving performance when using **MoltenVK** .
< a name = "shader_load_time" > < / a >
2018-02-26 17:30:47 +01:00
### Shader Loading Time
2017-11-17 11:14:29 -05:00
2018-03-30 12:13:50 -04:00
A number of steps is require to load and compile *SPIR-V* shaders into a form that *Metal* can use.
Although the overall process is fast, the slowest step involves converting shaders from *SPIR-V* to
*MSL* source code format.
If you have a lot of shaders, you can dramatically improve shader loading time by using the standard
*Vulkan pipeline cache* feature, to serialize shaders and store them in *MSL* form offline.
Loading *MSL* shaders via the pipeline cache serializing mechanism can be significantly faster than
converting from *SPIR-V* to *MSL* each time.
In *Vulkan* , pipeline cache serialization for offline storage is available through the
`vkGetPipelineCacheData()` and `vkCreatePipelineCache()` functions. Loading the pipeline cache
from offline storage at app start-up time can dramatically improve both shader loading performance,
and performance glitches and hiccups during runtime code if shader loading is performed then.
When using pipeline caching, nothing changes about how you load *SPIR-V* shader code. **MoltenVK**
automatically detects that the *SPIR-V* was previously converted to *MSL* , and stored offline via
the *Vulkan* pipeline cache serialization mechanism, and does not invoke the relatively expensive
step of converting the *SPIR-V* to *MSL* again.
As a second shader loading performance option, *Metal* also supports pre-compiled shaders, which
can improve shader loading and set-up performance, allowing you to reduce your scene loading time.
See the [*Metal Shading Language* Shaders ](#shaders ) and
[MoltenVKShaderConverter Shader Converter Tool ](#shader_converter_tool ) sections above for more
information about how to use the `MoltenVKShaderConverter` tool to create and load pre-compiled
*Metal* shaders into **MoltenVK** . This behaviour is not standard *Vulkan* behaviour, and does not
improve performance significantly. Your first choice should be to use offline storage of pipeline
cache contents as described in the previous paragraphs.
2017-11-17 11:14:29 -05:00
2020-01-07 13:50:35 -05:00
< a name = "swapchains" > < / a >
### Swapchains
*Metal* supports a very small number (3) of concurrent swapchain images. In addition, *Metal* can
sometimes hold onto these images during surface presentation.
**MoltenVK** supports using either 2 or 3 swapchain images. For best performance, it is recommended
that you use 3 swapchain images (triple-buffering), to ensure that at least one swapchain image will
be available when you need to render to it.
Using 3 swapchain images is particularly important when rendering to a full-screen surface, because
in that situation, *Metal* uses its *Direct to Display* feature, and avoids compositing the swapchain
image onto a separate composition surface before displaying it. Although *Direct to Display* can improve
performance throughput, it also means that *Metal* may hold onto each swapchain image a little longer
than when using an internal compositor, which increases the risk that a swapchain image will not be a
vailable when you request it, resulting in frame delays and visual stuttering.
2017-11-17 11:14:29 -05:00
< a name = "xcode_config" > < / a >
2018-02-26 17:30:47 +01:00
### Xcode Configuration
2017-11-17 11:14:29 -05:00
When a *Metal* app is running from *Xcode* , the default ** *Scheme*** settings reduce performance.
Be sure to follow the instructions for configuring your application's ** *Scheme*** within *Xcode* ,
found in the in the [installation ](#install ) section above.
< a name = "trace_tool" > < / a >
2018-02-26 17:30:47 +01:00
### Metal System Trace Tool
2017-11-17 11:14:29 -05:00
To help you get the best performance from your graphics app, the *Xcode Instruments* profiling tool
includes the *Metal System Trace* template. This template can be used to provide detailed tracing of the
CPU and GPU behaviour of your application, allowing you unprecedented performance measurement
and tuning capabilities for apps using *Metal* .
< a name = "limitations" > < / a >
Known **MoltenVK** Limitations
2018-01-18 10:58:04 -05:00
------------------------------
2017-11-17 11:14:29 -05:00
This section documents the known limitations in this version of **MoltenVK** .
2020-03-19 18:01:05 -04:00
- Since **MoltenVK** is an implementation of *Vulkan* functionality, it does not load
*Vulkan Layers* on its own. In order to use *Vulkan Layers* , such as the validation layers,
use the *Vulkan Loader and Layers* from the [LunarG Vulkan SDK ](https://vulkan.lunarg.com ).
2017-11-17 11:14:29 -05:00
2019-03-26 13:31:26 -04:00
- Application-controlled memory allocations using `VkAllocationCallbacks` are ignored.
- Pipeline statistics query pool using `VK_QUERY_TYPE_PIPELINE_STATISTICS` is not supported.
- Image content in `PVRTC` compressed formats must be loaded directly into a `VkImage` using
host-visible memory mapping. Loading via a staging buffer will result in malformed image content.