On Gen10+, instead of copying the clear color from the state buffer to
the surface state, just use the address of the state buffer in the
surface state directly. This way we can avoid the copy from state buffer
to surface state.

Signed-off-by: Rafael Antognolli <rafael.antogno...@intel.com>
---
 src/intel/vulkan/anv_image.c       | 19 ++++++++++
 src/intel/vulkan/anv_private.h     |  5 +++
 src/intel/vulkan/genX_cmd_buffer.c | 74 ++++++++++++++++++++++++++++++--------
 3 files changed, 83 insertions(+), 15 deletions(-)

diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 4ccdc16cc23..cc0274e73bc 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -937,6 +937,15 @@ anv_image_fill_surface_state(struct anv_device *device,
    const uint64_t aux_address = aux_usage == ISL_AUX_USAGE_NONE ?
       0 : (image->planes[plane].bo_offset + aux_surface->offset);
 
+   bool use_clear_address = false;
+   struct anv_address clear_address = { .bo = NULL };
+   state_inout->clear_address = 0;
+   if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE && aux_usage 
!= ISL_AUX_USAGE_HIZ) {
+      clear_address = anv_image_get_clear_color_addr(
+         device, image, aspect, view_in->base_level);
+      use_clear_address = true;
+   }
+
    if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
        !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) &&
        !isl_has_matching_typed_storage_image_format(&device->info,
@@ -954,6 +963,7 @@ anv_image_fill_surface_state(struct anv_device *device,
                             .mocs = device->default_mocs);
       state_inout->address = address,
       state_inout->aux_address = 0;
+      state_inout->clear_address = 0;
    } else {
       if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
           !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) {
@@ -1027,6 +1037,8 @@ anv_image_fill_surface_state(struct anv_device *device,
                           .aux_surf = &aux_surface->isl,
                           .aux_usage = aux_usage,
                           .aux_address = aux_address,
+                          .clear_address = clear_address.offset,
+                          .use_clear_address = use_clear_address,
                           .mocs = device->default_mocs,
                           .x_offset_sa = tile_x_sa,
                           .y_offset_sa = tile_y_sa);
@@ -1048,6 +1060,13 @@ anv_image_fill_surface_state(struct anv_device *device,
       assert((aux_address & 0xfff) == 0);
       assert(aux_address == (*aux_addr_dw & 0xfffff000));
       state_inout->aux_address = *aux_addr_dw;
+
+      if (device->info.gen >= 10 && clear_address.bo) {
+         uint32_t *clear_addr_dw = state_inout->state.map +
+                                   device->isl_dev.ss.clear_value_offset;
+         assert((clear_address.offset & 0x3f) == 0);
+         state_inout->clear_address = *clear_addr_dw;
+      }
    }
 
    anv_state_flush(device, state_inout->state);
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 029e1b2b0b8..f0ac96489c9 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1635,6 +1635,11 @@ struct anv_surface_state {
     * bits of this address include extra aux information.
     */
    uint64_t aux_address;
+   /* Address of the clear color, if any
+    *
+    * This address is relative to the start of the BO.
+    */
+   uint64_t clear_address;
 };
 
 /**
diff --git a/src/intel/vulkan/genX_cmd_buffer.c 
b/src/intel/vulkan/genX_cmd_buffer.c
index e872749d4c1..f9a438c9c00 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -200,6 +200,16 @@ add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer,
       if (result != VK_SUCCESS)
          anv_batch_set_error(&cmd_buffer->batch, result);
    }
+
+   if (state.clear_address) {
+      VkResult result =
+         anv_reloc_list_add(&cmd_buffer->surface_relocs,
+                            &cmd_buffer->pool->alloc,
+                            state.state.offset + 
isl_dev->ss.clear_value_offset,
+                            image->planes[image_plane].bo, 
state.clear_address);
+      if (result != VK_SUCCESS)
+         anv_batch_set_error(&cmd_buffer->batch, result);
+   }
 }
 
 static bool
@@ -772,6 +782,27 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
       ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
 }
 
+static void
+update_fast_clear_color(struct anv_cmd_buffer *cmd_buffer,
+                        const struct anv_address addr,
+                        const union isl_color_value clear_color)
+{
+   assert(GEN_GEN >= 10);
+
+   /* Clear values are stored at the same bo as the aux surface, right
+    * after the surface.
+    */
+   for (int i = 0; i < cmd_buffer->device->isl_dev.ss.clear_value_size / 4; 
i++) {
+      anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) {
+         sdi.Address = (struct anv_address) {
+            .bo = addr.bo,
+            .offset = addr.offset + i * 4,
+         };
+         sdi.ImmediateData = clear_color.u32[i];
+      }
+   }
+}
+
 /**
  * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
  */
@@ -883,7 +914,6 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer 
*cmd_buffer,
             color_attachment_compute_aux_usage(cmd_buffer->device,
                                                state, i, begin->renderArea,
                                                &clear_color);
-
             anv_image_fill_surface_state(cmd_buffer->device,
                                          iview->image,
                                          VK_IMAGE_ASPECT_COLOR_BIT,
@@ -3083,11 +3113,23 @@ cmd_buffer_subpass_sync_fast_clear_values(struct 
anv_cmd_buffer *cmd_buffer)
        */
       if (att_state->pending_clear_aspects && att_state->fast_clear) {
          /* Update the fast clear state entry. */
-         genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
-                                      iview->image,
-                                      VK_IMAGE_ASPECT_COLOR_BIT,
-                                      iview->planes[0].isl.base_level,
-                                      true /* copy from ss */);
+         if (GEN_GEN >= 10) {
+            assert(state->attachments[i].aux_usage != ISL_AUX_USAGE_NONE);
+            struct anv_address clear_address =
+               anv_image_get_clear_color_addr(
+                  cmd_buffer->device, iview->image,
+                  VK_IMAGE_ASPECT_COLOR_BIT, iview->planes[0].isl.base_level);
+            union isl_color_value fast_clear_value;
+            memcpy(fast_clear_value.u32, att_state->clear_value.color.uint32,
+                   sizeof(fast_clear_value.u32));
+            update_fast_clear_color(cmd_buffer, clear_address, 
fast_clear_value);
+         } else {
+            genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
+                                         iview->image,
+                                         VK_IMAGE_ASPECT_COLOR_BIT,
+                                         iview->planes[0].isl.base_level,
+                                         true /* copy from ss */);
+         }
 
          /* Fast-clears impact whether or not a resolve will be necessary. */
          if (iview->image->planes[0].aux_usage == ISL_AUX_USAGE_CCS_E &&
@@ -3113,19 +3155,21 @@ cmd_buffer_subpass_sync_fast_clear_values(struct 
anv_cmd_buffer *cmd_buffer)
           *
           * TODO: Do this only once per render pass instead of every subpass.
           */
-         genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
-                                      iview->image,
-                                      VK_IMAGE_ASPECT_COLOR_BIT,
-                                      iview->planes[0].isl.base_level,
-                                      false /* copy to ss */);
-
-         if (need_input_attachment_state(rp_att) &&
-             att_state->input_aux_usage != ISL_AUX_USAGE_NONE) {
-            genX(copy_fast_clear_dwords)(cmd_buffer, att_state->input.state,
+         if (GEN_GEN < 10) {
+            genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
                                          iview->image,
                                          VK_IMAGE_ASPECT_COLOR_BIT,
                                          iview->planes[0].isl.base_level,
                                          false /* copy to ss */);
+
+            if (need_input_attachment_state(rp_att) &&
+                att_state->input_aux_usage != ISL_AUX_USAGE_NONE) {
+               genX(copy_fast_clear_dwords)(cmd_buffer, att_state->input.state,
+                                            iview->image,
+                                            VK_IMAGE_ASPECT_COLOR_BIT,
+                                            iview->planes[0].isl.base_level,
+                                            false /* copy to ss */);
+            }
          }
       }
    }
-- 
2.14.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to