anv: Handle color layout transitions from the UNINITIALIZED layout
authorJason Ekstrand <jason.ekstrand@intel.com>
Thu, 18 May 2017 02:02:42 +0000 (19:02 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 23 May 2017 23:46:03 +0000 (16:46 -0700)
This causes dEQP-VK.api.copy_and_blit.resolve_image.partial.* to start
failing due to test bugs.  See CL 1031 for a test fix.

Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Cc: "17.1" <mesa-stable@lists.freedesktop.org>
src/intel/vulkan/anv_blorp.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_cmd_buffer.c

index 974ea310cfacbacc781ae5b07e4869a06b9b51fb..45cbbb8690083405ddc8748bafaf2019cf8aae1c 100644 (file)
@@ -1414,6 +1414,73 @@ void anv_CmdResolveImage(
    blorp_batch_finish(&batch);
 }
 
+void
+anv_image_ccs_clear(struct anv_cmd_buffer *cmd_buffer,
+                    const struct anv_image *image,
+                    const struct isl_view *view,
+                    const VkImageSubresourceRange *subresourceRange)
+{
+   assert(image->type == VK_IMAGE_TYPE_3D || image->extent.depth == 1);
+
+   struct blorp_batch batch;
+   blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
+
+   struct blorp_surf surf;
+   get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
+                                image->aux_usage, &surf);
+
+   /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
+    *
+    *    "After Render target fast clear, pipe-control with color cache
+    *    write-flush must be issued before sending any DRAW commands on
+    *    that render target."
+    *
+    * This comment is a bit cryptic and doesn't really tell you what's going
+    * or what's really needed.  It appears that fast clear ops are not
+    * properly synchronized with other drawing.  This means that we cannot
+    * have a fast clear operation in the pipe at the same time as other
+    * regular drawing operations.  We need to use a PIPE_CONTROL to ensure
+    * that the contents of the previous draw hit the render target before we
+    * resolve and then use a second PIPE_CONTROL after the resolve to ensure
+    * that it is completed before any additional drawing occurs.
+    */
+   cmd_buffer->state.pending_pipe_bits |=
+      ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+
+   const uint32_t level_count =
+      view ? view->levels : anv_get_levelCount(image, subresourceRange);
+   for (uint32_t l = 0; l < level_count; l++) {
+      const uint32_t level =
+         (view ? view->base_level : subresourceRange->baseMipLevel) + l;
+
+      const VkExtent3D extent = {
+         .width = anv_minify(image->extent.width, level),
+         .height = anv_minify(image->extent.height, level),
+         .depth = anv_minify(image->extent.depth, level),
+      };
+
+      /* Blorp likes to treat 2D_ARRAY and 3D the same. */
+      uint32_t blorp_base_layer, blorp_layer_count;
+      if (view) {
+         blorp_base_layer = view->base_array_layer;
+         blorp_layer_count = view->array_len;
+      } else if (image->type == VK_IMAGE_TYPE_3D) {
+         blorp_base_layer = 0;
+         blorp_layer_count = extent.depth;
+      } else {
+         blorp_base_layer = subresourceRange->baseArrayLayer;
+         blorp_layer_count = anv_get_layerCount(image, subresourceRange);
+      }
+
+      blorp_fast_clear(&batch, &surf, surf.surf->format,
+                       level, blorp_base_layer, blorp_layer_count,
+                       0, 0, extent.width, extent.height);
+   }
+
+   cmd_buffer->state.pending_pipe_bits |=
+      ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+}
+
 static void
 ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
                        struct blorp_batch *batch,
index 9b0dd678fdc062c999bc82b8be312537c1178b20..8435e5339b6f07cf95dd5bc227fa2fddbdde5859 100644 (file)
@@ -2064,6 +2064,12 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,
                         const struct anv_image *image,
                         enum blorp_hiz_op op);
 
+void
+anv_image_ccs_clear(struct anv_cmd_buffer *cmd_buffer,
+                    const struct anv_image *image,
+                    const struct isl_view *view,
+                    const VkImageSubresourceRange *subresourceRange);
+
 enum isl_aux_usage
 anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
                         const struct anv_image *image,
index ef9b7d0554cd56b0382468e9ef4069f145d44b12..79af9aad82c0ee6df8d21c5af081dbb5a9f53fcf 100644 (file)
@@ -388,6 +388,25 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer,
       anv_gen8_hiz_op_resolve(cmd_buffer, image, hiz_op);
 }
 
+static void
+transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
+                        const struct anv_image *image,
+                        VkImageLayout initial_layout,
+                        VkImageLayout final_layout,
+                        const struct isl_view *view,
+                        const VkImageSubresourceRange *subresourceRange)
+{
+   if (image->aux_usage != ISL_AUX_USAGE_CCS_E)
+      return;
+
+   if (initial_layout != VK_IMAGE_LAYOUT_UNDEFINED &&
+       initial_layout != VK_IMAGE_LAYOUT_PREINITIALIZED)
+      return;
+
+#if GEN_GEN >= 9
+   anv_image_ccs_clear(cmd_buffer, image, view, subresourceRange);
+#endif
+}
 
 /**
  * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
@@ -976,6 +995,14 @@ void genX(CmdPipelineBarrier)(
                                  pImageMemoryBarriers[i].oldLayout,
                                  pImageMemoryBarriers[i].newLayout);
       }
+      if (pImageMemoryBarriers[i].subresourceRange.aspectMask &
+          VK_IMAGE_ASPECT_COLOR_BIT) {
+         transition_color_buffer(cmd_buffer, image,
+                                 pImageMemoryBarriers[i].oldLayout,
+                                 pImageMemoryBarriers[i].newLayout,
+                                 NULL,
+                                 &pImageMemoryBarriers[i].subresourceRange);
+      }
    }
 
    cmd_buffer->state.pending_pipe_bits |=
@@ -2448,8 +2475,9 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer,
        */
       assert(att_ref->attachment < cmd_state->framebuffer->attachment_count);
 
-      const struct anv_image * const image =
-         cmd_state->framebuffer->attachments[att_ref->attachment]->image;
+      const struct anv_image_view * const iview =
+         cmd_state->framebuffer->attachments[att_ref->attachment];
+      const struct anv_image * const image = iview->image;
 
       /* Perform the layout transition. */
       if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
@@ -2459,6 +2487,11 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer,
             anv_layout_to_aux_usage(&cmd_buffer->device->info, image,
                                     image->aspects, target_layout);
       }
+      if (image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+         transition_color_buffer(cmd_buffer, image,
+                                 att_state->current_layout, target_layout,
+                                 &iview->isl, NULL);
+      }
 
       att_state->current_layout = target_layout;
    }