diff --git a/Demos/README.md b/Demos/README.md index 29fddb10..1e607ab4 100644 --- a/Demos/README.md +++ b/Demos/README.md @@ -24,19 +24,19 @@ Table of Contents *Cube* ------ -The basic canonical *Cube* sample app from the -[*Vulkan-Tools* repository](https://github.com/KhronosGroup/Vulkan-Tools) +The basic canonical *Cube* sample app from the +[*Vulkan-Tools* repository](https://github.com/KhronosGroup/Vulkan-Tools) is included in this **MoltenVK** package. This demo renders a basic textured cube that spins in place. -The demo can be found in the `Cube` folder, and in the `Cube` group in the +The demo can be found in the `Cube` folder, and in the `Cube` group in the *Xcode Project Navigator* in the `Demos.xcworkspace` *Xcode* workspace. -To run this demo, run the `Cube-iOS`, `Cube-tvOS`, or `Cube-macOS` *Scheme* from within *Xcode*. +To run this demo, run the `Cube-iOS`, `Cube-tvOS`, or `Cube-macOS` *Scheme* from within *Xcode*. In addition to devices, this demo will also run on the `iOS Simulator` or `tvOS Simulator` destinations. -The `Cube` demo is a simple example of installing **MoltenVK** as an `XCFramework` that is +The `Cube` demo is a simple example of installing **MoltenVK** as an `XCFramework` that is statically linked to the application. It supports all platforms, including _Mac Catalyst_, _iOS Simulator_ and _tvOS Simulator_, and all architectures including _Apple Silicon_. @@ -46,5 +46,5 @@ Simulator_ and _tvOS Simulator_, and all architectures including _Apple Silicon_ *Khronos Vulkan Samples* ---------------------- -*Khronos Group* provides a [repository](https://github.com/KhronosGroup/Vulkan-Samples) +*Khronos Group* provides a [repository](https://github.com/KhronosGroup/Vulkan-Samples) containing a full suite of standard *Vulkan* samples that run on **MoltenVK** on *macOS*. diff --git a/Docs/MoltenVK_Configuration_Parameters.md b/Docs/MoltenVK_Configuration_Parameters.md index f5527d31..423bd488 100644 --- a/Docs/MoltenVK_Configuration_Parameters.md +++ b/Docs/MoltenVK_Configuration_Parameters.md @@ -1,4 +1,4 @@ - @@ -14,28 +14,37 @@ Copyright (c) 2015-2023 [The Brenwill Workshop Ltd.](http://www.brenwill.com) -**MoltenVK** provides the ability to configure and optimize **MoltenVK** for your particular -application runtime requirements and development-time needs. +**MoltenVK** provides the ability to configure and optimize **MoltenVK** for your particular +application runtime requirements and development-time needs. -At runtime, configuration can be helpful in situtations where _Metal_ behavior is different -than _Vulkan_ behavior, and the results or performance you receive can depend on how **MoltenVK** -works around those differences, which, in turn, may depend on how you are using _Vulkan_. +At runtime, configuration can be helpful in situtations where _Metal_ behavior is different +than _Vulkan_ behavior, and the results or performance you receive can depend on how **MoltenVK** +works around those differences, which, in turn, may depend on how you are using _Vulkan_. Different apps might benefit differently in this handling. Additional configuration parameters can be helpful at development time by providing you with additional tracing, debugging, and performance measuring capabilities. -Each configuration parameter has a *name* and *value*, and can be passed to **MoltenVK** +Each configuration parameter has a *name* and *value*, and can be passed to **MoltenVK** via any of the following mechanisms: - The standard _Vulkan_ `VK_EXT_layer_settings` extension. - Application runtime environment variables. - Build settings at **MoltenVK** build time. -Parameter values configured by build settings at **MoltenVK** build time can be overridden -by values set by environment variables, which, in turn, can be overridden during `VkInstance` +Parameter values configured by build settings at **MoltenVK** build time can be overridden +by values set by environment variables, which, in turn, can be overridden during `VkInstance` creation via the _Vulkan_ `VK_EXT_layer_settings` extension. +Using the `VK_EXT_layer_settings` extension is the preferred mechanism, as it is a standard +_Vulkan_ extension, and is supported by the _Vulkan_ loader and layers. When using the +`VK_EXT_layer_settings` extension, set `VkLayerSettingEXT::pLayerName` to the value of +`kMVKMoltenVKDriverLayerName` found in the `mvk_vulkan.h` header (or simply to `"MoltenVK"`). + +Using environment variables can be a convinient mechanism to modify configuration parameters +during runtime debugging in the field (if the settings are *not* overridden during `VkInstance` +creation via the _Vulkan_ `VK_EXT_layer_settings` extension). + --------------------------------------- #### MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE @@ -49,7 +58,7 @@ creation via the _Vulkan_ `VK_EXT_layer_settings` extension. ##### Default: `0` -If the `MVK_CONFIG_PERFORMANCE_TRACKING` parameter is enabled, this parameter controls +If the `MVK_CONFIG_PERFORMANCE_TRACKING` parameter is enabled, this parameter controls when **MoltenVK** should log activity performance events. @@ -59,8 +68,8 @@ when **MoltenVK** should log activity performance events. ##### Type: UInt32 ##### Default: `1` -Controls which extensions **MoltenVK** should advertise it supports in `vkEnumerateInstanceExtensionProperties()` -and `vkEnumerateDeviceExtensionProperties()`. This can be useful when testing **MoltenVK** against specific +Controls which extensions **MoltenVK** should advertise it supports in `vkEnumerateInstanceExtensionProperties()` +and `vkEnumerateDeviceExtensionProperties()`. This can be useful when testing **MoltenVK** against specific limited functionality. The value of this parameter is a `Bitwise-OR` of the following values: - `1`: All supported extensions. @@ -68,7 +77,7 @@ limited functionality. The value of this parameter is a `Bitwise-OR` of the foll - `4`: _Vulkan_ Portability Subset extensions. -Any prerequisite extensions are also advertised. If bit `1` is included, all supported +Any prerequisite extensions are also advertised. If bit `1` is included, all supported extensions will be advertised. A value of zero means no extensions will be advertised. @@ -78,7 +87,7 @@ extensions will be advertised. A value of zero means no extensions will be adver ##### Type: UInt32 ##### Default: `4202496` -Controls the _Vulkan_ API version that **MoltenVK** should advertise in `vkEnumerateInstanceVersion()`, +Controls the _Vulkan_ API version that **MoltenVK** should advertise in `vkEnumerateInstanceVersion()`, after **MoltenVK** adds the `VK_HEADER_VERSION` component. Set this value to one of: @@ -96,13 +105,13 @@ Set this value to one of: _(The default value is an empty string)._ -If `MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE` is any value other than `0`, this is the path to a -file where the automatic GPU capture will be saved. If this parameter is an empty string +If `MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE` is any value other than `0`, this is the path to a +file where the automatic GPU capture will be saved. If this parameter is an empty string (the default), automatic GPU capture will be handled by the _Xcode_ user interface. -If this parameter is set to a valid file path, the _Xcode_ scheme need not have _Metal_ GPU capture -enabled, and in fact the app need not be run under _Xcode_'s control at all. This is useful in case -the app cannot be run under _Xcode_'s control. A path starting with '~' can be used to place it in +If this parameter is set to a valid file path, the _Xcode_ scheme need not have _Metal_ GPU capture +enabled, and in fact the app need not be run under _Xcode_'s control at all. This is useful in case +the app cannot be run under _Xcode_'s control. A path starting with '~' can be used to place it in a user's home directory. This feature requires _Metal 2.2 (macOS 10.15+, iOS/tvOS 13+)_. @@ -113,8 +122,8 @@ a user's home directory. This feature requires _Metal 2.2 (macOS 10.15+, iOS/tvO - `0`: No automatic GPU capture. - `1`: Automatically capture all GPU activity during the lifetime of a `VkDevice`. - `2`: Automatically capture all GPU activity during the rendering and presentation of the first frame. - The queue for which the frame is captured is identifed by the values of the - `MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX` and + The queue for which the frame is captured is identifed by the values of the + `MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX` and `MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_INDEX` configuration parameters. ##### Default: `0` @@ -144,7 +153,7 @@ If enabled, debugging capabilities will be enabled, including logging shader cod ##### Type: UInt32 ##### Default: `0` -The index of the queue family whose presentation submissions will be +The index of the queue family whose presentation submissions will be used as the default GPU Capture Scope, when GPU Capture is active. @@ -155,7 +164,7 @@ used as the default GPU Capture Scope, when GPU Capture is active. ##### Default: `0` The index of the queue, within the queue family identified by the -`MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX` parameter, whose presentation +`MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX` parameter, whose presentation submissions will be used as the default GPU Capture Scope, when GPU Capture is active. @@ -175,22 +184,22 @@ This can be enabled for publicity during demos. ##### Type: Enumeration - `0`: _Metal_ shaders will never be compiled with the fast math option. - `1`: _Metal_ shaders will always be compiled with the fast math option. -- `2`: _Metal_ shaders will be compiled with the fast math option, unless the shader includes execution +- `2`: _Metal_ shaders will be compiled with the fast math option, unless the shader includes execution capabilities, such as `SignedZeroInfNanPreserve`, that require it to be compiled without fast math. ##### Default: `1` -Identifies when _Metal_ shaders will be compiled with the _Metal_ fast math option enabled. +Identifies when _Metal_ shaders will be compiled with the _Metal_ fast math option enabled. -Shaders compiled with the _Metal_ fast math option enabled perform floating point math significantly +Shaders compiled with the _Metal_ fast math option enabled perform floating point math significantly faster, but may optimize floating point operations in ways that violate the IEEE 754 standard. -Enabling _Metal_ fast math can dramatically improve shader performance, and has little practical -effect on the numerical accuracy of most shaders. As such, disabling fast math should be done +Enabling _Metal_ fast math can dramatically improve shader performance, and has little practical +effect on the numerical accuracy of most shaders. As such, disabling fast math should be done carefully and deliberately. For most applications, always enabling fast math is the preferred choice. -Apps that have specific accuracy and handling needs for particular shaders, may elect to set -the value of this property to `2`, so that fast math will be disabled when compiling shaders +Apps that have specific accuracy and handling needs for particular shaders, may elect to set +the value of this property to `2`, so that fast math will be disabled when compiling shaders that request specific math accuracy and precision capabilities, such as `SignedZeroInfNanPreserve`. @@ -218,7 +227,7 @@ _Metal_ shader code during all texture sampling and reading operations. This occ of whether a swizzle is required for the `VkImageView` associated with the _Metal_ texture, which may result in reduced performance. -If disabled, and native _Metal_ per-texture swizzling is not available on the platform, the +If disabled, and native _Metal_ per-texture swizzling is not available on the platform, the following very limited set of `VkImageView` component swizzles is supported via format substitutions: ``` @@ -237,9 +246,9 @@ VK_FORMAT_D24_UNORM_S8_UINT RED, ANY, ANY, ANY (stencil only) If native per-texture swizzling is not available, and this feature is not enabled, an error is logged and returned in the following situations: -- `VkImageView` creation if that `VkImageView` requires full image view swizzling. +- `VkImageView` creation if that `VkImageView` requires full image view swizzling. - A pipeline that was not compiled with full image view swizzling uses a `VkImageView` that is expecting a swizzle. -- `VkPhysicalDeviceImageFormatInfo2KHR` is passed in a call to `vkGetPhysicalDeviceImageFormatProperties2KHR()` +- `VkPhysicalDeviceImageFormatInfo2KHR` is passed in a call to `vkGetPhysicalDeviceImageFormatProperties2KHR()` to query for an `VkImageView` format that will require full swizzling. @@ -265,9 +274,9 @@ Controls the level of logging performed by **MoltenVK**. ##### Default: `64` The maximum number of _Metal_ command buffers that can be concurrently active per _Vulkan_ queue. The number -of active _Metal_ command buffers required depends on the `MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS` parameter. -If `MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS` is set to anything other than `0`, one _Metal_ command buffer -is required per _Vulkan_ command buffer, otherwise one _Metal_ command buffer is required per command buffer +of active _Metal_ command buffers required depends on the `MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS` parameter. +If `MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS` is set to anything other than `0`, one _Metal_ command buffer +is required per _Vulkan_ command buffer, otherwise one _Metal_ command buffer is required per command buffer queue submission, which will typically be significantly less than the number of _Vulkan_ command buffers. @@ -304,7 +313,7 @@ no frame-based performance statistics will be logged. If enabled, performance statistics, as defined by the `MVKPerformanceStatistics` structure, are collected, and can be retrieved via the private-API `vkGetPerformanceStatisticsMVK()` function. -You can also use the `MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE` and +You can also use the `MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE` and `MVK_CONFIG_PERFORMANCE_LOGGING_FRAME_COUNT` parameters to configure when to log the performance statistics collected by this parameter. @@ -325,47 +334,47 @@ dynamically allocated in application memory when the descriptor set itself is al #### MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS ##### Type: Enumeration -- `0`: During _Vulkan_ command buffer filling, do not prefill a _Metal_ command buffer for each _Vulkan_ - command buffer. A single _Metal_ command buffer will be created and encoded for all the _Vulkan_ command - buffers included when `vkQueueSubmit()` is called. **MoltenVK** automatically creates and drains - a single _Metal_ object autorelease pool when `vkQueueSubmit()` is called. This is the fastest option, +- `0`: During _Vulkan_ command buffer filling, do not prefill a _Metal_ command buffer for each _Vulkan_ + command buffer. A single _Metal_ command buffer will be created and encoded for all the _Vulkan_ command + buffers included when `vkQueueSubmit()` is called. **MoltenVK** automatically creates and drains + a single _Metal_ object autorelease pool when `vkQueueSubmit()` is called. This is the fastest option, but potentially has the largest memory footprint. -- `1`: During _Vulkan_ command buffer filling, encode to the _Metal_ command buffer when `vkEndCommandBuffer()` - is called. **MoltenVK** automatically creates and drains a single _Metal_ object autorelease pool when - `vkEndCommandBuffer()` is called. This option has the fastest performance, and the largest memory footprint, +- `1`: During _Vulkan_ command buffer filling, encode to the _Metal_ command buffer when `vkEndCommandBuffer()` + is called. **MoltenVK** automatically creates and drains a single _Metal_ object autorelease pool when + `vkEndCommandBuffer()` is called. This option has the fastest performance, and the largest memory footprint, of the prefilling options using autorelease pools. -- `2`: During _Vulkan_ command buffer filling, as each +- `2`: During _Vulkan_ command buffer filling, as each command is submitted to the _Vulkan_ command buffer, immediately encode it to the _Metal_ command buffer, and do not retain any command content in the _Vulkan_ command buffer. **MoltenVK** automatically creates and drains a _Metal_ object autorelease pool for each and every command added to the _Vulkan_ command buffer. - This option has the smallest memory footprint, + This option has the smallest memory footprint, and the slowest performance, of the prefilling options using autorelease pools. -- `3`: During _Vulkan_ command buffer filling, as each +- `3`: During _Vulkan_ command buffer filling, as each command is submitted to the _Vulkan_ command buffer, immediately encode it to the _Metal_ command buffer, do not retain any command content in the _Vulkan_ command buffer, and assume the app will ensure that each thread that fills commands into a _Vulkan_ command buffer has a _Metal_ autorelease pool. **MoltenVK** will - not create and drain any autorelease pools during encoding. This is the fastest prefilling option, and + not create and drain any autorelease pools during encoding. This is the fastest prefilling option, and generally has a small memory footprint, depending on when the app-provided autorelease pool drains. ##### Default: `0` For any value other than `0`, be aware of the following: -- One _Metal_ command buffer is required for each _Vulkan_ command buffer. Depending on the - number of command buffers that you use, you may also need to change the value of the +- One _Metal_ command buffer is required for each _Vulkan_ command buffer. Depending on the + number of command buffers that you use, you may also need to change the value of the `MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE` parameter. -- Prefilling of a _Metal_ command buffer will not occur during the filling of secondary command buffers - (`VK_COMMAND_BUFFER_LEVEL_SECONDARY`), or for primary command buffers that are intended to be submitted +- Prefilling of a _Metal_ command buffer will not occur during the filling of secondary command buffers + (`VK_COMMAND_BUFFER_LEVEL_SECONDARY`), or for primary command buffers that are intended to be submitted to multiple queues concurrently (`VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT`). -- For primary command buffers that are intended to be reused (`VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT` - is not set), prefilling will only apply to the first submission. Later submissions of the same command buffer +- For primary command buffers that are intended to be reused (`VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT` + is not set), prefilling will only apply to the first submission. Later submissions of the same command buffer will behave as if this configuration parameter is set to `0`. - If you have recorded commands to a _Vulkan_ command buffer, and then choose to reset that command buffer instead of submitting it, the corresponding prefilled _Metal_ command buffer will still be submitted. This is because _Metal_ command buffers do not support the concept of being reset after being filled. Depending on when and how often you do this, it may cause unexpected visual artifacts and unnecessary GPU load. -- This configuration is incompatible with updating descriptors after binding. If any of the _UpdateAfterBind_ - feature flags of `VkPhysicalDeviceDescriptorIndexingFeatures` or `VkPhysicalDeviceInlineUniformBlockFeatures` +- This configuration is incompatible with updating descriptors after binding. If any of the _UpdateAfterBind_ + feature flags of `VkPhysicalDeviceDescriptorIndexingFeatures` or `VkPhysicalDeviceInlineUniformBlockFeatures` have been enabled, the value of this parameter will be ignored and treated as if it is `0`. @@ -375,11 +384,11 @@ For any value other than `0`, be aware of the following: ##### Type: Boolean ##### Default: `0` -Controls whether **MoltenVK** should treat a lost `VkDevice` as resumable, unless the corresponding -`VkPhysicalDevice` has also been lost. The `VK_ERROR_DEVICE_LOST` error has a broad definitional range, -and can mean anything from a GPU hiccup on the current command buffer submission, to a physically removed -GPU. In the case where this error does not impact the `VkPhysicalDevice`, _Vulkan_ requires that the app -destroy and re-create a new `VkDevice`. However, not all apps (including CTS) respect that requirement, +Controls whether **MoltenVK** should treat a lost `VkDevice` as resumable, unless the corresponding +`VkPhysicalDevice` has also been lost. The `VK_ERROR_DEVICE_LOST` error has a broad definitional range, +and can mean anything from a GPU hiccup on the current command buffer submission, to a physically removed +GPU. In the case where this error does not impact the `VkPhysicalDevice`, _Vulkan_ requires that the app +destroy and re-create a new `VkDevice`. However, not all apps (including CTS) respect that requirement, leading to what might be a transient command submission failure causing an unexpected catastrophic app failure. If this parameter is enabled, in the case of a `VK_ERROR_DEVICE_LOST` error that does NOT impact @@ -402,10 +411,10 @@ mark the `VkDevice` as lost, and subsequent use of that `VkDevice` will be reduc Pipeline cache compression is available for _macOS 10.15+_, and _iOS/tvOS 13.0+_. -Controls the type of compression to use on the MSL source code that is stored in memory for use in a pipeline cache. -After being converted from SPIR-V, or loaded directly into a `VkShaderModule`, and then compiled into a `MTLLibrary`, -the MSL source code is no longer needed for operation, but it is retained so it can be written out as part of a -pipeline cache export. When a large number of shaders are loaded, this can consume significant memory. In such a case, +Controls the type of compression to use on the MSL source code that is stored in memory for use in a pipeline cache. +After being converted from SPIR-V, or loaded directly into a `VkShaderModule`, and then compiled into a `MTLLibrary`, +the MSL source code is no longer needed for operation, but it is retained so it can be written out as part of a +pipeline cache export. When a large number of shaders are loaded, this can consume significant memory. In such a case, this parameter can be used to compress the MSL source code that is awaiting export as part of a pipeline cache. @@ -439,11 +448,11 @@ To have effect, this parameter requires _macOS 13.3+_, and has no effect on _iOS ##### Type: Boolean ##### Default: `0` -_Metal_ does not distinguish functionality between queues, which would normally mean only a single -general-purpose queue family with multiple queues is needed. However, _Vulkan_ associates command -buffers with a queue family, whereas _Metal_ associates command buffers with a specific _Metal_ queue. -In order to allow a _Metal_ command buffer to be prefilled before it is formally submitted to a _Vulkan_ queue, -each _Vulkan_ queue family can support only a single _Metal_ queue. As a result, in order to provide parallel +_Metal_ does not distinguish functionality between queues, which would normally mean only a single +general-purpose queue family with multiple queues is needed. However, _Vulkan_ associates command +buffers with a queue family, whereas _Metal_ associates command buffers with a specific _Metal_ queue. +In order to allow a _Metal_ command buffer to be prefilled before it is formally submitted to a _Vulkan_ queue, +each _Vulkan_ queue family can support only a single _Metal_ queue. As a result, in order to provide parallel queue operations, **MoltenVK** provides multiple queue families, each with a single queue. If this parameter is disabled, all queue families will be advertised as having general-purpose @@ -522,8 +531,8 @@ system, and as a result, may want to disable this parameter. _(The default value is `0` for OS versions prior to macOS 10.14+/iOS 12+)._ If enabled, queue command submissions `vkQueueSubmit()` and `vkQueuePresentKHR()` -will be processed on the thread that called the submission function. If disabled, -processing will be dispatched to a GCD `dispatch_queue` whose priority is determined +will be processed on the thread that called the submission function. If disabled, +processing will be dispatched to a GCD `dispatch_queue` whose priority is determined by `VkDeviceQueueCreateInfo::pQueuePriorities` during `vkCreateDevice()`. @@ -547,18 +556,18 @@ Using a _Metal_ 2D texture allows _Vulkan_ 1D textures to support this additiona This parameter is ignored on Apple Silicon (Apple GPU) devices. -Non-Apple GPUs can have a dynamic timestamp period, which varies over time according to GPU -workload. Depending on how often the app samples the `VkPhysicalDeviceLimits::timestampPeriod` -value using `vkGetPhysicalDeviceProperties()`, the app may want up-to-date, but potentially +Non-Apple GPUs can have a dynamic timestamp period, which varies over time according to GPU +workload. Depending on how often the app samples the `VkPhysicalDeviceLimits::timestampPeriod` +value using `vkGetPhysicalDeviceProperties()`, the app may want up-to-date, but potentially volatile values, or it may find average values more useful. -The value of this parameter sets the alpha `(A)` value of a simple lowpass filter on the +The value of this parameter sets the alpha `(A)` value of a simple lowpass filter on the `timestampPeriod` value, of the form: TPout = (1 - A)TPout + (A * TPin) -The alpha value can be set to a float between `0.0` and `1.0`. Values of alpha closer to `0.0` -cause the value of `timestampPeriod` to vary slowly over time and be less volatile, and values +The alpha value can be set to a float between `0.0` and `1.0`. Values of alpha closer to `0.0` +cause the value of `timestampPeriod` to vary slowly over time and be less volatile, and values of alpha closer to `1.0` cause the value of `timestampPeriod` to vary quickly and be more volatile. Apps that query the `timestampPeriod` value infrequently will prefer low volatility, whereas @@ -572,9 +581,9 @@ apps that query frequently may prefer higher volatility, to track more recent ch - `0`: No _Vulkan_ call logging. - `1`: Log the name of each _Vulkan_ call when the call is entered. - `2`: Log the name and thread ID of each _Vulkan_ call when the call is entered. -- `3`: Log the name of each _Vulkan_ call when the call is entered and exited. +- `3`: Log the name of each _Vulkan_ call when the call is entered and exited. This effectively brackets any other logging activity within the scope of the _Vulkan_ call. -- `4`: Log the name and thread ID of each _Vulkan_ call when the call is entered, and name when exited. +- `4`: Log the name and thread ID of each _Vulkan_ call when the call is entered, and name when exited. This effectively brackets any other logging activity within the scope of the _Vulkan_ call. - `5`: Same as `3`, plus logs the time spent inside the _Vulkan_ function. - `6`: Same as `4`, plus logs the time spent inside the _Vulkan_ function. @@ -593,7 +602,7 @@ Controls the information **MoltenVK** logs for each _Vulkan_ call made by the ap Controls whether **MoltenVK** should use pools to manage memory used when adding commands to command buffers. If this setting is enabled, **MoltenVK** will use a pool to hold command resources for reuse during command execution. If this setting is disabled, command memory is allocated and destroyed each time a command is executed. -This is a classic time-space trade off. When command pooling is active, the memory in the pool can be +This is a classic time-space trade off. When command pooling is active, the memory in the pool can be cleared via a call to the `vkTrimCommandPoolKHR()` command. @@ -607,9 +616,9 @@ cleared via a call to the `vkTrimCommandPoolKHR()` command. ##### Default: `0` -Controls whether **MoltenVK** should use _Metal_ argument buffers for resources defined in descriptor sets, -if _Metal_ argument buffers are supported on the platform. Using _Metal_ argument buffers dramatically -increases the number of buffers, textures and samplers that can be bound to a pipeline shader, and in most +Controls whether **MoltenVK** should use _Metal_ argument buffers for resources defined in descriptor sets, +if _Metal_ argument buffers are supported on the platform. Using _Metal_ argument buffers dramatically +increases the number of buffers, textures and samplers that can be bound to a pipeline shader, and in most cases improves performance. _**NOTE:**_ Currently, _Metal_ argument buffer support is in beta stage, and is only supported on _macOS 11.0+_, @@ -623,13 +632,13 @@ Development to support _iOS_ and _tvOS_ and a wider combination of GPU's on olde ##### Type: Boolean ##### Default: `0` -Controls whether **MoltenVK** should use `MTLHeaps` for allocating textures and buffers from device memory. -If this setting is enabled, and placement `MTLHeaps` are available on the platform, **MoltenVK** will allocate a -placement `MTLHeap` for each `VkDeviceMemory` instance, and allocate textures and buffers from that placement heap. +Controls whether **MoltenVK** should use `MTLHeaps` for allocating textures and buffers from device memory. +If this setting is enabled, and placement `MTLHeaps` are available on the platform, **MoltenVK** will allocate a +placement `MTLHeap` for each `VkDeviceMemory` instance, and allocate textures and buffers from that placement heap. If this parameter is disabled, **MoltenVK** will allocate textures and buffers from general device memory. -Apple recommends that `MTLHeaps` should only be used for specific requirements such as aliasing or hazard tracking, -and **MoltenVK** testing has shown that allocating multiple textures of different types or usages from one `MTLHeap` +Apple recommends that `MTLHeaps` should only be used for specific requirements such as aliasing or hazard tracking, +and **MoltenVK** testing has shown that allocating multiple textures of different types or usages from one `MTLHeap` can occassionally cause corruption issues under certain circumstances. @@ -637,12 +646,12 @@ can occassionally cause corruption issues under certain circumstances. #### MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE ##### Type: Enumeration -- `0`: Limit _Vulkan_ to a single queue, with no explicit semaphore synchronization, and use _Metal's_ implicit +- `0`: Limit _Vulkan_ to a single queue, with no explicit semaphore synchronization, and use _Metal's_ implicit guarantees that all operations submitted to a queue will give the same result as if they had been run in submission order. -- `1`: Use _Metal_ events (`MTLEvent`) when available on the platform, and where safe. This will revert to the same as `0` on some - _NVIDIA_ GPUs and _Rosetta2_, due to potential challenges with `MTLEvents` on those platforms, or in older environments where +- `1`: Use _Metal_ events (`MTLEvent`) when available on the platform, and where safe. This will revert to the same as `0` on some + _NVIDIA_ GPUs and _Rosetta2_, due to potential challenges with `MTLEvents` on those platforms, or in older environments where `MTLEvents` are not supported. -- `2`: Always use _Metal_ events (`MTLEvent`) when available on the platform. This will revert to the same as `0` in older +- `2`: Always use _Metal_ events (`MTLEvent`) when available on the platform. This will revert to the same as `0` in older environments where `MTLEvents` are not supported. - `3`: Use CPU callbacks upon GPU submission completion. This is the slowest technique, but allows multiple queues, compared to `0`. diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index 6a00edf3..36329b5a 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -46,7 +46,7 @@ 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 *macOS*, *iOS*, or *tvOS*. -To learn how to use the **MoltenVK** open-source repository to build a **MoltenVK** runtime +To learn how to use the **MoltenVK** open-source repository to build a **MoltenVK** runtime distribution package, see the main [`README.md`](../README.md) document in the `MoltenVK` repository. @@ -55,20 +55,20 @@ distribution package, see the main [`README.md`](../README.md) document in the ` About **MoltenVK** ------------------ -**MoltenVK** is a layered implementation of [*Vulkan 1.2*](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 *macOS*, *iOS*, and *tvOS*. **MoltenVK** allows you to use *Vulkan* -graphics and compute functionality to develop modern, cross-platform, high-performance graphical games +**MoltenVK** is a layered implementation of [*Vulkan 1.2*](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 *macOS*, *iOS*, and *tvOS*. **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 *macOS*, *iOS*, *tvOS*, *Simulators*, and *Mac Catalyst* on *macOS 11.0+*. -*Metal* uses a different shading language, the *Metal Shading Language (MSL)*, than -*Vulkan*, which uses *SPIR-V*. **MoltenVK** automatically converts your *SPIR-V* shaders +*Metal* uses a different shading language, the *Metal Shading Language (MSL)*, than +*Vulkan*, which uses *SPIR-V*. **MoltenVK** automatically converts your *SPIR-V* shaders to their *MSL* equivalents. -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 +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*. @@ -78,56 +78,56 @@ Installing **MoltenVK** in Your *Vulkan* Application Installation of **MoltenVK** in your application is straightforward and easy! -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** +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, and encompasses the largest set of supported platforms. ### Install *MoltenVK* as a Universal `XCFramework` -> ***Note:*** *Xcode 14* introduced a new static linkage model that is not compatible with previous -versions of *Xcode*. If you link to a `MoltenVK.xcframework` that was built with *Xcode 14* or later, -also use *Xcode 14* or later to link it to your app or game. +> ***Note:*** *Xcode 14* introduced a new static linkage model that is not compatible with previous +versions of *Xcode*. If you link to a `MoltenVK.xcframework` that was built with *Xcode 14* or later, +also use *Xcode 14* or later to link it to your app or game. > -> If you need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` to your app or game, -first [build](../README.md#building) **MoltenVK** with *Xcode 13* or earlier. +> If you need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` to your app or game, +first [build](../README.md#building) **MoltenVK** with *Xcode 13* or earlier. > -> Or, if you want to use *Xcode 14* or later to [build](../README.md#building) **MoltenVK**, in order to be able to use the latest -*Metal* capabilities, but need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` to your -app or game, first add the value `-fno-objc-msgsend-selector-stubs` to the `OTHER_CFLAGS` -*Xcode* build setting in the `MoltenVK.xcodeproj` and `MoltenVKShaderConverter.xcodeproj` *Xcode* -projects, [build](../README.md#building) **MoltenVK** with *Xcode 14* or later, and then link `MoltenVK.xcframework` +> Or, if you want to use *Xcode 14* or later to [build](../README.md#building) **MoltenVK**, in order to be able to use the latest +*Metal* capabilities, but need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` to your +app or game, first add the value `-fno-objc-msgsend-selector-stubs` to the `OTHER_CFLAGS` +*Xcode* build setting in the `MoltenVK.xcodeproj` and `MoltenVKShaderConverter.xcodeproj` *Xcode* +projects, [build](../README.md#building) **MoltenVK** with *Xcode 14* or later, and then link `MoltenVK.xcframework` to your app or game using *Xcode 13* or earlier. 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 +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, + 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*, + 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. + 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 + + 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` @@ -135,7 +135,7 @@ To link **MoltenVK** to your application as an `XCFramework`, follow these steps - `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`, + - `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`) @@ -145,50 +145,50 @@ To link **MoltenVK** to your application as an `XCFramework`, follow these steps To link **MoltenVK** to your application as a dynamic library (`.dylib`), follow these steps: -1. Open your application in *Xcode* and select your application's target in the +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, + 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, + + 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, + + 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, + 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 + + 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*, + 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. - + 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)* + - `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. + 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 + + 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` @@ -196,30 +196,30 @@ To link **MoltenVK** to your application as a dynamic library (`.dylib`), follow - `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`, + - `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: - To copy the `libMoltenVK.dylib` file into your application or component library: - + 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** + 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)* - - - Alternately, you may create your own installation mechanism to install one of the following + - `MoltenVK/dylib/macOS/libMoltenVK.dylib` *(macOS)* + - `MoltenVK/dylib/iOS/libMoltenVK.dylib` *(iOS)* + - `MoltenVK/dylib/tvOS/libMoltenVK.dylib` *(tvOS)* + + - 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)* - + - `MoltenVK/dylib/macOS/libMoltenVK.dylib` *(macOS)* + - `MoltenVK/dylib/iOS/libMoltenVK.dylib` *(iOS)* + - `MoltenVK/dylib/tvOS/libMoltenVK.dylib` *(tvOS)* + ### Install *MoltenVK* replacing the Vulkan SDK `libMoltenVK.dylib` @@ -261,33 +261,33 @@ $ make macos MVK_CONFIG_LOG_LEVEL=1 **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 +>***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* +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* +- 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 +- 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 +- 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). -When a *Metal* app is running from *Xcode*, the default ***Scheme*** settings may reduce performance. +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 +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 +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) + 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. @@ -296,13 +296,13 @@ To improve performance and gain the benefits of *Metal*, perform the following i Interacting with the **MoltenVK** Runtime ----------------------------------------- -You programmatically configure and interact with the **MoltenVK** runtime through function +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 -*Vulkan* implementations. **MoltenVK** contains several header files that define access +*Vulkan* implementations. **MoltenVK** contains several header files that define access to *Vulkan* and **MoltenVK** function calls. -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 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 @@ -367,9 +367,9 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_EXT_debug_marker` - `VK_EXT_debug_report` - `VK_EXT_debug_utils` -- `VK_EXT_descriptor_indexing` - - *Initial release limited to Metal Tier 1: 96/128 textures, - 16 samplers, except macOS 11.0 (Big Sur) or later, or on older versions of macOS using +- `VK_EXT_descriptor_indexing` + - *Initial release limited to Metal Tier 1: 96/128 textures, + 16 samplers, except macOS 11.0 (Big Sur) or later, or on older versions of macOS using an Intel GPU, and if Metal argument buffers enabled in config.* - `VK_EXT_extended_dynamic_state` - *Requires Metal 3.1 for `VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE`.* @@ -393,20 +393,20 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_EXT_metal_surface` - `VK_EXT_pipeline_creation_cache_control` - `VK_EXT_pipeline_creation_feedback` -- `VK_EXT_post_depth_coverage` +- `VK_EXT_post_depth_coverage` - *iOS and macOS, requires family 4 (A11) or better Apple GPU.* - `VK_EXT_private_data ` - `VK_EXT_robustness2` - `VK_EXT_sample_locations` - `VK_EXT_scalar_block_layout` - `VK_EXT_separate_stencil_usage` -- `VK_EXT_shader_atomic_float` +- `VK_EXT_shader_atomic_float` - *Requires Metal 3.0.* -- `VK_EXT_shader_demote_to_helper_invocation` +- `VK_EXT_shader_demote_to_helper_invocation` - *Requires Metal Shading Language 2.3.* - `VK_EXT_shader_stencil_export` - *Requires Mac GPU family 2 or iOS GPU family 5.* -- `VK_EXT_shader_subgroup_ballot` +- `VK_EXT_shader_subgroup_ballot` - *Requires Mac GPU family 2 or Apple GPU family 4.* - `VK_EXT_shader_subgroup_vote` - *Requires Mac GPU family 2 or Apple GPU family 4.* @@ -421,9 +421,9 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - *Requires Metal 2.0.* - `VK_EXT_texture_compression_astc_hdr` - *iOS and macOS, requires family 6 (A13) or better Apple GPU.* -- `VK_MVK_ios_surface` +- `VK_MVK_ios_surface` - *Obsolete. Use `VK_EXT_metal_surface` instead.* -- `VK_MVK_macos_surface` +- `VK_MVK_macos_surface` - *Obsolete. Use `VK_EXT_metal_surface` instead.* - `VK_AMD_gpu_shader_half_float` - `VK_AMD_negative_viewport_height` @@ -439,44 +439,44 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_NV_glsl_shader` 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 +`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. -When creating a `CAMetalLayer` to underpin the *Vulkan* surface to render to, it is strongly -recommended that you ensure the `delegate` of the `CAMetalLayer` is the `NSView/UIView` in -which the layer is contained, to ensure correct and optimized *Vulkan* swapchain and refresh +When creating a `CAMetalLayer` to underpin the *Vulkan* surface to render to, it is strongly +recommended that you ensure the `delegate` of the `CAMetalLayer` is the `NSView/UIView` in +which the layer is contained, to ensure correct and optimized *Vulkan* swapchain and refresh timing behavior across multiple display screens that might have different properties. -The view will automatically be the `delegate` of the layer when the view creates the +The view will automatically be the `delegate` of the layer when the view creates the `CAMetalLayer`, as per Apple's documentation: ->If the layer object was created by a view, the view typically assigns itself as the layer’s -delegate automatically, and you should not change that relationship. For layers you create -yourself, you can assign a delegate object and use that object to provide the contents of +>If the layer object was created by a view, the view typically assigns itself as the layer’s +delegate automatically, and you should not change that relationship. For layers you create +yourself, you can assign a delegate object and use that object to provide the contents of the layer dynamically and perform other tasks. -But in the case where you create the `CAMetalLayer` yourself and assign it to the view, -you should also assign the view as the `delegate` of the layer. +But in the case where you create the `CAMetalLayer` yourself and assign it to the view, +you should also assign the view as the `delegate` of the layer. -Because **MoltenVK** supports the `VK_KHR_portability_subset` extension, when using the -*Vulkan Loader* from the *Vulkan SDK* to run **MoltenVK** on *macOS*, the *Vulkan Loader* -will only include **MoltenVK** `VkPhysicalDevices` in the list returned by -`vkEnumeratePhysicalDevices()` if the `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` -flag is enabled in `vkCreateInstance()`. See the description of the `VK_KHR_portability_enumeration` -extension in the *Vulkan* specification for more information about the use of the +Because **MoltenVK** supports the `VK_KHR_portability_subset` extension, when using the +*Vulkan Loader* from the *Vulkan SDK* to run **MoltenVK** on *macOS*, the *Vulkan Loader* +will only include **MoltenVK** `VkPhysicalDevices` in the list returned by +`vkEnumeratePhysicalDevices()` if the `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` +flag is enabled in `vkCreateInstance()`. See the description of the `VK_KHR_portability_enumeration` +extension in the *Vulkan* specification for more information about the use of the `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` flag. ### MoltenVK Header Files -**MoltenVK** provides additional functionality beyond standard *Vulkan* functionality, -to support configuration options and query behaviour that is specific to the **MoltenVK** +**MoltenVK** provides additional functionality beyond standard *Vulkan* functionality, +to support configuration options and query behaviour that is specific to the **MoltenVK** implementation of *Vulkan* functionality. -The following API header files are included in the **MoltenVK** package, each of which +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 @@ -485,52 +485,55 @@ where `HEADER_FILE` is one of the following: - `mvk_vulkan.h` - This is a convenience header file that loads the `` header file with platform settings to enable the appropriate _Vulkan_ WSI surface and portability extensions. - -- `mvk_private_api.h` - Contains private structures and functions to query **MoltenVK** about - **MoltenVK** version and configuration, runtime performance information, and available - _Metal_ capabilities. - > _**NOTE:**_ THE FUNCTIONS in `mvk_private_api.h` ARE NOT SUPPORTED BY THE _Vulkan Loader + +- `mvk_private_api.h` - Contains private structures and functions to query **MoltenVK** about + **MoltenVK** version and configuration, runtime performance information, and available + _Metal_ capabilities. + > _**NOTE:**_ THE FUNCTIONS in `mvk_private_api.h` ARE NOT SUPPORTED BY THE _Vulkan Loader and Layers_, AND CAN ONLY BE USED WHEN **MoltenVK** IS LINKED DIRECTLY TO YOUR APPLICATION. -- `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 as a convienience for your own +- `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 as a convienience for your own purposes such as interacting with *Metal* directly, or simply logging data values. ### Configuring MoltenVK -**MoltenVK** provides the ability to configure and optimize **MoltenVK** for your particular -application runtime requirements and development-time needs. +**MoltenVK** provides the ability to configure and optimize **MoltenVK** for your particular +application runtime requirements and development-time needs. -At runtime, configuration can be helpful in situtations where _Metal_ behavior is different -than _Vulkan_ behavior, and the results or performance you receive can depend on how **MoltenVK** -works around those differences, which, in turn, may depend on how you are using _Vulkan_. +At runtime, configuration can be helpful in situtations where _Metal_ behavior is different +than _Vulkan_ behavior, and the results or performance you receive can depend on how **MoltenVK** +works around those differences, which, in turn, may depend on how you are using _Vulkan_. Different apps might benefit differently in this handling. Additional configuration parameters can be helpful at development time by providing you with additional tracing, debugging, and performance measuring capabilities. -Each configuration parameter has a *name* and *value*, and can be passed to **MoltenVK** +Each configuration parameter has a *name* and *value*, and can be passed to **MoltenVK** via any of the following mechanisms: - The standard _Vulkan_ `VK_EXT_layer_settings` extension. - Application runtime environment variables. - Build settings at **MoltenVK** build time. -Parameter values configured by build settings at **MoltenVK** build time can be overridden -by values set by environment variables, which, in turn, can be overridden during `VkInstance` -creation via the Vulkan `VK_EXT_layer_settings` extension. +Parameter values configured by build settings at **MoltenVK** build time can be overridden +by values set by environment variables, which, in turn, can be overridden during `VkInstance` +creation via the _Vulkan_ `VK_EXT_layer_settings` extension. -Using the `VK_EXT_layer_settings` extension is the preferred mechanism, as it is a standard -_Vulkan_ extension, and is supported by the _Vulkan_ loader and layers. Using environment -variables can be a convinient mechanism to modify configuration parameters during runtime -debugging in the field (if the settings are *not* overridden during `VkInstance` creation -via the _Vulkan_ `VK_EXT_layer_settings` extension). +Using the `VK_EXT_layer_settings` extension is the preferred mechanism, as it is a standard +_Vulkan_ extension, and is supported by the _Vulkan_ loader and layers. When using the +`VK_EXT_layer_settings` extension, set `VkLayerSettingEXT::pLayerName` to the value of +`kMVKMoltenVKDriverLayerName` found in the `mvk_vulkan.h` header (or simply to `"MoltenVK"`). -A description of each configuration parameter supported by **MoltenVK** can be found in the +Using environment variables can be a convinient mechanism to modify configuration parameters +during runtime debugging in the field (if the settings are *not* overridden during `VkInstance` +creation via the _Vulkan_ `VK_EXT_layer_settings` extension). + +A description of each configuration parameter supported by **MoltenVK** can be found in the [`MoltenVK_Configuration_Parameters.md`](MoltenVK_Configuration_Parameters.md) document in the `Docs` directory. @@ -538,10 +541,10 @@ A description of each configuration parameter supported by **MoltenVK** can be f *Metal Shading Language* Shaders -------------------------------- -*Metal* uses a different shader language than *Vulkan*. *Vulkan* uses the new +*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** uses **Runtime Shader Conversion** to automatically convert your *SPIR-V* shaders -to their *MSL* equivalents, during loading your *SPIR-V* shaders, using the standard *Vulkan* +**MoltenVK** uses **Runtime Shader Conversion** to automatically convert your *SPIR-V* shaders +to their *MSL* equivalents, during loading your *SPIR-V* shaders, using the standard *Vulkan* `vkCreateShaderModule()` function. @@ -549,27 +552,27 @@ to their *MSL* equivalents, during loading your *SPIR-V* shaders, using the stan ### Troubleshooting Shader Conversion -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, +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. -- To help understand conversion issues during **Runtime Shader Conversion**, you can enable logging - the *SPIR-V* and *MSL* shader source code during shader conversion, by enabing the `MVK_CONFIG_DEBUG` +- To help understand conversion issues during **Runtime Shader Conversion**, you can enable logging + the *SPIR-V* and *MSL* shader source code during shader conversion, by enabing the `MVK_CONFIG_DEBUG` configuration parameter. 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 + 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. -- For some issues, you may be able to adjust your *SPIR-V* code so that it behaves the same +- For some 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*. -- 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. +- 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. @@ -583,22 +586,22 @@ This section discusses various options for improving performance when using **Mo ### Shader Loading Time -A number of steps is required to load and compile *SPIR-V* shaders into a form that *Metal* can use. +A number of steps is required 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 +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, +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 +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. @@ -610,13 +613,13 @@ step of converting the *SPIR-V* to *MSL* again. 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. +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 +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 +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. @@ -624,21 +627,21 @@ vailable when you request it, resulting in frame delays and visual stuttering. ### Timestamping -On non-Apple GPUs (older Mac devices), the GPU can switch power and performance states as -required by usage. This affects the GPU timestamps retrievable through the Vulkan API. -As a result, the value of `VkPhysicalDeviceLimits::timestampPeriod` can vary over time. +On non-Apple GPUs (older Mac devices), the GPU can switch power and performance states as +required by usage. This affects the GPU timestamps retrievable through the Vulkan API. +As a result, the value of `VkPhysicalDeviceLimits::timestampPeriod` can vary over time. Consider calling `vkGetPhysicalDeviceProperties()`, when needed, and retrieve the current -value of `VkPhysicalDeviceLimits::timestampPeriod`, to help you calibrate recent GPU +value of `VkPhysicalDeviceLimits::timestampPeriod`, to help you calibrate recent GPU timestamps queried through the Vulkan API. -This is not needed on Apple Silicon devices, where all GPU timestamps are always returned +This is not needed on Apple Silicon devices, where all GPU timestamps are always returned as nanoseconds, regardless of variations in power and performance states as the app runs. ### Xcode Configuration -When a *Metal* app is running from *Xcode*, the default ***Scheme*** settings reduce performance. +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. @@ -646,7 +649,7 @@ found in the in the [installation](#install) section above. ### Metal System Trace Tool -To help you get the best performance from your graphics app, the *Xcode Instruments* profiling tool +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*. @@ -658,28 +661,28 @@ Known **MoltenVK** Limitations ------------------------------ This section documents the known limitations in this version of **MoltenVK**. - + - See [above](#interaction) for known limitations for specific Vulkan extensions. - 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` + 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*, + `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. -- 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. +- 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. - Pipeline statistics query pool using `VK_QUERY_TYPE_PIPELINE_STATISTICS` is not supported. - 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 *[Vulkan SDK](https://vulkan.lunarg.com/sdk/home)*. - Refer to the *Vulkan SDK [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)* +- 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 *[Vulkan SDK](https://vulkan.lunarg.com/sdk/home)*. + Refer to the *Vulkan SDK [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)* document for more info. diff --git a/MoltenVK/MoltenVK/API/mvk_config.h b/MoltenVK/MoltenVK/API/mvk_config.h index b1e423fe..8b815fc1 100644 --- a/MoltenVK/MoltenVK/API/mvk_config.h +++ b/MoltenVK/MoltenVK/API/mvk_config.h @@ -35,7 +35,7 @@ extern "C" { * To configure MoltenVK, use one of the following mechanisms, * as documented in MoltenVK_Configuration_Parameters.md: * - * - The standard Vulkan VK_EXT_layer_settings extension. + * - The standard Vulkan VK_EXT_layer_settings extension (layer name "MoltenVK"). * - Application runtime environment variables. * - Build settings at MoltenVK build time. * diff --git a/MoltenVK/MoltenVK/API/mvk_deprecated_api.h b/MoltenVK/MoltenVK/API/mvk_deprecated_api.h index 1aea704f..e2faf5b1 100644 --- a/MoltenVK/MoltenVK/API/mvk_deprecated_api.h +++ b/MoltenVK/MoltenVK/API/mvk_deprecated_api.h @@ -78,11 +78,11 @@ typedef void (VKAPI_PTR *PFN_vkGetMTLCommandQueueMVK)(VkQueue queue, id +/** The name of the MoltenVK driver layer. */ +static const char* kMVKMoltenVKDriverLayerName = "MoltenVK"; + #endif diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index d0b2cef1..deec23a2 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -28,7 +28,7 @@ * To configure MoltenVK, use one of the following mechanisms, * as documented in MoltenVK_Configuration_Parameters.md: * - * - The standard Vulkan VK_EXT_layer_settings extension. + * - The standard Vulkan VK_EXT_layer_settings extension (layer name "MoltenVK"). * - Application runtime environment variables. * - Build settings at MoltenVK build time. * diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index f1b4f2a2..3b08b14d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -533,7 +533,7 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) { supportedProps12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; supportedProps12.pNext = nullptr; supportedProps12.driverID = VK_DRIVER_ID_MOLTENVK; - strcpy(supportedProps12.driverName, "MoltenVK"); + strcpy(supportedProps12.driverName, kMVKMoltenVKDriverLayerName); strcpy(supportedProps12.driverInfo, mvkGetMoltenVKVersionString(MVK_VERSION).c_str()); supportedProps12.conformanceVersion.major = 0; supportedProps12.conformanceVersion.minor = 0; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h index da63fea4..491505d4 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h @@ -72,7 +72,7 @@ public: MVKInstance* getInstance() override { return this; } /** Return the MoltenVK configuration info for this VkInstance. */ - const MVKConfiguration& getMVKConfig() override { return _enabledExtensions.vk_EXT_layer_settings.enabled ? _mvkConfig : mvkConfig(); } + const MVKConfiguration& getMVKConfig() override { return _enabledExtensions.vk_EXT_layer_settings.enabled ? _mvkConfig : getGlobalMVKConfig(); } /** Returns the maximum version of Vulkan the application supports. */ inline uint32_t getAPIVersion() { return _appInfo.apiVersion; } @@ -204,7 +204,7 @@ protected: MVKSmallVector _debugReportCallbacks; MVKSmallVector _debugUtilMessengers; std::unordered_map _entryPoints; - std::string _autoGPUCaptureOutputFilepath; + std::string _mvkConfigStringHolders[kMVKConfigurationStringCount] = {}; std::mutex _dcbLock; bool _hasDebugReportCallbacks; bool _hasDebugUtilsMessengers; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 0e5b2c6d..c0d4e197 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -352,7 +352,7 @@ void MVKInstance::initMVKConfig(const VkInstanceCreateInfo* pCreateInfo) { if ( !_enabledExtensions.vk_EXT_layer_settings.enabled ) { return; } - _mvkConfig = mvkConfig(); + _mvkConfig = getGlobalMVKConfig(); VkLayerSettingsCreateInfoEXT* pLSCreateInfo = nil; for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) { @@ -379,7 +379,7 @@ void MVKInstance::initMVKConfig(const VkInstanceCreateInfo* pCreateInfo) { } #include "MVKConfigMembers.def" } - mvkSetConfig(_mvkConfig, _mvkConfig, _autoGPUCaptureOutputFilepath); + mvkSetConfig(_mvkConfig, _mvkConfig, _mvkConfigStringHolders); } #define ADD_ENTRY_POINT_MAP(name, func, api, ext1, ext2, isDev) \ diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm index 50e4601f..50c5d462 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm @@ -582,7 +582,7 @@ void MVKMetalCompiler::compile(unique_lock& lock, dispatch_block_t block) if ( !_isCompileDone ) { @autoreleasepool { NSString* errDesc = [NSString stringWithFormat: @"Timeout after %.3f milliseconds. Likely internal Metal compiler error", (double)nanoTimeout.count() / 1e6]; - _compileError = [[NSError alloc] initWithDomain: @"MoltenVK" code: 1 userInfo: @{NSLocalizedDescriptionKey : errDesc}]; // retained + _compileError = [[NSError alloc] initWithDomain: @(kMVKMoltenVKDriverLayerName) code: 1 userInfo: @{NSLocalizedDescriptionKey : errDesc}]; // retained } } diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.mm b/MoltenVK/MoltenVK/Layers/MVKExtensions.mm index 11f98b49..6f6c2cab 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.mm +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.mm @@ -50,7 +50,7 @@ static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) { // If the config indicates that not all supported extensions should be advertised, // only advertise those supported extensions that have been specifically configured. - auto advExtns = mvkConfig().advertiseExtensions; + auto advExtns = getGlobalMVKConfig().advertiseExtensions; if ( !mvkIsAnyFlagEnabled(advExtns, MVK_CONFIG_ADVERTISE_EXTENSIONS_ALL) ) { #define MVK_NA kMVKOSVersionUnsupported if (mvkIsAnyFlagEnabled(advExtns, MVK_CONFIG_ADVERTISE_EXTENSIONS_WSI)) { diff --git a/MoltenVK/MoltenVK/Layers/MVKLayers.mm b/MoltenVK/MoltenVK/Layers/MVKLayers.mm index 237017dc..b5899413 100644 --- a/MoltenVK/MoltenVK/Layers/MVKLayers.mm +++ b/MoltenVK/MoltenVK/Layers/MVKLayers.mm @@ -40,7 +40,7 @@ MVKLayer::MVKLayer() : _supportedInstanceExtensions(nullptr, true) { // The core driver layer mvkClear(_layerProperties.layerName, VK_MAX_EXTENSION_NAME_SIZE); - strcpy(_layerProperties.layerName, "MoltenVK"); + strcpy(_layerProperties.layerName, kMVKMoltenVKDriverLayerName); mvkClear(_layerProperties.description, VK_MAX_DESCRIPTION_SIZE); strcpy(_layerProperties.description, "MoltenVK driver layer"); _layerProperties.specVersion = getMVKConfig().apiVersionToAdvertise; diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h index 356dce42..457b39de 100644 --- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h +++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h @@ -222,5 +222,5 @@ protected: * VkInstance that created the object, otherwise returns the global configuration info. */ static inline const MVKConfiguration& mvkGetMVKConfig(MVKBaseObject* mvkObj) { - return mvkObj ? mvkObj->getMVKConfig() : mvkConfig(); + return mvkObj ? mvkObj->getMVKConfig() : getGlobalMVKConfig(); } diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm b/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm index 53b1731d..77a61681 100644 --- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm +++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm @@ -44,7 +44,7 @@ string MVKBaseObject::getClassName() { return mvk::getTypeName(this); } const MVKConfiguration& MVKBaseObject::getMVKConfig() { MVKVulkanAPIObject* mvkAPIObj = getVulkanAPIObject(); MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr; - return mvkInst ? mvkInst->getMVKConfig() : mvkConfig(); + return mvkGetMVKConfig(mvkInst); } void MVKBaseObject::reportMessage(MVKConfigLogLevel logLevel, const char* format, ...) { @@ -67,7 +67,7 @@ void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, MVKConfigLogLevel logLe MVKVulkanAPIObject* mvkAPIObj = mvkObj ? mvkObj->getVulkanAPIObject() : nullptr; MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr; bool hasDebugCallbacks = mvkInst && mvkInst->hasDebugCallbacks(); - bool shouldLog = logLevel <= (mvkInst ? mvkInst->getMVKConfig() : mvkConfig()).logLevel; + bool shouldLog = logLevel <= mvkGetMVKConfig(mvkInst).logLevel; // Fail fast to avoid further unnecessary processing. if ( !(shouldLog || hasDebugCallbacks) ) { return; } diff --git a/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def b/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def index 1b5cf69f..6e00a01c 100644 --- a/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def +++ b/MoltenVK/MoltenVK/Utility/MVKConfigMembers.def @@ -69,7 +69,7 @@ MVK_CONFIG_MEMBER(forceLowPowerGPU, VkBool32, MVK_CONFIG_MEMBER(semaphoreUseMTLFence, VkBool32, ALLOW_METAL_FENCES) // Deprecated legacy MVK_CONFIG_MEMBER(semaphoreSupportStyle, MVKVkSemaphoreSupportStyle, VK_SEMAPHORE_SUPPORT_STYLE) MVK_CONFIG_MEMBER(autoGPUCaptureScope, MVKConfigAutoGPUCaptureScope, AUTO_GPU_CAPTURE_SCOPE) -MVK_CONFIG_MEMBER_STRING(autoGPUCaptureOutputFilepath, char*, AUTO_GPU_CAPTURE_OUTPUT_FILE) +MVK_CONFIG_MEMBER_STRING(autoGPUCaptureOutputFilepath, const char*, AUTO_GPU_CAPTURE_OUTPUT_FILE) MVK_CONFIG_MEMBER(texture1DAs2D, VkBool32, TEXTURE_1D_AS_2D) MVK_CONFIG_MEMBER(preallocateDescriptors, VkBool32, PREALLOCATE_DESCRIPTORS) MVK_CONFIG_MEMBER(useCommandPooling, VkBool32, USE_COMMAND_POOLING) diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp index e8f0870c..a716b16b 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp @@ -21,6 +21,8 @@ #include "MVKFoundation.h" +#pragma mark Support functions + // Return the expected size of MVKConfiguration, based on contents of MVKConfigMembers.def. static constexpr uint32_t getExpectedMVKConfigurationSize() { #define MVK_CONFIG_MEMBER(member, mbrType, name) cfgSize += sizeof(mbrType); @@ -29,11 +31,62 @@ static constexpr uint32_t getExpectedMVKConfigurationSize() { return cfgSize; } -static bool _mvkConfigInitialized = false; -static void mvkInitConfigFromEnvVars() { +// Return the expected number of string members in MVKConfiguration, based on contents of MVKConfigMembers.def. +static constexpr uint32_t getExpectedMVKConfigurationStringCount() { +#define MVK_CONFIG_MEMBER(member, mbrType, name) +#define MVK_CONFIG_MEMBER_STRING(member, mbrType, name) if(std::is_same::value) { strCnt++; } + uint32_t strCnt = 0; +#include "MVKConfigMembers.def" + return strCnt; +} + + +#pragma mark Set configuration values + +// Sets destination config content from the source content, validates content, +// and ensures the content of any string members of MVKConfiguration are copied locally. +void mvkSetConfig(MVKConfiguration& dstMVKConfig, const MVKConfiguration& srcMVKConfig, std::string* stringHolders) { + + dstMVKConfig = srcMVKConfig; + + // Ensure the API version is supported, and add the VK_HEADER_VERSION. + dstMVKConfig.apiVersionToAdvertise = std::min(dstMVKConfig.apiVersionToAdvertise, MVK_VULKAN_API_VERSION); + dstMVKConfig.apiVersionToAdvertise = VK_MAKE_VERSION(VK_VERSION_MAJOR(dstMVKConfig.apiVersionToAdvertise), + VK_VERSION_MINOR(dstMVKConfig.apiVersionToAdvertise), + VK_HEADER_VERSION); + + // Deprecated legacy support for specific case where both legacy semaphoreUseMTLEvent + // (now aliased to semaphoreSupportStyle) and legacy semaphoreUseMTLFence are explicitly + // disabled by the app. In this case the app had been using CPU emulation, so use + // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK. + if ( !dstMVKConfig.semaphoreUseMTLEvent && !dstMVKConfig.semaphoreUseMTLFence ) { + dstMVKConfig.semaphoreSupportStyle = MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK; + } + + // Clamp timestampPeriodLowPassAlpha between 0.0 and 1.0. + dstMVKConfig.timestampPeriodLowPassAlpha = mvkClamp(dstMVKConfig.timestampPeriodLowPassAlpha, 0.0f, 1.0f); + + // For each string member of the destination MVKConfiguration, store the contents + // in a std::string, then repoint the member to the contents of the std::string. +#define MVK_CONFIG_MEMBER(member, mbrType, name) +#define MVK_CONFIG_MEMBER_STRING(member, mbrType, name) \ + if (dstMVKConfig.member) { stringHolders[strIdx] = dstMVKConfig.member; } \ + dstMVKConfig.member = stringHolders[strIdx++].c_str(); + + static_assert(getExpectedMVKConfigurationStringCount() == kMVKConfigurationStringCount, "Each string member in MVKConfiguration needs a separate std::string to hold its content."); + uint32_t strIdx = 0; +#include "MVKConfigMembers.def" + assert(strIdx == kMVKConfigurationStringCount); // Ensure all string members of MVKConfiguration were stored in separate std::strings. +} + + +#pragma mark Load global configuration from environment variables + +static bool _mvkGlobalConfigInitialized = false; +static void mvkInitGlobalConfigFromEnvVars() { static_assert(getExpectedMVKConfigurationSize() == sizeof(MVKConfiguration), "MVKConfigMembers.def does not match the members of MVKConfiguration."); - _mvkConfigInitialized = true; + _mvkGlobalConfigInitialized = true; MVKConfiguration evCfg; std::string evGPUCapFileStrObj; @@ -59,7 +112,7 @@ static void mvkInitConfigFromEnvVars() { // Legacy MVK_ALLOW_METAL_EVENTS is covered by MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE, // but for backwards compatibility, if legacy MVK_ALLOW_METAL_EVENTS is explicitly // disabled, disable semaphoreUseMTLEvent (aliased as semaphoreSupportStyle value - // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE), and let mvkSetConfig() + // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE), and let mvkSetGlobalConfig() // further process legacy behavior of MVK_ALLOW_METAL_FENCES. if ( !mvkGetEnvVarNumber("MVK_CONFIG_ALLOW_METAL_EVENTS", 1.0) ) { evCfg.semaphoreUseMTLEvent = (MVKVkSemaphoreSupportStyle)false; // Disabled. Also semaphoreSupportStyle MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE. @@ -74,57 +127,23 @@ static void mvkInitConfigFromEnvVars() { evCfg.activityPerformanceLoggingStyle = MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE; } - mvkSetConfig(evCfg); + mvkSetGlobalConfig(evCfg); } -static MVKConfiguration _mvkConfig; -static std::string _autoGPUCaptureOutputFilepath; +static MVKConfiguration _globalMVKConfig; +static std::string _globalMVKConfigStringHolders[kMVKConfigurationStringCount] = {}; // Returns the MoltenVK config, lazily initializing it if necessary. // We initialize lazily instead of in a library constructor function to // ensure the NSProcessInfo environment is available when called upon. -const MVKConfiguration& mvkConfig() { - if ( !_mvkConfigInitialized ) { - mvkInitConfigFromEnvVars(); +const MVKConfiguration& getGlobalMVKConfig() { + if ( !_mvkGlobalConfigInitialized ) { + mvkInitGlobalConfigFromEnvVars(); } - return _mvkConfig; + return _globalMVKConfig; } -void mvkSetConfig(const MVKConfiguration& mvkConfig) { - mvkSetConfig(_mvkConfig, mvkConfig, _autoGPUCaptureOutputFilepath); -} - -// Sets destination config content from the source content, validates content, -// and updates any content that needs baking, including copying the contents of -// strings from the incoming MVKConfiguration member to a corresponding std::string, -// and then repointing the MVKConfiguration member to the contents of the std::string. -void mvkSetConfig(MVKConfiguration& dstMVKConfig, - const MVKConfiguration& srcMVKConfig, - std::string& autoGPUCaptureOutputFilepath) { - - dstMVKConfig = srcMVKConfig; - - // Ensure the API version is supported, and add the VK_HEADER_VERSION. - dstMVKConfig.apiVersionToAdvertise = std::min(dstMVKConfig.apiVersionToAdvertise, MVK_VULKAN_API_VERSION); - dstMVKConfig.apiVersionToAdvertise = VK_MAKE_VERSION(VK_VERSION_MAJOR(dstMVKConfig.apiVersionToAdvertise), - VK_VERSION_MINOR(dstMVKConfig.apiVersionToAdvertise), - VK_HEADER_VERSION); - - // Deprecated legacy support for specific case where both legacy semaphoreUseMTLEvent - // (now aliased to semaphoreSupportStyle) and legacy semaphoreUseMTLFence are explicitly - // disabled by the app. In this case the app had been using CPU emulation, so use - // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK. - if ( !dstMVKConfig.semaphoreUseMTLEvent && !dstMVKConfig.semaphoreUseMTLFence ) { - dstMVKConfig.semaphoreSupportStyle = MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK; - } - - // Set capture file path string - if (dstMVKConfig.autoGPUCaptureOutputFilepath) { - autoGPUCaptureOutputFilepath = dstMVKConfig.autoGPUCaptureOutputFilepath; - } - dstMVKConfig.autoGPUCaptureOutputFilepath = autoGPUCaptureOutputFilepath.c_str(); - - // Clamp timestampPeriodLowPassAlpha between 0.0 and 1.0. - dstMVKConfig.timestampPeriodLowPassAlpha = mvkClamp(dstMVKConfig.timestampPeriodLowPassAlpha, 0.0f, 1.0f); +void mvkSetGlobalConfig(const MVKConfiguration& srcMVKConfig) { + mvkSetConfig(_globalMVKConfig, srcMVKConfig, _globalMVKConfigStringHolders); } diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h index 4dc98a18..648ae034 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h @@ -75,21 +75,22 @@ #pragma mark - -#pragma mark Global Configuration +#pragma mark MoltenVK Configuration + +/** The number of members of MVKConfiguration that are strings. */ +static constexpr uint32_t kMVKConfigurationStringCount = 1; /** Global function to access MoltenVK configuration info. */ -const MVKConfiguration& mvkConfig(); +const MVKConfiguration& getGlobalMVKConfig(); /** Sets the MoltenVK global configuration content. */ -void mvkSetConfig(const MVKConfiguration& mvkConfig); +void mvkSetGlobalConfig(const MVKConfiguration& srcMVKConfig); /** * Sets the content from the source config into the destination * config, while using the string object to retain string content. */ -void mvkSetConfig(MVKConfiguration& dstMVKConfig, - const MVKConfiguration& srcMVKConfig, - std::string& autoGPUCaptureOutputFilepath); +void mvkSetConfig(MVKConfiguration& dstMVKConfig, const MVKConfiguration& srcMVKConfig, std::string* stringHolders); /** * Enable debug mode. diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index d3aa660a..3d5dee0d 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -379,9 +379,6 @@ static constexpr bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComp mvkVKComponentSwizzlesMatch(cm1.a, cm2.a, VK_COMPONENT_SWIZZLE_A)); } -/** Print the size of the type. */ -#define mvkPrintSizeOf(type) printf("Size of " #type " is %lu.\n", sizeof(type)) - #pragma mark Math diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_api.mm b/MoltenVK/MoltenVK/Vulkan/mvk_api.mm index fec65666..cc0d7065 100644 --- a/MoltenVK/MoltenVK/Vulkan/mvk_api.mm +++ b/MoltenVK/MoltenVK/Vulkan/mvk_api.mm @@ -59,7 +59,7 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkGetMoltenVKConfigurationMVK( MVKConfiguration* pConfiguration, size_t* pConfigurationSize) { - return mvkCopyGrowingStruct(pConfiguration, &mvkConfig(), pConfigurationSize); + return mvkCopyGrowingStruct(pConfiguration, &getGlobalMVKConfig(), pConfigurationSize); } MVK_PUBLIC_VULKAN_SYMBOL VkResult vkSetMoltenVKConfigurationMVK( @@ -69,9 +69,9 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkSetMoltenVKConfigurationMVK( // Start with copy of current config, in case incoming is not fully copied MVKBaseObject::reportMessage(nullptr, MVK_CONFIG_LOG_LEVEL_WARNING, "vkSetMoltenVKConfigurationMVK() is deprecated. To set MoltenVK configuration parameters, the VK_EXT_layer_settings extension, or environment variables."); - MVKConfiguration mvkCfg = mvkConfig(); + MVKConfiguration mvkCfg = getGlobalMVKConfig(); VkResult rslt = mvkCopyGrowingStruct(&mvkCfg, pConfiguration, pConfigurationSize); - mvkSetConfig(mvkCfg); + mvkSetGlobalConfig(mvkCfg); return rslt; } @@ -110,7 +110,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkGetVersionStringsMVK( len = mvkVer.copy(pMoltenVersionStringBuffer, moltenVersionStringBufferLength - 1); pMoltenVersionStringBuffer[len] = 0; // terminator - string vkVer = mvkGetVulkanVersionString(mvkConfig().apiVersionToAdvertise); + string vkVer = mvkGetVulkanVersionString(getGlobalMVKConfig().apiVersionToAdvertise); len = vkVer.copy(pVulkanVersionStringBuffer, vulkanVersionStringBufferLength - 1); pVulkanVersionStringBuffer[len] = 0; // terminator } diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 293826a3..1d228faf 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -55,7 +55,7 @@ static inline uint64_t MVKTraceVulkanCallStartImpl(const char* funcName) { bool includeExit = false; bool includeDuration = false; - switch (mvkConfig().traceVulkanCalls) { + switch (getGlobalMVKConfig().traceVulkanCalls) { case MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION: includeDuration = true; // fallthrough case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT: @@ -94,7 +94,7 @@ static inline uint64_t MVKTraceVulkanCallStartImpl(const char* funcName) { // Optionally log end of function calls and timings to stderr static inline void MVKTraceVulkanCallEndImpl(const char* funcName, uint64_t startTime) { - switch(mvkConfig().traceVulkanCalls) { + switch(getGlobalMVKConfig().traceVulkanCalls) { case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT: case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT_THREAD_ID: fprintf(stderr, "[mvk-trace] } %s\n", funcName); @@ -2021,7 +2021,7 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkEnumerateInstanceVersion( uint32_t* pApiVersion) { MVKTraceVulkanCallStart(); - *pApiVersion = mvkConfig().apiVersionToAdvertise; + *pApiVersion = getGlobalMVKConfig().apiVersionToAdvertise; MVKTraceVulkanCallEnd(); return VK_SUCCESS; } diff --git a/README.md b/README.md index e7d56599..69446d25 100644 --- a/README.md +++ b/README.md @@ -36,33 +36,33 @@ Table of Contents Introduction to MoltenVK ------------------------ -**MoltenVK** is a layered implementation of [*Vulkan 1.2*](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 *macOS*, *iOS*, *tvOS*, and *visionOS*. **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 *macOS*, *iOS*, *tvOS*, *visionOS*, *Simulators*, and *Mac Catalyst* on *macOS 11.0+*, +**MoltenVK** is a layered implementation of [*Vulkan 1.2*](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 *macOS*, *iOS*, *tvOS*, and *visionOS*. **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 *macOS*, *iOS*, *tvOS*, *visionOS*, *Simulators*, and *Mac Catalyst* on *macOS 11.0+*, and all *Apple* architectures, including *Apple Silicon*. -*Metal* uses a different shading language, the *Metal Shading Language (MSL)*, than -*Vulkan*, which uses *SPIR-V*. **MoltenVK** automatically converts your *SPIR-V* shaders +*Metal* uses a different shading language, the *Metal Shading Language (MSL)*, than +*Vulkan*, which uses *SPIR-V*. **MoltenVK** automatically converts your *SPIR-V* shaders to their *MSL* equivalents. -To provide *Vulkan* capability to the *macOS*, *iOS*, *tvOS*, and *visionOS* 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 +To provide *Vulkan* capability to the *macOS*, *iOS*, *tvOS*, and *visionOS* 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*. The **MoltenVK** runtime package contains two products: -- **MoltenVK** is a implementation of an almost-complete subset of the +- **MoltenVK** is a implementation of an almost-complete subset of the [*Vulkan 1.2*](https://www.khronos.org/vulkan) graphics and compute API. - **MoltenVKShaderConverter** converts *SPIR-V* shader code to *Metal Shading Language (MSL)* shader code, and converts *GLSL* shader source code to *SPIR-V* shader code and/or - *Metal Shading Language (MSL)* shader code. The converter is embedded in the **MoltenVK** - runtime to automatically convert *SPIR-V* shaders to their *MSL* equivalents. In addition, - both the *SPIR-V* and *GLSL* converters are packaged into a stand-alone command-line + *Metal Shading Language (MSL)* shader code. The converter is embedded in the **MoltenVK** + runtime to automatically convert *SPIR-V* shaders to their *MSL* equivalents. In addition, + both the *SPIR-V* and *GLSL* converters are packaged into a stand-alone command-line `MoltenVKShaderConverter` *macOS* tool for converting shaders at development time from the command line. @@ -74,32 +74,32 @@ Developing *Vulkan* Applications for *macOS, iOS, tvOS, and visionOS* ### Using the *Vulkan SDK* -The recommended method for developing a *Vulkan* application for *macOS* is to use the +The recommended method for developing a *Vulkan* application for *macOS* is to use the [*Vulkan SDK*](https://vulkan.lunarg.com/sdk/home). -The *Vulkan SDK* includes a **MoltenVK** runtime library for *macOS*. *Vulkan* is a layered -architecture that allows applications to add additional functionality without modifying the +The *Vulkan SDK* includes a **MoltenVK** runtime library for *macOS*. *Vulkan* is a layered +architecture that allows applications to add additional functionality without modifying the application itself. The *Validation Layers* included in the *Vulkan SDK* are an essential debugging -tool for application developers because they identify inappropriate use of the *Vulkan API*. +tool for application developers because they identify inappropriate use of the *Vulkan API*. If you are developing a *Vulkan* application for *macOS*, it is highly recommended that you use the [*Vulkan SDK*](https://vulkan.lunarg.com/sdk/home) and the **MoltenVK** library included in it. -Refer to the *Vulkan SDK [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)* +Refer to the *Vulkan SDK [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)* document for more info. -Because **MoltenVK** supports the `VK_KHR_portability_subset` extension, when using the -*Vulkan Loader* from the *Vulkan SDK* to run **MoltenVK** on *macOS*, the *Vulkan Loader* -will only include **MoltenVK** `VkPhysicalDevices` in the list returned by -`vkEnumeratePhysicalDevices()` if the `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` -flag is enabled in `vkCreateInstance()`. See the description of the `VK_KHR_portability_enumeration` -extension in the *Vulkan* specification for more information about the use of the +Because **MoltenVK** supports the `VK_KHR_portability_subset` extension, when using the +*Vulkan Loader* from the *Vulkan SDK* to run **MoltenVK** on *macOS*, the *Vulkan Loader* +will only include **MoltenVK** `VkPhysicalDevices` in the list returned by +`vkEnumeratePhysicalDevices()` if the `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` +flag is enabled in `vkCreateInstance()`. See the description of the `VK_KHR_portability_enumeration` +extension in the *Vulkan* specification for more information about the use of the `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` flag. ### Using MoltenVK Directly -If you are developing a *Vulkan* application for *iOS*, *tvOS*, or *visionOS*, or are -developing a *Vulkan* application for *macOS* and want to use a different version or -build of the **MoltenVK** runtime library than provided in the *macOS Vulkan SDK*, +If you are developing a *Vulkan* application for *iOS*, *tvOS*, or *visionOS*, or are +developing a *Vulkan* application for *macOS* and want to use a different version or +build of the **MoltenVK** runtime library than provided in the *macOS Vulkan SDK*, you can access a pre-built MoltenVK binary library from the **MoltenVK** repository, by [selecting a repository commit from the list](https://github.com/KhronosGroup/MoltenVK/actions), and downloading the associated **MoltenVK** runtime library artifact. @@ -108,8 +108,8 @@ Finally, if you want a customized build of **MoltenVK**, you can follow the [ins to create a **MoltenVK** runtime library by fetching and building the **MoltenVK** source code. To learn how to integrate the **MoltenVK** runtime library into a game or application, -see the [`MoltenVK_Runtime_UserGuide.md `](Docs/MoltenVK_Runtime_UserGuide.md) -document in the `Docs` directory. +see the [`MoltenVK_Runtime_UserGuide.md `](Docs/MoltenVK_Runtime_UserGuide.md) +document in the `Docs` directory. @@ -117,8 +117,8 @@ document in the `Docs` directory. Fetching **MoltenVK** Source Code --------------------------------- -To fetch **MoltenVK** source code, clone this `MoltenVK` repository, and then run the -`fetchDependencies` script to retrieve and build several external open-source libraries +To fetch **MoltenVK** source code, clone this `MoltenVK` repository, and then run the +`fetchDependencies` script to retrieve and build several external open-source libraries on which **MoltenVK** relies: 1. Ensure you have `cmake` and `python3` installed: @@ -139,26 +139,26 @@ on which **MoltenVK** relies: cd MoltenVK ./fetchDependencies [platform...] -When running the `fetchDependencies` script, you must specify one or more platforms -for which to build the external libraries. The platform choices include: +When running the `fetchDependencies` script, you must specify one or more platforms +for which to build the external libraries. The platform choices include: - --all - --macos - --ios - --iossim - --maccat - --tvos + --all + --macos + --ios + --iossim + --maccat + --tvos --tvossim -You can specify multiple of these selections. The result is a single `XCFramework` -for each external dependency library, with each `XCFramework` containing binaries for -each of the requested platforms. +You can specify multiple of these selections. The result is a single `XCFramework` +for each external dependency library, with each `XCFramework` containing binaries for +each of the requested platforms. -The `--all` selection is the same as entering all of the other platform choices, -and will result in a single `XCFramework` for each external dependency library, -with each `XCFramework` containing binaries for all supported platforms and simulators. +The `--all` selection is the same as entering all of the other platform choices, +and will result in a single `XCFramework` for each external dependency library, +with each `XCFramework` containing binaries for all supported platforms and simulators. -Running `fetchDependencies` repeatedly with different platforms will accumulate targets +Running `fetchDependencies` repeatedly with different platforms will accumulate targets in the `XCFramework`, if the `--keep-cache` option is used on each invocation. For more information about the external open-source libraries used by **MoltenVK**, @@ -169,83 +169,83 @@ see the [`ExternalRevisions/README.md`](ExternalRevisions/README.md) document. Building **MoltenVK** ------------------- -During building, **MoltenVK** references the latest *Apple SDK* frameworks. To access these frameworks, +During building, **MoltenVK** references the latest *Apple SDK* frameworks. To access these frameworks, and to avoid build errors, be sure to use the latest publicly available version of *Xcode*. -> ***Note:*** *Xcode 14* introduced a new static linkage model that is not compatible with previous -versions of *Xcode*. If you link to a `MoltenVK.xcframework` that was built with *Xcode 14* or later, -also use *Xcode 14* or later to link it to your app or game. +> ***Note:*** *Xcode 14* introduced a new static linkage model that is not compatible with previous +versions of *Xcode*. If you link to a `MoltenVK.xcframework` that was built with *Xcode 14* or later, +also use *Xcode 14* or later to link it to your app or game. > -> If you need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` to your app or game, -first build **MoltenVK** with *Xcode 13* or earlier. +> If you need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` to your app or game, +first build **MoltenVK** with *Xcode 13* or earlier. > -> Or, if you want to use *Xcode 14* or later to build **MoltenVK**, in order to be able to use the -latest *Metal* capabilities, but need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` -to your app or game, first add the value `-fno-objc-msgsend-selector-stubs` to the `OTHER_CFLAGS` -*Xcode* build setting in the `MoltenVK.xcodeproj` and `MoltenVKShaderConverter.xcodeproj` *Xcode* -projects, build **MoltenVK** with *Xcode 14* or later, and then link `MoltenVK.xcframework` +> Or, if you want to use *Xcode 14* or later to build **MoltenVK**, in order to be able to use the +latest *Metal* capabilities, but need to use *Xcode 13* or earlier to link `MoltenVK.xcframework` +to your app or game, first add the value `-fno-objc-msgsend-selector-stubs` to the `OTHER_CFLAGS` +*Xcode* build setting in the `MoltenVK.xcodeproj` and `MoltenVKShaderConverter.xcodeproj` *Xcode* +projects, build **MoltenVK** with *Xcode 14* or later, and then link `MoltenVK.xcframework` to your app or game using *Xcode 13* or earlier. -**MoltenVK** can be built to support at least *macOS 10.11*, *iOS 9*, or *tvOS 9*, but the default -_Xcode_ build settings in the included _Xcode_ projects are set to a minimum deployment target of -*macOS 10.13*, *iOS 11*, and *tvOS 11*, which are the oldest OS versions supported by the current -_Xcode_ version. If you require support for earlier OS versions, modify the `MACOSX_DEPLOYMENT_TARGET`, +**MoltenVK** can be built to support at least *macOS 10.11*, *iOS 9*, or *tvOS 9*, but the default +_Xcode_ build settings in the included _Xcode_ projects are set to a minimum deployment target of +*macOS 10.13*, *iOS 11*, and *tvOS 11*, which are the oldest OS versions supported by the current +_Xcode_ version. If you require support for earlier OS versions, modify the `MACOSX_DEPLOYMENT_TARGET`, `IPHONEOS_DEPLOYMENT_TARGET`, or `TVOS_DEPLOYMENT_TARGET` build settings in _Xcode_ before building **MoltenVK**. ->***Note:*** To support `IOSurfaces` on *iOS* or *tvOS*, **MoltenVK**, and 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 `) +>***Note:*** To support `IOSurfaces` on *iOS* or *tvOS*, **MoltenVK**, and 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, the **MoltenVK** libraries can be run on *macOS*, *iOS*, *tvOS*, or *visionOS* devices +Once built, the **MoltenVK** libraries can be run on *macOS*, *iOS*, *tvOS*, or *visionOS* devices that support *Metal*,or on the *Xcode* *iOS Simulator*, *tvOS Simulator*, or *visionOS Simulator*. -- At runtime, **MoltenVK** requires at least *macOS 10.11*, *iOS 9.0*, *tvOS 9.0*, +- At runtime, **MoltenVK** requires at least *macOS 10.11*, *iOS 9.0*, *tvOS 9.0*, or *visionOS 1.0* (or *iOS 11* or *tvOS 11* if using `IOSurfaces`). -- Information on *macOS* devices that are compatible with *Metal* can be found in +- 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 +- 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). -The `MoltenVKPackaging.xcodeproj` *Xcode* project contains targets and schemes to build -and package the entire **MoltenVK** runtime distribution package, or to build individual +The `MoltenVKPackaging.xcodeproj` *Xcode* project contains targets and schemes to build +and package the entire **MoltenVK** runtime distribution package, or to build individual **MoltenVK** or **MoltenVKShaderConverter** components. -To build a **MoltenVK** runtime distribution package, suitable for testing and integrating into an app, +To build a **MoltenVK** runtime distribution package, suitable for testing and integrating into an app, open `MoltenVKPackaging.xcodeproj` in *Xcode*, and use one of the following *Xcode Schemes*, depending -on whether you want a **_Release_** or **_Debug_** configuration, and whether you want to build for all +on whether you want a **_Release_** or **_Debug_** configuration, and whether you want to build for all platforms, or just one platform (in **_Release_** configuration): -- **MoltenVK Package** -- **MoltenVK Package (Debug)** -- **MoltenVK Package (macOS only)** +- **MoltenVK Package** +- **MoltenVK Package (Debug)** +- **MoltenVK Package (macOS only)** - **MoltenVK Package (iOS only)** - **MoltenVK Package (tvOS only)** - **MoltenVK Package (visionOS only)** _(requires Xcode 15+)_ -Each of these`MoltenVKPackaging.xcodeproj` *Xcode* project *Schemes* puts the resulting packages in the -`Package` directory, creating it if necessary. This directory contains separate `Release` and `Debug` +Each of these`MoltenVKPackaging.xcodeproj` *Xcode* project *Schemes* puts the resulting packages in the +`Package` directory, creating it if necessary. This directory contains separate `Release` and `Debug` directories, holding the most recent **_Release_** and **_Debug_** builds, respectively. -A separate `Latest` directory links to the most recent build, regardless of whether it was a **_Release_** -or **_Debug_** build. Effectively, the `Package/Latest` directory points to whichever of the `Package/Release` +A separate `Latest` directory links to the most recent build, regardless of whether it was a **_Release_** +or **_Debug_** build. Effectively, the `Package/Latest` directory points to whichever of the `Package/Release` or `Package/Debug` directories was most recently updated. -With this packaging structure, you can follow the [instructions below](#using) to link your application -to the **MoltenVK** libraries and frameworks in the `Package/Latest` directory, to provide the flexibility +With this packaging structure, you can follow the [instructions below](#using) to link your application +to the **MoltenVK** libraries and frameworks in the `Package/Latest` directory, to provide the flexibility to test your app with either a **_Debug_** build, or a higher-performance **_Release_** build. ### Building from the Command Line If you prefer to build **MoltenVK** from the command line, or to include the activity in a larger build script, -you can do so by executing a command similar to the following command within the `MoltenVK` repository folder, -and identifying one of the *Xcode Schemes* from the list above. For example, the following command will build +you can do so by executing a command similar to the following command within the `MoltenVK` repository folder, +and identifying one of the *Xcode Schemes* from the list above. For example, the following command will build **MoltenVK** in the **_Debug_** configuration for *macOS* only: xcodebuild build -quiet -project MoltenVKPackaging.xcodeproj -scheme "MoltenVK Package (macOS only)" -configuration "Debug" -Alternately, you can use the basic `Makefile` in the `MoltenVK` repository folder to build **MoltenVK** +Alternately, you can use the basic `Makefile` in the `MoltenVK` repository folder to build **MoltenVK** from the command line. The following `make` targets are provided: make @@ -272,19 +272,19 @@ from the command line. The following `make` targets are provided: - The `all` target executes all platform targets. - The `all` target is the default target. Running `make` with no arguments is the same as running `make all`. - The `*-debug` targets build the binaries using the **_Debug_** configuration. -- The `install` target will copy the most recently built `MoltenVK.xcframework` into the - `/Library/Frameworks` folder of your computer. Since `/Library/Frameworks` is protected, +- The `install` target will copy the most recently built `MoltenVK.xcframework` into the + `/Library/Frameworks` folder of your computer. Since `/Library/Frameworks` is protected, you will generally need to run it as `sudo make install` and enter your password. The `install` target just installs the built framework, it does not first build the framework. You will first need to at least run `make macos` first. -The `make` targets all require that *Xcode* is installed on your system. +The `make` targets all require that *Xcode* is installed on your system. -Building from the command line creates the same `Package` folder structure described above when +Building from the command line creates the same `Package` folder structure described above when building from within *Xcode*. -When building from the command line, you can set any of the build settings documented -in the `MoltenVK_Configuration_Parameters.md` file, by passing them in the command line, +When building from the command line, you can set any of the build settings documented +in the `MoltenVK_Configuration_Parameters.md` file, by passing them in the command line, as in the following examples: make MVK_CONFIG_LOG_LEVEL=0 @@ -301,7 +301,7 @@ You can optionally build MoltenVK with the Vulkan API static call symbols (`vk*` to avoid library linking conflicts when bound to a Vulkan Loader that also exports identical symbols. To do so, when building MoltenVK, set the build setting `MVK_HIDE_VULKAN_SYMBOLS=1`. -This build setting can be set in the `MoltenVK.xcodeproj` *Xcode* project, +This build setting can be set in the `MoltenVK.xcodeproj` *Xcode* project, or it can be included in any of the `make` build commands. For example: make MVK_HIDE_VULKAN_SYMBOLS=1 @@ -316,14 +316,14 @@ or Running **MoltenVK** Demo Applications -------------------------------------- -Once you have compiled and built the **MoltenVK** runtime distribution package from this **MoltenVK** repository, -as described in the [Building **MoltenVK**](#building) section, you can explore how **MoltenVK** provides *Vulkan* +Once you have compiled and built the **MoltenVK** runtime distribution package from this **MoltenVK** repository, +as described in the [Building **MoltenVK**](#building) section, you can explore how **MoltenVK** provides *Vulkan* support on *macOS*, *iOS*, and *tvOS* by investigating and running the demo application that is included in **MoltenVK**. The **MoltenVK** _Cube_ demo app is located in the `Demos` folder. The demo app is available as an *Xcode* project. To review and run the included demo app, open the `Demos/Demos.xcworkspace` workspace in *Xcode*. -Please read the [`Demos/README.md`](Demos/README.md) document for a description and instructions for running the +Please read the [`Demos/README.md`](Demos/README.md) document for a description and instructions for running the included *Cube* demo app, and for external links to more sophisticated demo applications that can be run on **MoltenVK**. @@ -332,12 +332,12 @@ included *Cube* demo app, and for external links to more sophisticated demo appl Using **MoltenVK** in Your Application -------------------------------------- -Once you have compiled and built the **MoltenVK** runtime distribution package from this **MoltenVK** repository, -as described in the [Building **MoltenVK**](#building) section, follow the instructions in the Installation -section of the [`Docs/MoltenVK_Runtime_UserGuide.md`](Docs/MoltenVK_Runtime_UserGuide.md#install) document +Once you have compiled and built the **MoltenVK** runtime distribution package from this **MoltenVK** repository, +as described in the [Building **MoltenVK**](#building) section, follow the instructions in the Installation +section of the [`Docs/MoltenVK_Runtime_UserGuide.md`](Docs/MoltenVK_Runtime_UserGuide.md#install) document in the `Docs` directory, to link the **MoltenVK** libraries and frameworks to your application. -The runtime distribution package in the `Package/Latest` directory is a stand-alone package, and you can copy +The runtime distribution package in the `Package/Latest` directory is a stand-alone package, and you can copy the contents of that directory out of this **MoltenVK** repository into your own application building environment. @@ -346,38 +346,38 @@ the contents of that directory out of this **MoltenVK** repository into your own **MoltenVK** and *Vulkan* Compliance ------------------------------------ -**MoltenVK** is designed to be an implementation of a *Vulkan 1.2* subset that runs on *macOS*, *iOS*, +**MoltenVK** is designed to be an implementation of a *Vulkan 1.2* subset that runs on *macOS*, *iOS*, *tvOS*, and *visionOS* platforms by mapping *Vulkan* capability to native *Metal* capability. -The fundamental design and development goal of **MoltenVK** is to provide this capability in a way that +The fundamental design and development goal of **MoltenVK** is to provide this capability in a way that is both maximally compliant with the *Vulkan 1.2* specification, and maximally performant. -Such compliance and performance is inherently affected by the capability available through *Metal*, -as the native graphics driver on *macOS*, *iOS*, *tvOS*, and *visionOS* platforms. *Vulkan* +Such compliance and performance is inherently affected by the capability available through *Metal*, +as the native graphics driver on *macOS*, *iOS*, *tvOS*, and *visionOS* platforms. *Vulkan* compliance may fall into one of the following categories: - Direct mapping between *Vulkan* capabilities and *Metal* capabilities. Within **MoltenVK**, the vast - majority of *Vulkan* capability is the result of this type of direct mapping. - + majority of *Vulkan* capability is the result of this type of direct mapping. + - Synthesized compliance through alternate implementation. A small amount of capability is provided using this mechanism, such as via an extra render or compute shader stage. - Non-compliance. This appears where the capabilities of *Vulkan* and *Metal* are sufficiently different, that - there is no practical, or reasonably performant, mechanism to implement a *Vulkan* capability in *Metal*. - Because of design differences between *Vulkan* and *Metal*, a very small amount of capability falls into this - category, and at present **MoltenVK** is **_not_** fully compliant with the *Vulkan* specification. A list of - known limitations is documented in the [`MoltenVK_Runtime_UserGuide.md`](Docs/MoltenVK_Runtime_UserGuide.md#limitations) + there is no practical, or reasonably performant, mechanism to implement a *Vulkan* capability in *Metal*. + Because of design differences between *Vulkan* and *Metal*, a very small amount of capability falls into this + category, and at present **MoltenVK** is **_not_** fully compliant with the *Vulkan* specification. A list of + known limitations is documented in the [`MoltenVK_Runtime_UserGuide.md`](Docs/MoltenVK_Runtime_UserGuide.md#limitations) document in the `Docs` directory. -The **MoltenVK** development team welcomes you to [post Issues](https://github.com/KhronosGroup/MoltenVK/issues) -of non-compliance, and engage in discussions about how compliance can be improved, and non-compliant features can +The **MoltenVK** development team welcomes you to [post Issues](https://github.com/KhronosGroup/MoltenVK/issues) +of non-compliance, and engage in discussions about how compliance can be improved, and non-compliant features can be implemented or worked around. -**MoltenVK** is a key component of the -[*Khronos Vulkan Portability Initiative*](https://www.khronos.org/vulkan/portability-initiative), -whose intention is to provide specifications, resources, and tools to allow developers to understand and design -their *Vulkan* apps for maximum cross-platform compatibility and portability, including on platforms, such as -*macOS*, *iOS*, *tvOS*, and *visionOS*, where a native *Vulkan* driver is not available. +**MoltenVK** is a key component of the +[*Khronos Vulkan Portability Initiative*](https://www.khronos.org/vulkan/portability-initiative), +whose intention is to provide specifications, resources, and tools to allow developers to understand and design +their *Vulkan* apps for maximum cross-platform compatibility and portability, including on platforms, such as +*macOS*, *iOS*, *tvOS*, and *visionOS*, where a native *Vulkan* driver is not available. @@ -386,19 +386,19 @@ their *Vulkan* apps for maximum cross-platform compatibility and portability, in Getting Support ---------------- -- If you have a question about using **MoltenVK**, you can ask it in - [*MoltenVK Discussions*](https://github.com/KhronosGroup/MoltenVK/discussions). +- If you have a question about using **MoltenVK**, you can ask it in + [*MoltenVK Discussions*](https://github.com/KhronosGroup/MoltenVK/discussions). This forum is monitored by **MoltenVK** contributors and users. -- If you encounter an issue with the behavior of **MoltenVK**, or want to request an enhancement, +- If you encounter an issue with the behavior of **MoltenVK**, or want to request an enhancement, you can report it in the [*MoltenVK Issues List*](https://github.com/KhronosGroup/MoltenVK/issues). -- If you encounter an issue with the *Vulkan SDK*, including the *Validation Layers*, you can report it in the +- If you encounter an issue with the *Vulkan SDK*, including the *Validation Layers*, you can report it in the [*Vulkan SDK Issues List*](https://vulkan.lunarg.com/issue/home). - If you explore **MoltenVK** and determine that it does not meet your requirements at this time, we would appreciate - hearing why that is so, in [*MoltenVK Discussions*](https://github.com/KhronosGroup/MoltenVK/discussions). - The goal of **MoltenVK** is to increase the value of *Vulkan* as a true cross-platform ecosystem, by providing + hearing why that is so, in [*MoltenVK Discussions*](https://github.com/KhronosGroup/MoltenVK/discussions). + The goal of **MoltenVK** is to increase the value of *Vulkan* as a true cross-platform ecosystem, by providing *Vulkan* on *Apple* platforms. Hearing why this is currently not working for you will help us in that goal. @@ -408,52 +408,52 @@ Getting Support Contributing to **MoltenVK** Development ---------------------------------------- -As a public open-source project, **MoltenVK** benefits from code contributions from a wide range of developers, +As a public open-source project, **MoltenVK** benefits from code contributions from a wide range of developers, and we encourage you to get involved and contribute code to this **MoltenVK** repository. -To contribute your code, submit a [Pull Request](https://github.com/KhronosGroup/MoltenVK/pulls) -to this repository. The first time you do this, you will be asked to agree to the **MoltenVK** +To contribute your code, submit a [Pull Request](https://github.com/KhronosGroup/MoltenVK/pulls) +to this repository. The first time you do this, you will be asked to agree to the **MoltenVK** [Contributor License Agreement](https://cla-assistant.io/KhronosGroup/MoltenVK). ### Licensing -**MoltenVK** is licensed under the Apache 2.0 license. All new source code files should include a -copyright header at the top, containing your authorship copyright and the Apache 2.0 licensing stub. +**MoltenVK** is licensed under the Apache 2.0 license. All new source code files should include a +copyright header at the top, containing your authorship copyright and the Apache 2.0 licensing stub. You may copy the text from an existing source code file as a template. The Apache 2.0 license guarantees that code in the **MoltenVK** repository is free of Intellectual Property -encumbrances. In submitting code to this repository, you are agreeing that the code is free of any Intellectual -Property claims. +encumbrances. In submitting code to this repository, you are agreeing that the code is free of any Intellectual +Property claims. ### *Vulkan* Validation -Despite running on top of *Metal*, **MoltenVK** operates as a *Vulkan* core layer. As such, as per the -error handling guidelines of the [*Vulkan* specification](https://www.khronos.org/registry/vulkan/specs/1.2/html/vkspec.html#fundamentals-errors), **MoltenVK** should not perform *Vulkan* validation. When adding functionality +Despite running on top of *Metal*, **MoltenVK** operates as a *Vulkan* core layer. As such, as per the +error handling guidelines of the [*Vulkan* specification](https://www.khronos.org/registry/vulkan/specs/1.2/html/vkspec.html#fundamentals-errors), **MoltenVK** should not perform *Vulkan* validation. When adding functionality to **MoltenVK**, avoid adding unnecessary validation code. -Validation and error generation **_is_** appropriate within **MoltenVK** in cases where **MoltenVK** deviates -from behavior defined by the *Vulkan* specification. This most commonly occurs when required behavior cannot +Validation and error generation **_is_** appropriate within **MoltenVK** in cases where **MoltenVK** deviates +from behavior defined by the *Vulkan* specification. This most commonly occurs when required behavior cannot be mapped to functionality available within *Metal*. In that situation, it is important to provide feedback to the application developer to that effect, by performing the necessary validation, and reporting an error. -Currently, there is some excess *Vulkan* validation and error reporting code within **MoltenVK**, added before -this guideline was introduced. You are encouraged to remove such code if you encounter it while performing other -**MoltenVK** development. Do not remove validation and error reporting code that is covering a deviation in +Currently, there is some excess *Vulkan* validation and error reporting code within **MoltenVK**, added before +this guideline was introduced. You are encouraged to remove such code if you encounter it while performing other +**MoltenVK** development. Do not remove validation and error reporting code that is covering a deviation in behavior from the *Vulkan* specification. ### Memory Management -*Metal*, and other *Objective-C* objects in *Apple's SDK* frameworks, use reference counting for memory management. -As a contributor to **MoltenVK**, when instantiating *Objective-C* objects, it is important that you do not rely on -the app providing *autorelease pools* to do memory management for you. Because many *Vulkan* games and apps may be +*Metal*, and other *Objective-C* objects in *Apple's SDK* frameworks, use reference counting for memory management. +As a contributor to **MoltenVK**, when instantiating *Objective-C* objects, it is important that you do not rely on +the app providing *autorelease pools* to do memory management for you. Because many *Vulkan* games and apps may be ported from other platforms, they will often not automatically include autorelease pools in their threading models. -As a contributor to **MoltenVK**, avoid the use of the *Metal* `autorelease` method, or any object *Metal* creation -methods that imply internal use of `autorelease`, (eg- `[NSString stringWithFormat: ]`, etc). Instead, favor object -creation methods that return a retained object (eg- `[[NSString alloc] initWithFormat: ]`, etc), and manually track +As a contributor to **MoltenVK**, avoid the use of the *Metal* `autorelease` method, or any object *Metal* creation +methods that imply internal use of `autorelease`, (eg- `[NSString stringWithFormat: ]`, etc). Instead, favor object +creation methods that return a retained object (eg- `[[NSString alloc] initWithFormat: ]`, etc), and manually track and release those objects. If you need to use autoreleased objects, wrap your code in an `@autoreleasepool {...}` block.