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: