Merge pull request #1095 from cdavis5e/exact-clear-fix

MVKPixelFormats: Add 0.5 ULP to clear values for normalized formats.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
index bae44ce..26ae597 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
@@ -430,6 +430,100 @@
 			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;
+			}
+#undef OFFSET_UNORM
+#undef OFFSET_SNORM
 			break;
 		case kMVKFormatColorUInt8:
 		case kMVKFormatColorUInt16: