[v5,16/19] anv: Emit the fast clear color address, instead of value.

Submitted by Rafael Antognolli on March 29, 2018, 5:58 p.m.

Details

Message ID 20180329175853.23728-17-rafael.antognolli@intel.com
State New
Headers show
Series "Use clear color address in surface state." ( rev: 7 6 5 ) in Mesa

Not browsing as part of any series.

Commit Message

Rafael Antognolli March 29, 2018, 5:58 p.m.
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.

v4:
 - Remove use_clear_address from anv code. (Jason)
 - Use the helper to extract clear color from attachment (Jason)

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
---
 src/intel/vulkan/anv_image.c       | 17 +++++++++++++
 src/intel/vulkan/anv_private.h     |  5 ++++
 src/intel/vulkan/genX_cmd_buffer.c | 52 +++++++++++++++++++++++++++++++++++---
 3 files changed, 70 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index d9b5d266020..da4601ce20e 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -1059,6 +1059,13 @@  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);
 
+   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);
+   }
+
    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,
@@ -1076,6 +1083,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)) {
@@ -1149,6 +1157,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 = clear_address.bo != NULL,
                           .mocs = device->default_mocs,
                           .x_offset_sa = tile_x_sa,
                           .y_offset_sa = tile_y_sa);
@@ -1163,6 +1173,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_color_state_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 fcb1f8b54ef..1e352576e22 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1704,6 +1704,11 @@  struct anv_surface_state {
     * gen8, the bottom 12 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 3bf71b073bf..483c0651a75 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -200,6 +200,17 @@  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_color_state_offset,
+                            image->planes[image_plane].bo, state.clear_address);
+      if (result != VK_SUCCESS)
+         anv_batch_set_error(&cmd_buffer->batch, result);
+   }
 }
 
 static void
@@ -1124,6 +1135,34 @@  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_attachment_state *att_state,
+                        const struct anv_image_view *iview)
+{
+   assert(GEN_GEN >= 10);
+   assert(iview->image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+
+   struct anv_address clear_address =
+      anv_image_get_clear_color_addr(cmd_buffer->device, iview->image,
+                                     VK_IMAGE_ASPECT_COLOR_BIT);
+   union isl_color_value clear_color;
+   anv_clear_color_from_att_state(&clear_color, att_state, iview);
+
+   /* Clear values are stored at the same bo as the aux surface, right
+    * after the surface.
+    */
+   for (int i = 0; i < 4; i++) {
+      anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) {
+         sdi.Address = (struct anv_address) {
+            .bo = clear_address.bo,
+            .offset = clear_address.offset + i * 4,
+         };
+         sdi.ImmediateData = clear_color.u32[i];
+      }
+   }
+}
+
 /**
  * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
  */
@@ -3523,9 +3562,13 @@  cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
             base_clear_layer++;
             clear_layer_count--;
 
-            genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
-                                         image, VK_IMAGE_ASPECT_COLOR_BIT,
-                                         true /* copy from ss */);
+            if (GEN_GEN < 10) {
+               genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
+                                            image, VK_IMAGE_ASPECT_COLOR_BIT,
+                                            true /* copy from ss */);
+            } else {
+               update_fast_clear_color(cmd_buffer, att_state, iview);
+            }
 
             if (att_state->clear_color_is_zero) {
                /* This image has the auxiliary buffer enabled. We can mark the
@@ -3585,7 +3628,8 @@  cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
          assert(att_state->pending_clear_aspects == 0);
       }
 
-      if ((att_state->pending_load_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) &&
+      if (GEN_GEN < 10 &&
+          (att_state->pending_load_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) &&
           image->planes[0].aux_surface.isl.size > 0 &&
           iview->planes[0].isl.base_level == 0 &&
           iview->planes[0].isl.base_array_layer == 0) {