From cf3b5968ef31f6c29a29d7740748c21204b20e7b Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Fri, 11 Mar 2022 11:24:05 -0500 Subject: [PATCH] Avoid adjusting SRGB clear color values by half-ULP. For GPUs that round float clear colors down, a half-ULP adjustment is performed on normalized formats. But this adjustment should not be performed on SRGB formats, which Vulkan requires to be treated as linear, with the value managed by the app. --- Docs/Whats_New.md | 1 + MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 2ed6e474..a4ab46a4 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -24,6 +24,7 @@ Released TBD - Fix issue where the depth component of a stencil-only renderpass attachment was incorrectly attempting to be stored. - Fix deletion of GPU counter `MTLFence` while it is being used by `MTLCommandBuffer`. - Remove limit on `VkPhysicalDeviceLimits::maxSamplerAllocationCount` when not using Metal argument buffers. +- Avoid adjusting SRGB clear color values by half-ULP on GPUs that round float clear colors down. - `MoltenVKShaderConverter` tool defaults to the highest MSL version supported on runtime OS. - Update *glslang* version, to use `python3` in *glslang* scripts, to replace missing `python` on *macOS 12.3*. - Update to latest SPIRV-Cross: diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm index c972226f..688d8249 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm @@ -472,6 +472,8 @@ MTLClearColor MVKPixelFormats::getMTLClearColor(VkClearValue vkClearValue, VkFor // 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. + // This adjustment is not performed on SRGB formats, which Vulkan + // requires to be treated as linear, with the value managed by the app. #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)); \ @@ -497,14 +499,12 @@ MTLClearColor MVKPixelFormats::getMTLClearColor(VkClearValue vkClearValue, VkFor 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; @@ -513,11 +513,8 @@ MTLClearColor MVKPixelFormats::getMTLClearColor(VkClearValue vkClearValue, VkFor 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)