anv: flush fast clear colors into compressed surfaces
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sun, 23 Dec 2018 17:49:23 +0000 (17:49 +0000)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Tue, 8 Jan 2019 16:37:00 +0000 (16:37 +0000)
In the following scenario :

   1. Create image format R8G8B8A8_UNORM
   2. Create image view format R8G8B8A8_SRGB
   3. Clear the view through a sub pass to a particular color
   4. Barrier on the image to from color attachment to source transfer
   5. Copy the image into a linear buffer to check the content

The step 4 resolving the clear color is unaware of the SRGB format of
the view, because the blorp resolve operations operate on images the
color associated with the resolve will not operate on SRGB format but
UNORM. Leading to the wrong color being written into surfaces.

This change forces a clear color resolve at the end of the render pass
so following resolves won't have to deal with the clear color with a
format that doesn't match the image's format.

On gfxbench vulkan_5_normal 1280x720, this appear to cost us ~0.5fps,
from 49.316 down to 48.949.

v2: Only fast clear resolve when image & view have different formats
    (Lionel)

v3: Update warning (Jason)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108911
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Cc: mesa-stable@lists.freedesktop.org
src/intel/vulkan/genX_cmd_buffer.c

index fc075def0aa1e0a115f112d12f4145137a76d83a..35a70f7fe376fa077dd8e50f33f64168889c442e 100644 (file)
@@ -3909,6 +3909,55 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
       struct anv_image_view *iview = fb->attachments[a];
       const struct anv_image *image = iview->image;
 
+      if ((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) &&
+          image->vk_format != iview->vk_format) {
+         enum anv_fast_clear_type fast_clear_type =
+            anv_layout_to_fast_clear_type(&cmd_buffer->device->info,
+                                          image, VK_IMAGE_ASPECT_COLOR_BIT,
+                                          att_state->current_layout);
+
+         /* If any clear color was used, flush it down the aux surfaces. If we
+          * don't do it now using the view's format we might use the clear
+          * color incorrectly in the following resolves (for example with an
+          * SRGB view & a UNORM image).
+          */
+         if (fast_clear_type != ANV_FAST_CLEAR_NONE) {
+            anv_perf_warn(cmd_buffer->device->instance, fb,
+                          "Doing a partial resolve to get rid of clear color at the "
+                          "end of a renderpass due to an image/view format mismatch");
+
+            uint32_t base_layer, layer_count;
+            if (image->type == VK_IMAGE_TYPE_3D) {
+               base_layer = 0;
+               layer_count = anv_minify(iview->image->extent.depth,
+                                        iview->planes[0].isl.base_level);
+            } else {
+               base_layer = iview->planes[0].isl.base_array_layer;
+               layer_count = fb->layers;
+            }
+
+            for (uint32_t a = 0; a < layer_count; a++) {
+               uint32_t array_layer = base_layer + a;
+               if (image->samples == 1) {
+                  anv_cmd_predicated_ccs_resolve(cmd_buffer, image,
+                                                 iview->planes[0].isl.format,
+                                                 VK_IMAGE_ASPECT_COLOR_BIT,
+                                                 iview->planes[0].isl.base_level,
+                                                 array_layer,
+                                                 ISL_AUX_OP_PARTIAL_RESOLVE,
+                                                 ANV_FAST_CLEAR_NONE);
+               } else {
+                  anv_cmd_predicated_mcs_resolve(cmd_buffer, image,
+                                                 iview->planes[0].isl.format,
+                                                 VK_IMAGE_ASPECT_COLOR_BIT,
+                                                 base_layer,
+                                                 ISL_AUX_OP_PARTIAL_RESOLVE,
+                                                 ANV_FAST_CLEAR_NONE);
+               }
+            }
+         }
+      }
+
       /* Transition the image into the final layout for this render pass */
       VkImageLayout target_layout =
          cmd_state->pass->attachments[a].final_layout;