radv: fix DCC fast clear code for intensity formats
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 11 Oct 2019 15:40:59 +0000 (17:40 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Mon, 14 Oct 2019 06:36:14 +0000 (08:36 +0200)
This fixes a rendering issue with DiRT 4 on GFX10. Only GFX10 was
affected because intensity formats are different.

Cc: 19.2 <mesa-stable@lists.freedesktop.org>
Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/1923
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_image.c
src/amd/vulkan/radv_meta_clear.c
src/amd/vulkan/radv_private.h

index fa7f47cc8ef5e36e37ec92c5087b7564fc704031..1842daabf68ae2ade2e8bb46eeed983f1d3fd4a3 100644 (file)
@@ -715,7 +715,7 @@ static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle[4])
        return bc_swizzle;
 }
 
-static bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
+bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
 {
        const struct vk_format_description *desc = vk_format_description(format);
 
index 83bf45fb4cce19b999203d2db729700bfa2a6874..6002fc87a61f40fe9683263225a50ef3b83945bb 100644 (file)
@@ -1450,7 +1450,9 @@ enum {
        RADV_DCC_CLEAR_SECONDARY_1 = 0x40404040U
 };
 
-static void vi_get_fast_clear_parameters(VkFormat format,
+static void vi_get_fast_clear_parameters(struct radv_device *device,
+                                        VkFormat image_format,
+                                        VkFormat view_format,
                                         const VkClearColorValue *clear_value,
                                         uint32_t* reset_value,
                                         bool *can_avoid_fast_clear_elim)
@@ -1464,19 +1466,22 @@ static void vi_get_fast_clear_parameters(VkFormat format,
 
        *reset_value = RADV_DCC_CLEAR_REG;
 
-       const struct vk_format_description *desc = vk_format_description(format);
-       if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 ||
-           format == VK_FORMAT_R5G6B5_UNORM_PACK16 ||
-           format == VK_FORMAT_B5G6R5_UNORM_PACK16)
+       const struct vk_format_description *desc = vk_format_description(view_format);
+       if (view_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 ||
+           view_format == VK_FORMAT_R5G6B5_UNORM_PACK16 ||
+           view_format == VK_FORMAT_B5G6R5_UNORM_PACK16)
                extra_channel = -1;
        else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) {
-               if (radv_translate_colorswap(format, false) <= 1)
+               if (vi_alpha_is_on_msb(device, view_format))
                        extra_channel = desc->nr_channels - 1;
                else
                        extra_channel = 0;
        } else
                return;
 
+       bool image_alpha_is_on_msb = vi_alpha_is_on_msb(device, image_format);
+       bool view_alpha_is_on_msb = vi_alpha_is_on_msb(device, view_format);
+
        for (i = 0; i < 4; i++) {
                int index = desc->swizzle[i] - VK_SWIZZLE_X;
                if (desc->swizzle[i] < VK_SWIZZLE_X ||
@@ -1511,6 +1516,17 @@ static void vi_get_fast_clear_parameters(VkFormat format,
                        main_value = values[i];
        }
 
+       /* If alpha isn't present, make it the same as color, and vice versa. */
+       if (!extra_value)
+               extra_value = main_value;
+       else if (!main_value)
+               main_value = extra_value;
+
+       if (main_value != extra_value) {
+               assert(image_alpha_is_on_msb == view_alpha_is_on_msb);
+               return; /* require ELIMINATE_FAST_CLEAR */
+       }
+
        for (int i = 0; i < 4; ++i)
                if (values[i] != main_value &&
                    desc->swizzle[i] - VK_SWIZZLE_X != extra_channel &&
@@ -1570,7 +1586,9 @@ radv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer,
                bool can_avoid_fast_clear_elim;
                uint32_t reset_value;
 
-               vi_get_fast_clear_parameters(iview->vk_format,
+               vi_get_fast_clear_parameters(cmd_buffer->device,
+                                            iview->image->vk_format,
+                                            iview->vk_format,
                                             &clear_value, &reset_value,
                                             &can_avoid_fast_clear_elim);
 
@@ -1642,7 +1660,9 @@ radv_fast_clear_color(struct radv_cmd_buffer *cmd_buffer,
                bool can_avoid_fast_clear_elim;
                bool need_decompress_pass = false;
 
-               vi_get_fast_clear_parameters(iview->vk_format,
+               vi_get_fast_clear_parameters(cmd_buffer->device,
+                                            iview->image->vk_format,
+                                            iview->vk_format,
                                             &clear_value, &reset_value,
                                             &can_avoid_fast_clear_elim);
 
index 1995d59045f34aa3630331cb6a1f79aecf2dcfc2..1158a30f7675668d4bfe060bf4b3d407734b1285 100644 (file)
@@ -1924,6 +1924,8 @@ VkResult radv_image_create(VkDevice _device,
                           const VkAllocationCallbacks* alloc,
                           VkImage *pImage);
 
+bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format);
+
 VkResult
 radv_image_from_gralloc(VkDevice device_h,
                        const VkImageCreateInfo *base_info,