Merge pull request #1691 from billhollings/VK_KHR_shader_float_controls

Add support for the VK_KHR_shader_float_controls.
diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md
index ad840f5..a8433a4 100644
--- a/Docs/MoltenVK_Runtime_UserGuide.md
+++ b/Docs/MoltenVK_Runtime_UserGuide.md
@@ -289,6 +289,7 @@
 - `VK_KHR_sampler_ycbcr_conversion`
 - `VK_KHR_separate_depth_stencil_layouts`
 - `VK_KHR_shader_draw_parameters`
+- `VK_KHR_shader_float_controls`
 - `VK_KHR_shader_float16_int8`
 - `VK_KHR_shader_subgroup_extended_types` *(requires Metal 2.1 on Mac or Metal 2.2 and Apple family 4 on iOS)*
 - `VK_KHR_storage_buffer_storage_class`
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index b54e5ab..f68de67 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -18,6 +18,8 @@
 
 Released TBD
 
+- Add support for extensions:
+	- `VK_KHR_shader_float_controls`
 - Fix occassional crash from retention of `MVKSwapchain` for future drawable presentations.
 - Add `MVK_USE_CEREAL` build setting to avoid use of Cereal external library (for pipeline caching).
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 763e639..bd42b74 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -429,23 +429,23 @@
 	supportedProps12.conformanceVersion.minor = 0;
 	supportedProps12.conformanceVersion.subminor = 0;
 	supportedProps12.conformanceVersion.patch = 0;
-	supportedProps12.denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY;	// VK_KHR_shader_float_controls
-	supportedProps12.roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY;		// VK_KHR_shader_float_controls
-	supportedProps12.shaderSignedZeroInfNanPreserveFloat16 = false;										// VK_KHR_shader_float_controls
-	supportedProps12.shaderSignedZeroInfNanPreserveFloat32 = false;										// VK_KHR_shader_float_controls
-	supportedProps12.shaderSignedZeroInfNanPreserveFloat64 = false;										// VK_KHR_shader_float_controls
-	supportedProps12.shaderDenormPreserveFloat16 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderDenormPreserveFloat32 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderDenormPreserveFloat64 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderDenormFlushToZeroFloat16 = false;											// VK_KHR_shader_float_controls
-	supportedProps12.shaderDenormFlushToZeroFloat32 = false;											// VK_KHR_shader_float_controls
-	supportedProps12.shaderDenormFlushToZeroFloat64 = false;											// VK_KHR_shader_float_controls
-	supportedProps12.shaderRoundingModeRTEFloat16 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderRoundingModeRTEFloat32 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderRoundingModeRTEFloat64 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderRoundingModeRTZFloat16 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderRoundingModeRTZFloat32 = false;												// VK_KHR_shader_float_controls
-	supportedProps12.shaderRoundingModeRTZFloat64 = false;												// VK_KHR_shader_float_controls
+	supportedProps12.denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
+	supportedProps12.roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
+	supportedProps12.shaderSignedZeroInfNanPreserveFloat16 = true;
+	supportedProps12.shaderSignedZeroInfNanPreserveFloat32 = true;
+	supportedProps12.shaderSignedZeroInfNanPreserveFloat64 = false;
+	supportedProps12.shaderDenormPreserveFloat16 = false;
+	supportedProps12.shaderDenormPreserveFloat32 = false;
+	supportedProps12.shaderDenormPreserveFloat64 = false;
+	supportedProps12.shaderDenormFlushToZeroFloat16 = false;
+	supportedProps12.shaderDenormFlushToZeroFloat32 = false;
+	supportedProps12.shaderDenormFlushToZeroFloat64 = false;
+	supportedProps12.shaderRoundingModeRTEFloat16 = false;
+	supportedProps12.shaderRoundingModeRTEFloat32 = false;
+	supportedProps12.shaderRoundingModeRTEFloat64 = false;
+	supportedProps12.shaderRoundingModeRTZFloat16 = false;
+	supportedProps12.shaderRoundingModeRTZFloat32 = false;
+	supportedProps12.shaderRoundingModeRTZFloat64 = false;
 	supportedProps12.maxUpdateAfterBindDescriptorsInAllPools				= kMVKUndefinedLargeUInt32;
 	supportedProps12.shaderUniformBufferArrayNonUniformIndexingNative		= false;
 	supportedProps12.shaderSampledImageArrayNonUniformIndexingNative		= _metalFeatures.arrayOfTextures && _metalFeatures.arrayOfSamplers;
@@ -612,6 +612,27 @@
 				texelBuffAlignProps->pNext = pNext;
 				break;
 			}
+			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES: {
+				auto* floatControlsProperties = (VkPhysicalDeviceFloatControlsProperties*)next;
+				floatControlsProperties->denormBehaviorIndependence = supportedProps12.denormBehaviorIndependence;
+				floatControlsProperties->roundingModeIndependence = supportedProps12.roundingModeIndependence;
+				floatControlsProperties->shaderSignedZeroInfNanPreserveFloat16 = supportedProps12.shaderSignedZeroInfNanPreserveFloat16;
+				floatControlsProperties->shaderSignedZeroInfNanPreserveFloat32 = supportedProps12.shaderSignedZeroInfNanPreserveFloat32;
+				floatControlsProperties->shaderSignedZeroInfNanPreserveFloat64 = supportedProps12.shaderSignedZeroInfNanPreserveFloat64;
+				floatControlsProperties->shaderDenormPreserveFloat16 = supportedProps12.shaderDenormPreserveFloat16;
+				floatControlsProperties->shaderDenormPreserveFloat32 = supportedProps12.shaderDenormPreserveFloat32;
+				floatControlsProperties->shaderDenormPreserveFloat64 = supportedProps12.shaderDenormPreserveFloat64;
+				floatControlsProperties->shaderDenormFlushToZeroFloat16 = supportedProps12.shaderDenormFlushToZeroFloat16;
+				floatControlsProperties->shaderDenormFlushToZeroFloat32 = supportedProps12.shaderDenormFlushToZeroFloat32;
+				floatControlsProperties->shaderDenormFlushToZeroFloat64 = supportedProps12.shaderDenormFlushToZeroFloat64;
+				floatControlsProperties->shaderRoundingModeRTEFloat16 = supportedProps12.shaderRoundingModeRTEFloat16;
+				floatControlsProperties->shaderRoundingModeRTEFloat32 = supportedProps12.shaderRoundingModeRTEFloat32;
+				floatControlsProperties->shaderRoundingModeRTEFloat64 = supportedProps12.shaderRoundingModeRTEFloat64;
+				floatControlsProperties->shaderRoundingModeRTZFloat16 = supportedProps12.shaderRoundingModeRTZFloat16;
+				floatControlsProperties->shaderRoundingModeRTZFloat32 = supportedProps12.shaderRoundingModeRTZFloat32;
+				floatControlsProperties->shaderRoundingModeRTZFloat64 = supportedProps12.shaderRoundingModeRTZFloat64;
+				break;
+			}
             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_PROPERTIES_KHR: {
                 auto* barycentricProperties = (VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR*)next;
                 barycentricProperties->triStripVertexOrderIndependentOfProvokingVertex = false;
@@ -4568,10 +4589,9 @@
 }
 
 void MVKDevice::enableExtensions(const VkDeviceCreateInfo* pCreateInfo) {
-	MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions;
-	setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount,
-												  pCreateInfo->ppEnabledExtensionNames,
-												  &_physicalDevice->_supportedExtensions));
+	setConfigurationResult(_enabledExtensions.enable(pCreateInfo->enabledExtensionCount,
+													 pCreateInfo->ppEnabledExtensionNames,
+													 &_physicalDevice->_supportedExtensions));
 }
 
 // Create the command queues
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
index f748d56..40b484f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
@@ -447,9 +447,11 @@
 	compile(lock, ^{
 		auto mtlDev = _owner->getMTLDevice();
 		@synchronized (mtlDev) {
+			auto mtlCompileOptions = _owner->getDevice()->getMTLCompileOptions(shaderConversionResults.entryPoint.supportsFastMath,
+																			   shaderConversionResults.isPositionInvariant);
+			MVKLogInfoIf(mvkConfig().debugMode, "Compiling Metal shader%s.", mtlCompileOptions.fastMathEnabled ? " with FastMath enabled" : "");
 			[mtlDev newLibraryWithSource: mslSourceCode
-								 options: _owner->getDevice()->getMTLCompileOptions(shaderConversionResults.entryPoint.supportsFastMath,
-																					shaderConversionResults.isPositionInvariant)
+								 options: mtlCompileOptions
 					   completionHandler: ^(id<MTLLibrary> mtlLib, NSError* error) {
 						   bool isLate = compileComplete(mtlLib, error);
 						   if (isLate) { destroy(); }
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
index 604a8cf..5192947 100644
--- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
@@ -76,6 +76,7 @@
 MVK_EXTENSION(KHR_sampler_ycbcr_conversion,        KHR_SAMPLER_YCBCR_CONVERSION,         DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_separate_depth_stencil_layouts,  KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS,   DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_shader_draw_parameters,          KHR_SHADER_DRAW_PARAMETERS,           DEVICE,   10.11,  8.0)
+MVK_EXTENSION(KHR_shader_float_controls,           KHR_SHADER_FLOAT_CONTROLS,            DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_shader_float16_int8,             KHR_SHADER_FLOAT16_INT8,              DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_shader_subgroup_extended_types,  KHR_SHADER_SUBGROUP_EXTENDED_TYPES,   DEVICE,   10.14, 13.0)
 MVK_EXTENSION(KHR_storage_buffer_storage_class,    KHR_STORAGE_BUFFER_STORAGE_CLASS,     DEVICE,   10.11,  8.0)
diff --git a/Scripts/runcts b/Scripts/runcts
index acc99d1..f408a75 100755
--- a/Scripts/runcts
+++ b/Scripts/runcts
@@ -105,7 +105,7 @@
 # Additional MoltenVK configuration can be set here by 
 # editing below, or can be set before calling this script.
 export MVK_CONFIG_RESUME_LOST_DEVICE=1
-export MVK_CONFIG_FAST_MATH_ENABLED=0
+export MVK_CONFIG_FAST_MATH_ENABLED=1
 export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=0
 export MVK_CONFIG_FORCE_LOW_POWER_GPU=0