Fix incorrect translation of clear color values on Apple Silicon.

The same set of CTS tests either fails or passes on different GPUs
based on whether or not we adjust float clear colors by one ULP.
Add MVKFloatRounding enum.
Add MVKPhysicalDeviceMetalFeatures::clearColorFloatRounding.
Disable ULP adjustment for clear colors on Apple Silicon.
For consistency and to simplify bookkeepping, calculate
clear color ULP adjustment from bit width of format component.
Update MoltenVK version to 1.1.5.
Update VK_MVK_MOLTENVK_SPEC_VERSION to 32.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 374bd2d..e7daeb8 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -13,6 +13,15 @@
 
 
 
+MoltenVK 1.1.5
+--------------
+
+Released TBD
+
+- Fix incorrect translation of clear color values on Apple Silicon.
+
+
+
 MoltenVK 1.1.4
 --------------
 
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index c77d52d..149dd21 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -50,12 +50,12 @@
  */
 #define MVK_VERSION_MAJOR   1
 #define MVK_VERSION_MINOR   1
-#define MVK_VERSION_PATCH   4
+#define MVK_VERSION_PATCH   5
 
 #define MVK_MAKE_VERSION(major, minor, patch)    (((major) * 10000) + ((minor) * 100) + (patch))
 #define MVK_VERSION     MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
 
-#define VK_MVK_MOLTENVK_SPEC_VERSION            31
+#define VK_MVK_MOLTENVK_SPEC_VERSION            32
 #define VK_MVK_MOLTENVK_EXTENSION_NAME          "VK_MVK_moltenvk"
 
 /** Identifies the level of logging MoltenVK should be limited to outputting. */
@@ -827,6 +827,14 @@
 
 } MVKConfiguration;
 
+/** Identifies the type of rounding Metal uses for float to integer conversions in particular calculatons. */
+typedef enum MVKFloatRounding {
+	MVK_FLOAT_ROUNDING_NEAREST     = 0,	 /**< Metal rounds to nearest. */
+	MVK_FLOAT_ROUNDING_UP          = 1,	 /**< Metal rounds towards positive infinity. */
+	MVK_FLOAT_ROUNDING_DOWN        = 2,	 /**< Metal rounds towards negative infinity. */
+	MVK_FLOAT_ROUNDING_UP_MAX_ENUM = 0x7FFFFFFF
+} MVKFloatRounding;
+
 /**
  * Features provided by the current implementation of Metal on the current device. You can
  * retrieve a copy of this structure using the vkGetPhysicalDeviceMetalFeaturesMVK() function.
@@ -906,6 +914,7 @@
     VkBool32 tileBasedDeferredRendering;        /**< If true, this device uses tile-based deferred rendering. */
 	VkBool32 argumentBuffers;					/**< If true, Metal argument buffers are supported. */
 	VkBool32 descriptorSetArgumentBuffers;		/**< If true, a Metal argument buffer can be assigned to a descriptor set, and used on any pipeline and pipeline stage. If false, a different Metal argument buffer must be used for each pipeline-stage/descriptor-set combination. */
+	MVKFloatRounding clearColorFloatRounding;	/**< Identifies the type of rounding Metal uses for MTLClearColor float to integer conversions. */
 } MVKPhysicalDeviceMetalFeatures;
 
 /** MoltenVK performance of a particular type of activity. */
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index ac1dbfd..b8a83e8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -1203,6 +1203,7 @@
     _metalFeatures.maxPerStageDynamicMTLBufferCount = _metalFeatures.maxPerStageBufferCount;
 	_metalFeatures.renderLinearTextures = true;
 	_metalFeatures.tileBasedDeferredRendering = true;
+	_metalFeatures.clearColorFloatRounding = MVK_FLOAT_ROUNDING_NEAREST;
 
     if (supportsMTLFeatureSet(tvOS_GPUFamily1_v2)) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion1_2;
@@ -1271,6 +1272,7 @@
     _metalFeatures.sharedLinearTextures = true;
 	_metalFeatures.renderLinearTextures = true;
 	_metalFeatures.tileBasedDeferredRendering = true;
+	_metalFeatures.clearColorFloatRounding = MVK_FLOAT_ROUNDING_NEAREST;
 
     if (supportsMTLFeatureSet(iOS_GPUFamily1_v2)) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion1_1;
@@ -1376,6 +1378,7 @@
 	_metalFeatures.maxTextureDimension = (16 * KIBI);
 	_metalFeatures.depthSampleCompare = true;
 	_metalFeatures.samplerMirrorClampToEdge = true;
+	_metalFeatures.clearColorFloatRounding = MVK_FLOAT_ROUNDING_DOWN;
 
     if (supportsMTLFeatureSet(macOS_GPUFamily1_v2)) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion1_2;
@@ -1434,6 +1437,8 @@
 	}
 
 #if MVK_MACOS_APPLE_SILICON
+	_metalFeatures.clearColorFloatRounding = MVK_FLOAT_ROUNDING_NEAREST;
+
 	if ( mvkOSVersionIsAtLeast(10.16) ) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion2_3;
 		if (supportsMTLGPUFamily(Apple5)) {
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
index 22117dc..c40a156 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
@@ -467,100 +467,108 @@
 			mtlClr.green	= vkClearValue.color.float32[1];
 			mtlClr.blue		= vkClearValue.color.float32[2];
 			mtlClr.alpha	= vkClearValue.color.float32[3];
-			// For normalized formats, increment the clear value by half the minimum delta
-			// (i.e. 1/(2*(2**component_size - 1))), to force Metal to round up. This should
-			// fix some problems with clear values being off by one.
-#define OFFSET_UNORM(COLOR, DENOM) if (mtlClr.COLOR > 0.0 && mtlClr.COLOR < 1.0) { mtlClr.COLOR += 1.0/DENOM; }
-#define OFFSET_SNORM(COLOR, DENOM) if (mtlClr.COLOR > -1.0 && mtlClr.COLOR < 1.0) { mtlClr.COLOR += 1.0/DENOM; }
-			switch (vkFormat) {
-				case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
-					OFFSET_UNORM(red, 30.0)
-					OFFSET_UNORM(green, 30.0)
-					OFFSET_UNORM(blue, 30.0)
-					OFFSET_UNORM(alpha, 30.0);
-					break;
-				case VK_FORMAT_R5G6B5_UNORM_PACK16:
-					OFFSET_UNORM(red, 62.0)
-					OFFSET_UNORM(green, 126.0)
-					OFFSET_UNORM(blue, 62.0)
-					break;
-				case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
-				case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
-					OFFSET_UNORM(red, 62.0)
-					OFFSET_UNORM(green, 62.0)
-					OFFSET_UNORM(blue, 62.0)
-					break;
-				case VK_FORMAT_R8_UNORM:
-				case VK_FORMAT_R8_SRGB:
-					OFFSET_UNORM(red, 510.0)
-					break;
-				case VK_FORMAT_R8_SNORM:
-					OFFSET_SNORM(red, 254.0)
-					break;
-				case VK_FORMAT_R8G8_UNORM:
-				case VK_FORMAT_R8G8_SRGB:
-					OFFSET_UNORM(red, 510.0)
-					OFFSET_UNORM(green, 510.0)
-					break;
-				case VK_FORMAT_R8G8_SNORM:
-					OFFSET_SNORM(red, 254.0)
-					OFFSET_SNORM(green, 254.0)
-					break;
-				case VK_FORMAT_R8G8B8A8_UNORM:
-				case VK_FORMAT_R8G8B8A8_SRGB:
-				case VK_FORMAT_B8G8R8A8_UNORM:
-				case VK_FORMAT_B8G8R8A8_SRGB:
-				case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
-				case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
-					OFFSET_UNORM(red, 510.0)
-					OFFSET_UNORM(green, 510.0)
-					OFFSET_UNORM(blue, 510.0)
-					OFFSET_UNORM(alpha, 510.0)
-					break;
-				case VK_FORMAT_R8G8B8A8_SNORM:
-					OFFSET_SNORM(red, 254.0)
-					OFFSET_SNORM(green, 254.0)
-					OFFSET_SNORM(blue, 254.0)
-					OFFSET_SNORM(alpha, 254.0)
-					break;
-				case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
-				case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
-					OFFSET_UNORM(red, 2046.0)
-					OFFSET_UNORM(green, 2046.0)
-					OFFSET_UNORM(blue, 2046.0)
-					OFFSET_UNORM(alpha, 6.0)
-					break;
-				case VK_FORMAT_R16_UNORM:
-					OFFSET_UNORM(red, 131070.0)
-					break;
-				case VK_FORMAT_R16_SNORM:
-					OFFSET_SNORM(red, 65534.0)
-					break;
-				case VK_FORMAT_R16G16_UNORM:
-					OFFSET_UNORM(red, 131070.0)
-					OFFSET_UNORM(green, 131070.0)
-					break;
-				case VK_FORMAT_R16G16_SNORM:
-					OFFSET_SNORM(red, 65534.0)
-					OFFSET_SNORM(green, 65534.0)
-					break;
-				case VK_FORMAT_R16G16B16A16_UNORM:
-					OFFSET_UNORM(red, 131070.0)
-					OFFSET_UNORM(green, 131070.0)
-					OFFSET_UNORM(blue, 131070.0)
-					OFFSET_UNORM(alpha, 131070.0)
-					break;
-				case VK_FORMAT_R16G16B16A16_SNORM:
-					OFFSET_SNORM(red, 65534.0)
-					OFFSET_SNORM(green, 65534.0)
-					OFFSET_SNORM(blue, 65534.0)
-					OFFSET_SNORM(alpha, 65534.0)
-					break;
-				default:
-					break;
-			}
+
+			if (_physicalDevice && _physicalDevice->getMetalFeatures()->clearColorFloatRounding == MVK_FLOAT_ROUNDING_DOWN) {
+				// For normalized formats, increment the clear value by half the ULP
+				// (i.e. 1/(2*(2**component_size - 1))), to force Metal to round up.
+				// This should fix some problems with clear values being off by one ULP on some platforms.
+#define OFFSET_NORM(MIN_VAL, COLOR, BIT_WIDTH)  \
+	if (mtlClr.COLOR > (MIN_VAL) && mtlClr.COLOR < 1.0) {  \
+		mtlClr.COLOR += 1.0 / (2.0 * ((1U << (BIT_WIDTH)) - 1));  \
+	}
+#define OFFSET_UNORM(COLOR, BIT_WIDTH)    OFFSET_NORM(0.0, COLOR, BIT_WIDTH)
+#define OFFSET_SNORM(COLOR, BIT_WIDTH)    OFFSET_NORM(-1.0, COLOR, BIT_WIDTH - 1)
+				switch (vkFormat) {
+					case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
+						OFFSET_UNORM(red, 4)
+						OFFSET_UNORM(green, 4)
+						OFFSET_UNORM(blue, 4)
+						OFFSET_UNORM(alpha, 4)
+						break;
+					case VK_FORMAT_R5G6B5_UNORM_PACK16:
+						OFFSET_UNORM(red, 5)
+						OFFSET_UNORM(green, 6)
+						OFFSET_UNORM(blue, 5)
+						break;
+					case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
+					case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
+						OFFSET_UNORM(red, 5)
+						OFFSET_UNORM(green, 5)
+						OFFSET_UNORM(blue, 5)
+						break;
+					case VK_FORMAT_R8_UNORM:
+					case VK_FORMAT_R8_SRGB:
+						OFFSET_UNORM(red, 8)
+						break;
+					case VK_FORMAT_R8_SNORM:
+						OFFSET_SNORM(red, 8)
+						break;
+					case VK_FORMAT_R8G8_UNORM:
+					case VK_FORMAT_R8G8_SRGB:
+						OFFSET_UNORM(red, 8)
+						OFFSET_UNORM(green, 8)
+						break;
+					case VK_FORMAT_R8G8_SNORM:
+						OFFSET_SNORM(red, 8)
+						OFFSET_SNORM(green, 8)
+						break;
+					case VK_FORMAT_R8G8B8A8_UNORM:
+					case VK_FORMAT_R8G8B8A8_SRGB:
+					case VK_FORMAT_B8G8R8A8_UNORM:
+					case VK_FORMAT_B8G8R8A8_SRGB:
+					case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
+					case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
+						OFFSET_UNORM(red, 8)
+						OFFSET_UNORM(green, 8)
+						OFFSET_UNORM(blue, 8)
+						OFFSET_UNORM(alpha, 8)
+						break;
+					case VK_FORMAT_R8G8B8A8_SNORM:
+						OFFSET_SNORM(red, 8)
+						OFFSET_SNORM(green, 8)
+						OFFSET_SNORM(blue, 8)
+						OFFSET_SNORM(alpha, 8)
+						break;
+					case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+					case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+						OFFSET_UNORM(red, 10)
+						OFFSET_UNORM(green, 10)
+						OFFSET_UNORM(blue, 10)
+						OFFSET_UNORM(alpha, 2)
+						break;
+					case VK_FORMAT_R16_UNORM:
+						OFFSET_UNORM(red, 16)
+						break;
+					case VK_FORMAT_R16_SNORM:
+						OFFSET_SNORM(red, 16)
+						break;
+					case VK_FORMAT_R16G16_UNORM:
+						OFFSET_UNORM(red, 16)
+						OFFSET_UNORM(green, 16)
+						break;
+					case VK_FORMAT_R16G16_SNORM:
+						OFFSET_SNORM(red, 16)
+						OFFSET_SNORM(green, 16)
+						break;
+					case VK_FORMAT_R16G16B16A16_UNORM:
+						OFFSET_UNORM(red, 16)
+						OFFSET_UNORM(green, 16)
+						OFFSET_UNORM(blue, 16)
+						OFFSET_UNORM(alpha, 16)
+						break;
+					case VK_FORMAT_R16G16B16A16_SNORM:
+						OFFSET_SNORM(red, 16)
+						OFFSET_SNORM(green, 16)
+						OFFSET_SNORM(blue, 16)
+						OFFSET_SNORM(alpha, 16)
+						break;
+					default:
+						break;
+				}
 #undef OFFSET_UNORM
 #undef OFFSET_SNORM
+#undef OFFSET_NORM
+			}
 			break;
 		case kMVKFormatColorUInt8:
 		case kMVKFormatColorUInt16: