From e03e7c510f571a8867ab7a8604058c075c601a70 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 5 Mar 2019 18:17:13 +0100 Subject: [PATCH] radv: fix color conversions for normalized uint/sint formats The hardware actually rounds before conversion. This now matches what values are used when performing fast clears vs slow clears. This fixes a rendering issue with Far Cry 3&4. This also fixes a bunch of CTS tests that use a 8-bit UNORM format (only when the 512*512 image size hint is manually disabled). Cc: "19.0" "19.1" Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_formats.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index bee1c57e610..5af172c8e7f 100644 --- a/src/amd/vulkan/radv_formats.c +++ b/src/amd/vulkan/radv_formats.c @@ -1032,10 +1032,22 @@ bool radv_format_pack_clear_color(VkFormat format, assert(channel->size == 8); v = util_format_linear_float_to_srgb_8unorm(value->float32[c]); - } else if (channel->type == VK_FORMAT_TYPE_UNSIGNED) { - v = MAX2(MIN2(value->float32[c], 1.0f), 0.0f) * ((1ULL << channel->size) - 1); - } else { - v = MAX2(MIN2(value->float32[c], 1.0f), -1.0f) * ((1ULL << (channel->size - 1)) - 1); + } else { + float f = MIN2(value->float32[c], 1.0f); + + if (channel->type == VK_FORMAT_TYPE_UNSIGNED) { + f = MAX2(f, 0.0f) * ((1ULL << channel->size) - 1); + } else { + f = MAX2(f, -1.0f) * ((1ULL << (channel->size - 1)) - 1); + } + + /* The hardware rounds before conversion. */ + if (f > 0) + f += 0.5f; + else + f -= 0.5f; + + v = (uint64_t)f; } } else if (channel->type == VK_FORMAT_TYPE_FLOAT) { if (channel->size == 32) { -- 2.30.2