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 )
2020-09-01 14:39:46 -04:00
- [Install *MoltenVK* as a Universal `XCFramework` ](#install_xcfwk )
- [Install *MoltenVK* as a Dynamic Library ](#install_dylib )
2018-03-01 19:42:15 -05:00
- [Build and Runtime Requirements ](#requirements )
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
-------------------
2020-06-23 23:06:08 -04:00
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 *macOS* , *iOS* , or *tvOS* .
2017-11-17 11:14:29 -05:00
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-09-03 02:16:19 -05:00
**MoltenVK** is a layered implementation of [*Vulkan 1.1* ](https://www.khronos.org/vulkan )
2020-03-19 18:01:05 -04:00
graphics and compute functionality, that is built on Apple's [*Metal* ](https://developer.apple.com/metal )
2020-06-23 23:06:08 -04:00
graphics and compute framework on *macOS* , *iOS* , and *tvOS* . **MoltenVK** allows you to use *Vulkan*
graphics and compute functionality to develop modern, cross-platform, high-performance graphical games
2020-06-24 17:04:30 -04:00
and applications, and to run them across many platforms, including *macOS* , *iOS* , and *tvOS* .
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.
2020-06-23 23:06:08 -04:00
To provide *Vulkan* capability to the*macOS*, *iOS* , and *tvOS* 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
----------------------------------------------------
2020-09-01 14:39:46 -04:00
Installation of **MoltenVK** in your application is straightforward and easy!
2018-03-01 19:42:15 -05:00
2020-09-01 14:39:46 -04:00
Depending on your build and deployment needs, you can link **MoltenVK** to your application either
as a universal `XCFramework` or as a *dynamic library* (`.dylib` ). Distributing an app containing
a dynamic library via the *iOS App Store* or *tvOS App Store* can require specialized bundling.
If you are unsure about which linking and deployment option you need, or on *iOS* or *tvOS* ,
unless you have specific needs for dynamic libraries, follow the steps for linking **MoltenVK**
as an `XCFramework` , as it is the simpler option.
2018-03-01 19:42:15 -05:00
2020-09-01 14:39:46 -04:00
The demo apps, found in the `Demos.xcworkspace` , located in the `Demos` folder, demonstrate both
of the installation techniques discussed above:
2018-03-01 19:42:15 -05:00
2020-09-01 14:39:46 -04:00
- `XCFramework` : `Cube` and `API-Samples` demos.
- Dynamic library: `Hologram` demo.
2019-02-13 14:34:55 -05:00
2018-03-01 19:42:15 -05:00
2020-09-01 14:39:46 -04:00
< a name = "install_xcfwk" > < / a >
### Install *MoltenVK* as a Universal `XCFramework`
To link **MoltenVK** to your application as an `XCFramework` , follow these steps:
1. Open your application in *Xcode* and select your application's target in the
*Project Navigator* panel.
2. Open the *Build Settings* tab.
1. In the **Header Search Paths** (aka `HEADER_SEARCH_PATHS` ) setting,
add an entry that points to the `MoltenVK/include` folder.
2. If using `IOSurfaces` on *iOS* , open the **iOS Deployment Target** (aka `IPHONEOS_DEPLOYMENT_TARGET` )
setting, and ensure it is set to a value of `iOS 11.0` or greater, or if using `IOSurfaces` on *tvOS* ,
open the **tvOS Deployment Target** (aka `TVOS_DEPLOYMENT_TARGET` ) setting, and ensure it is set to a
value of `tvOS 11.0` or greater.
3. Open the *Build Phases* tab and open the *Link Binary With Libraries* list.
1. Drag `MoltenVK/MoltenVK.xcframework` to the *Link Binary With Libraries* list.
2. If your application does **_not_** use use `C++` , click the ** +** button,
and add `libc++.tbd` by selecting it from the list of system frameworks.
This is needed because **MoltenVK** uses `C++` system libraries internally.
3. 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 add the following items by selecting them from the list of system frameworks:
- `libc++.tbd` *(if not already done in Step 2)*
- `Metal.framework`
- `Foundation.framework` .
- `QuartzCore.framework`
- `IOKit.framework` (*macOS*)
- `UIKit.framework` (*iOS* or *tvOS* )
- `IOSurface.framework` (*macOS*, or *iOS* if `IPHONEOS_DEPLOYMENT_TARGET` is at least `iOS 11.0` ,
or *tvOS* if `TVOS_DEPLOYMENT_TARGET` is at least `tvOS 11.0` )
2017-11-17 11:14:29 -05:00
2019-02-13 14:34:55 -05:00
2017-11-17 11:14:29 -05:00
2020-09-01 14:39:46 -04:00
< a name = "install_dylib" > < / a >
### Install *MoltenVK* as a Dynamic Library
2017-11-17 11:14:29 -05:00
2020-09-01 14:39:46 -04:00
To link **MoltenVK** to your application as a dynamic library (`.dylib` ), follow these steps:
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.
2020-09-01 14:39:46 -04:00
1. In the **Header Search Paths** (aka `HEADER_SEARCH_PATHS` ) setting,
add an entry that points to the `MoltenVK/include` folder.
2. In the **Library Search Paths** (aka `LIBRARY_SEARCH_PATHS` ) setting,
add an entry that points to **_one_** of the following folders:
- `MoltenVK/dylib/macOS` *(macOS)*
- `MoltenVK/dylib/iOS` *(iOS)*
- `MoltenVK/dylib/tvOS` *(tvOS)*
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,
you would typically set this to **_one_** of these values:
- `@executable_path/../Frameworks` *(macOS)*
- `@executable_path/Frameworks` *(iOS or tvOS)*
The `libMoltenVK.dylib` library is internally configured to be located at
`@rpath/libMoltenVK.dylib` .
3. If using `IOSurfaces` on *iOS* , open the **iOS Deployment Target** (aka `IPHONEOS_DEPLOYMENT_TARGET` )
setting, and ensure it is set to a value of `iOS 11.0` or greater, or if using `IOSurfaces` on *tvOS* ,
open the **tvOS Deployment Target** (aka `TVOS_DEPLOYMENT_TARGET` ) setting, and ensure it is set to a
value of `tvOS 11.0` or greater.
3. Open the *Build Phases* tab and open the *Link Binary With Libraries* list.
2018-10-30 23:16:12 -04:00
2020-09-01 14:39:46 -04:00
1. Drag **_one_** of the following files to the *Link Binary With Libraries* list:
- `MoltenVK/dylib/macOS/libMoltenVK.dylib` *(macOS)*
- `MoltenVK/dylib/iOS/libMoltenVK.dylib` *(iOS)*
- `MoltenVK/dylib/tvOS/libMoltenVK.dylib` *(tvOS)*
2. If your application does **_not_** use use `C++` , click the ** +** button,
and add `libc++.tbd` by selecting it from the list of system frameworks.
This is needed because **MoltenVK** uses `C++` system libraries internally.
3. 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 add the following items by selecting them from the list of system frameworks:
- `libc++.tbd` *(if not already done in Step 2)*
- `Metal.framework`
- `Foundation.framework` .
- `QuartzCore.framework`
- `IOKit.framework` (*macOS*)
- `UIKit.framework` (*iOS* or *tvOS* )
- `IOSurface.framework` (*macOS*, or *iOS* if `IPHONEOS_DEPLOYMENT_TARGET` is at least `iOS 11.0` ,
or *tvOS* if `TVOS_DEPLOYMENT_TARGET` is at least `tvOS 11.0` )
4. 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
2020-09-01 14:39:46 -04:00
1. On the *Build Phases* tab, add a new *Copy Files* build phase.
2. Set the *Destination* into which you want to place the `libMoltenVK.dylib` file.
Typically this will be *Frameworks* (and it should match the **Runpath Search Paths**
(aka `LD_RUNPATH_SEARCH_PATHS` ) build setting you added above).
3. Drag **_one_** of the following files to the *Copy Files* list in this new build phase:
- `MoltenVK/dylib/macOS/libMoltenVK.dylib` *(macOS)*
- `MoltenVK/dylib/iOS/libMoltenVK.dylib` *(iOS)*
- `MoltenVK/dylib/tvOS/libMoltenVK.dylib` *(tvOS)*
2017-11-17 11:14:29 -05:00
2020-09-01 14:39:46 -04:00
- Alternately, you may create your own installation mechanism to install one of the following
files into a standard *macOS* , *iOS* , or *tvOS* system library folder on the user's device:
- `MoltenVK/dylib/macOS/libMoltenVK.dylib` *(macOS)*
- `MoltenVK/dylib/iOS/libMoltenVK.dylib` *(iOS)*
- `MoltenVK/dylib/tvOS/libMoltenVK.dylib` *(tvOS)*
< a name = "requirements" > < / a >
### Build and Runtime Requirements
**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* .
>***Note:*** To support `IOSurfaces` on *iOS* or *tvOS* , 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, or a minimum **tvOS Deployment Target** (aka `TVOS_DEPLOYMENT_TARGET ` )
build setting of `tvOS 11.0` or greater.
Once built, your app integrating the **MoltenVK** libraries can be run on *macOS* , *iOS* or *tvOS*
devices that support *Metal* , or on the *Xcode* *iOS Simulator* or *tvOS Simulator* .
- At runtime, **MoltenVK** requires at least *macOS 10.11* , *iOS 9* , or *tvOS 9*
(or *iOS 11* or *tvOS 11* if using `IOSurfaces` ).
- 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 ).
- Information on *iOS* devices that are compatible with *Metal* can be found in
[this article ](https://developer.apple.com/library/content/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/HardwareGPUInformation/HardwareGPUInformation.html ).
2017-11-17 11:14:29 -05:00
2020-09-01 14:39:46 -04:00
When a *Metal* app is running from *Xcode* , the default ** *Scheme*** settings may reduce 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.
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`
2020-09-08 14:31:17 -05:00
- `VK_KHR_create_renderpass2`
2018-12-04 15:55:18 -06:00
- `VK_KHR_dedicated_allocation`
2020-09-09 20:03:38 -05:00
- `VK_KHR_depth_stencil_resolve`
2018-12-04 15:55:18 -06:00
- `VK_KHR_descriptor_update_template`
2019-07-23 23:52:34 -05:00
- `VK_KHR_device_group`
- `VK_KHR_device_group_creation`
2020-07-20 14:51:40 -04:00
- `VK_KHR_driver_properties`
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`
Support the VK_KHR_multiview extension.
Originally, Metal did not support this directly, and still largely
doesn't on GPUs other than Apple family 6. Therefore, this
implementation uses vertex instancing to draw the needed views. To
support the Vulkan requirement that only the layers for the enabled
views are loaded and stored in a multiview render pass, this
implementation uses multiple Metal render passes for multiple "clumps"
of enabled views.
For indirect draws, as with tessellation, we must adjust the draw
parameters at execution time to account for the extra views, so we need
to use deferred store actions here. Without them, tracking the state
becomes too involved.
If the implementation doesn't support either layered rendering or
deferred store actions, multiview render passes are instead unrolled and
rendered one view at a time. This will enable us to support the
extension even on older devices and OSes, but at the cost of additional
command buffer memory and (possibly) worse performance.
Eventually, we should consider using vertex amplification to accelerate
this, particularly since indirect multiview draws are terrible and
currently require a compute pass to adjust the instance count. Also,
instanced drawing in itself is terrible due to its subpar performance.
But, since vertex amplification on family 6 only supports two views,
when `VK_KHR_multiview` mandates a minimum of 6, we'll still need to use
instancing to support more than two views.
I have tested this extensively against the CTS. I'm very confident in
its correctness. The only failing tests are
`dEQP-VK.multiview.queries.*`, due to our inadequate implementation of
timestamp queries; and `dEQP-VK.multiview.depth.*`, due to what I assume
is a bug in the way Metal handles arrayed packed depth/stencil textures,
and which may only be a problem on Mojave. I need to test this on
Catalina and Big Sur.
Update SPIRV-Cross to pull in some fixes necessary for this to work.
Fixes #347.
2020-08-16 11:10:20 -05:00
- `VK_KHR_multiview`
2020-09-21 11:33:29 -04:00
- `VK_KHR_portability_subset`
2018-12-04 15:55:18 -06:00
- `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`
2020-10-27 11:32:06 -04:00
- `VK_EXT_descriptor_indexing`
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`
2020-07-24 13:43:31 -05:00
- `VK_EXT_image_robustness`
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-10-10 17:15:07 -04:00
- `VK_EXT_private_data `
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`
Support the VK_KHR_multiview extension.
Originally, Metal did not support this directly, and still largely
doesn't on GPUs other than Apple family 6. Therefore, this
implementation uses vertex instancing to draw the needed views. To
support the Vulkan requirement that only the layers for the enabled
views are loaded and stored in a multiview render pass, this
implementation uses multiple Metal render passes for multiple "clumps"
of enabled views.
For indirect draws, as with tessellation, we must adjust the draw
parameters at execution time to account for the extra views, so we need
to use deferred store actions here. Without them, tracking the state
becomes too involved.
If the implementation doesn't support either layered rendering or
deferred store actions, multiview render passes are instead unrolled and
rendered one view at a time. This will enable us to support the
extension even on older devices and OSes, but at the cost of additional
command buffer memory and (possibly) worse performance.
Eventually, we should consider using vertex amplification to accelerate
this, particularly since indirect multiview draws are terrible and
currently require a compute pass to adjust the instance count. Also,
instanced drawing in itself is terrible due to its subpar performance.
But, since vertex amplification on family 6 only supports two views,
when `VK_KHR_multiview` mandates a minimum of 6, we'll still need to use
instancing to support more than two views.
I have tested this extensively against the CTS. I'm very confident in
its correctness. The only failing tests are
`dEQP-VK.multiview.queries.*`, due to our inadequate implementation of
timestamp queries; and `dEQP-VK.multiview.depth.*`, due to what I assume
is a bug in the way Metal handles arrayed packed depth/stencil textures,
and which may only be a problem on Mojave. I need to test this on
Catalina and Big Sur.
Update SPIRV-Cross to pull in some fixes necessary for this to work.
Fixes #347.
2020-08-16 11:10:20 -05:00
- `VK_EXT_swapchain_colorspace`
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-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`
2020-06-23 23:06:08 -04:00
- `VK_AMD_shader_image_load_store_lod` *(iOS and tvOS)*
2019-07-17 10:57:08 -05:00
- `VK_AMD_shader_trinary_minmax` *(requires Metal 2.1)*
2020-10-28 17:04:24 -05:00
- `VK_IMG_format_pvrtc` *(requires Apple GPU)*
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
2020-06-23 23:06:08 -04:00
In order to visibly display your content on *macOS* , *iOS* , or *tvOS* , 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
2020-06-23 23:06:08 -04:00
enabled for *macOS* , *iOS* , or *tvOS* . Use this header file in place of the `vulkan.h`
header file, where access to a **MoltenVK** platform surface extension is required.
2017-11-17 11:14:29 -05:00
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-10-14 10:47:02 -04:00
- On *macOS* versions prior to *macOS 10.15.6* , native host-coherent image device memory is not available.
Because of this, changes made to `VkImage VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` device memory by the CPU
or GPU will not be available to the GPU or CPU, respectively, until the memory is flushed or unmapped by
the application. Applications using `vkMapMemory()` with `VkImage VK_MEMORY_PROPERTY_HOST_COHERENT_BIT`
device memory on *macOS* versions prior to *macOS 10.15.6* must call either `vkUnmapMemory()` , or
`vkFlushMappedMemoryRanges()` / `vkInvalidateMappedMemoryRanges()` to ensure memory changes are coherent
between the CPU and GPU. This limitation does **_not_** apply to `VKImage` device memory on *macOS*
starting with *macOS 10.15.6* , does not apply to `VKImage` device memory on any version of *iOS* or *tvOS* ,
and does **_not_** apply to `VKBuffer` device memory on any platform.
2017-11-17 11:14:29 -05:00
2020-10-14 10:47:02 -04:00
- 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.
2019-03-26 13:31:26 -04:00
- Pipeline statistics query pool using `VK_QUERY_TYPE_PIPELINE_STATISTICS` is not supported.
2020-10-14 10:47:02 -04:00
- Application-controlled memory allocations using `VkAllocationCallbacks` are ignored.
- 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 ).