Merge pull request #1793 from billhollings/fix-fastmath-regression

Fix app performance regression triggered by the previous introduction of VK_KHR_shader_float_controls.
This commit is contained in:
Bill Hollings 2022-12-08 11:34:25 -05:00 committed by GitHub
commit c0c00d78f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 13 deletions

View File

@ -20,6 +20,7 @@ Released TBD
- Fix crash on descriptor update with out-of-bounds descriptor count data.
- Fix Metal buffer index binding overrides for push constants and attachment clearing.
- Fix app performance regression triggered by the previous introduction of `VK_KHR_shader_float_controls`.
- Work around `MTLCounterSet` crash on additional Intel Iris Plus Graphics devices.
- Fix mistaken YCBCR format support indication.
- Document new linkage model used by *Xcode 14* and later, and how to link **MoltenVK**

View File

@ -122,6 +122,14 @@ typedef enum MVKPrefillMetalCommandBuffersStyle {
MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS_STYLE_MAX_ENUM = 0x7FFFFFFF
} MVKPrefillMetalCommandBuffersStyle;
/** Identifies when Metal shaders will be compiled with the fast math option. */
typedef enum MVKConfigFastMath {
MVK_CONFIG_FAST_MATH_NEVER = 0, /**< Metal shaders will never be compiled with the fast math option. */
MVK_CONFIG_FAST_MATH_ALWAYS = 1, /**< Metal shaders will always be compiled with the fast math option. */
MVK_CONFIG_FAST_MATH_ON_DEMAND = 2, /**< Metal shaders will be compiled with the fast math option, unless the shader includes execution modes that require it to be compiled without fast math. */
MVK_CONFIG_FAST_MATH_MAX_ENUM = 0x7FFFFFFF
} MVKConfigFastMath;
/**
* MoltenVK configuration settings.
*
@ -540,18 +548,30 @@ typedef struct {
uint32_t defaultGPUCaptureScopeQueueIndex;
/**
* Corresponds to the fastMathEnabled property of MTLCompileOptions.
* Setting it may cause the Metal Compiler to optimize floating point operations
* in ways that may violate the IEEE 754 standard.
* Identifies when Metal shaders will be compiled with the Metal fastMathEnabled property
* enabled. For shaders compiled with the Metal fastMathEnabled property enabled, shader
* floating point math is significantly faster, but it may cause the Metal Compiler to
* optimize floating point operations in ways that may violate the IEEE 754 standard.
*
* Must be changed before creating a VkDevice, for the change to take effect.
* 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, by setting the value of this property to MVK_CONFIG_FAST_MATH_ALWAYS,
* 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 MVK_CONFIG_FAST_MATH_ON_DEMAND, so that fast math will
* be disabled when compiling shaders that request capabilities such as SignedZeroInfNanPreserve.
*
* The value of this parameter may be changed at any time during application runtime,
* and the changed value will be applied to future Metal shader compilations.
*
* The initial value or this parameter is set by the
* MVK_CONFIG_FAST_MATH_ENABLED
* runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, the value of this parameter defaults to true.
* If neither is set, the value of this parameter defaults to MVK_CONFIG_FAST_MATH_ALWAYS.
*/
VkBool32 fastMathEnabled;
MVKConfigFastMath fastMathEnabled;
/**
* Controls the level of logging performned by MoltenVK.

View File

@ -715,12 +715,12 @@ public:
/**
* Returns an autoreleased options object to be used when compiling MSL shaders.
* The useFastMath parameter is and-combined with MVKConfiguration::fastMathEnabled
* The requestFastMath parameter is combined with the value of MVKConfiguration::fastMathEnabled
* to determine whether to enable fast math optimizations in the compiled shader.
* The preserveInvariance parameter indicates that the shader requires the position
* output invariance across invocations (typically for the position output).
*/
MTLCompileOptions* getMTLCompileOptions(bool useFastMath = true, bool preserveInvariance = false);
MTLCompileOptions* getMTLCompileOptions(bool requestFastMath = true, bool preserveInvariance = false);
/** Returns the Metal vertex buffer index to use for the specified vertex attribute binding number. */
uint32_t getMetalBufferIndexForVertexAttributeBinding(uint32_t binding);

View File

@ -4255,10 +4255,11 @@ id<MTLBuffer> MVKDevice::getDummyBlitMTLBuffer() {
return _dummyBlitMTLBuffer;
}
MTLCompileOptions* MVKDevice::getMTLCompileOptions(bool useFastMath, bool preserveInvariance) {
MTLCompileOptions* MVKDevice::getMTLCompileOptions(bool requestFastMath, bool preserveInvariance) {
MTLCompileOptions* mtlCompOpt = [MTLCompileOptions new];
mtlCompOpt.languageVersion = _pMetalFeatures->mslVersionEnum;
mtlCompOpt.fastMathEnabled = useFastMath && mvkConfig().fastMathEnabled;
mtlCompOpt.fastMathEnabled = (mvkConfig().fastMathEnabled == MVK_CONFIG_FAST_MATH_ALWAYS ||
(mvkConfig().fastMathEnabled == MVK_CONFIG_FAST_MATH_ON_DEMAND && requestFastMath));
#if MVK_XCODE_12
if ([mtlCompOpt respondsToSelector: @selector(setPreserveInvariance:)]) {
[mtlCompOpt setPreserveInvariance: preserveInvariance];

View File

@ -45,7 +45,7 @@ static void mvkInitConfigFromEnvVars() {
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.fullImageViewSwizzle, MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.defaultGPUCaptureScopeQueueFamilyIndex, MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.defaultGPUCaptureScopeQueueIndex, MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_INDEX);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.fastMathEnabled, MVK_CONFIG_FAST_MATH_ENABLED);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.fastMathEnabled, MVK_CONFIG_FAST_MATH_ENABLED);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.logLevel, MVK_CONFIG_LOG_LEVEL);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.traceVulkanCalls, MVK_CONFIG_TRACE_VULKAN_CALLS);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.forceLowPowerGPU, MVK_CONFIG_FORCE_LOW_POWER_GPU);

View File

@ -173,9 +173,9 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
# define MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE 0
#endif
/** Set the fastMathEnabled Metal Compiler option. Enabled by default. */
/** Set the fastMathEnabled Metal Compiler option. Set to always use fast math by default. */
#ifndef MVK_CONFIG_FAST_MATH_ENABLED
# define MVK_CONFIG_FAST_MATH_ENABLED 1
# define MVK_CONFIG_FAST_MATH_ENABLED MVK_CONFIG_FAST_MATH_ALWAYS
#endif
/** Set the logging level: */