<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Feb 21, 2018 at 1:45 PM, Rafael Antognolli <span dir="ltr"><<a href="mailto:rafael.antognolli@intel.com" target="_blank">rafael.antognolli@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Gen10+, instead of copying the clear color from the state buffer to<br>
the surface state, just use the address of the state buffer in the<br>
surface state directly. This way we can avoid the copy from state buffer<br>
to surface state.<br>
<br>
Signed-off-by: Rafael Antognolli <<a href="mailto:rafael.antognolli@intel.com">rafael.antognolli@intel.com</a>><br>
---<br>
 src/intel/vulkan/anv_image.c       | 19 ++++++++++++++<br>
 src/intel/vulkan/anv_private.h     |  5 ++++<br>
 src/intel/vulkan/genX_cmd_<wbr>buffer.c | 52 ++++++++++++++++++++++++++++++<wbr>+++++---<br>
 3 files changed, 72 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index 0dafe03442d..6b7ea32cbb3 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -1023,6 +1023,15 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
    const uint64_t aux_address = aux_usage == ISL_AUX_USAGE_NONE ?<br>
       0 : (image->planes[plane].bo_<wbr>offset + aux_surface->offset);<br>
<br>
+   bool use_clear_address = false;<br>
+   struct anv_address clear_address = { .bo = NULL };<br>
+   state_inout->clear_address = 0;<br>
+   if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE &&<br>
+       aux_usage != ISL_AUX_USAGE_HIZ) {<br>
+      clear_address = anv_image_get_clear_color_<wbr>addr(device, image, aspect);<br>
+      use_clear_address = true;<br>
+   }<br>
+<br>
    if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&<br>
        !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_<wbr>WRITE_ONLY) &&<br>
        !isl_has_matching_typed_<wbr>storage_image_format(&device-><wbr>info,<br>
@@ -1040,6 +1049,7 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
                             .mocs = device->default_mocs);<br>
       state_inout->address = address,<br>
       state_inout->aux_address = 0;<br>
+      state_inout->clear_address = 0;<br>
    } else {<br>
       if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&<br>
           !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_<wbr>WRITE_ONLY)) {<br>
@@ -1113,6 +1123,8 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
                           .aux_surf = &aux_surface->isl,<br>
                           .aux_usage = aux_usage,<br>
                           .aux_address = aux_address,<br>
+                          .clear_address = clear_address.offset,<br>
+                          .use_clear_address = use_clear_address,<br>
                           .mocs = device->default_mocs,<br>
                           .x_offset_sa = tile_x_sa,<br>
                           .y_offset_sa = tile_y_sa);<br>
@@ -1134,6 +1146,13 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
       assert((aux_address & 0xfff) == 0);<br>
       assert(aux_address == (*aux_addr_dw & 0xfffff000));<br>
       state_inout->aux_address = *aux_addr_dw;<br>
+<br>
+      if (device->info.gen >= 10 && <a href="http://clear_address.bo" rel="noreferrer" target="_blank">clear_address.bo</a>) {<br></blockquote><div><br></div><div>Here you use <a href="http://clear_address.bo">clear_address.bo</a> != NULL but above you use use_clear_address.  Probably best to just pick one and stick with it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+         uint32_t *clear_addr_dw = state_inout->state.map +<br>
+                                   device->isl_dev.ss.clear_<wbr>value_offset;<br>
+         assert((clear_address.offset & 0x3f) == 0);<br>
+         state_inout->clear_address = *clear_addr_dw;<br>
+      }<br>
    }<br>
<br>
    anv_state_flush(device, state_inout->state);<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index b8c381d2665..5c077987cef 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -1674,6 +1674,11 @@ struct anv_surface_state {<br>
     * bits of this address include extra aux information.<br>
     */<br>
    uint64_t aux_address;<br>
+   /* Address of the clear color, if any<br>
+    *<br>
+    * This address is relative to the start of the BO.<br>
+    */<br>
+   uint64_t clear_address;<br>
 };<br>
<br>
 /**<br>
diff --git a/src/intel/vulkan/genX_cmd_<wbr>buffer.c b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
index 939a795c2b1..b9e1d50cbe3 100644<br>
--- a/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
@@ -200,6 +200,16 @@ add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer,<br>
       if (result != VK_SUCCESS)<br>
          anv_batch_set_error(&cmd_<wbr>buffer->batch, result);<br>
    }<br>
+<br>
+   if (state.clear_address) {<br>
+      VkResult result =<br>
+         anv_reloc_list_add(&cmd_<wbr>buffer->surface_relocs,<br>
+                            &cmd_buffer->pool->alloc,<br>
+                            state.state.offset + isl_dev->ss.clear_value_<wbr>offset,<br></blockquote><div><br></div><div>I'm not sure how comfortable I am with ss.clear_value_offset doing double-duty for inline clear values and clear value addresses.  I suppose it's probably ok because the only overlap is gen10 and we know it matches there.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+                            image->planes[image_plane].bo, state.clear_address);<br>
+      if (result != VK_SUCCESS)<br>
+         anv_batch_set_error(&cmd_<wbr>buffer->batch, result);<br>
+   }<br>
 }<br>
<br>
 static void<br>
@@ -1056,6 +1066,35 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
       ANV_PIPE_RENDER_TARGET_CACHE_<wbr>FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;<br>
 }<br>
<br>
+static void<br>
+update_fast_clear_color(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
+                        const struct anv_attachment_state *att_state,<br>
+                        const struct anv_image *image)<br>
+{<br>
+   assert(GEN_GEN >= 10);<br>
+   assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+<br>
+   struct anv_address clear_address =<br>
+      anv_image_get_clear_color_<wbr>addr(cmd_buffer->device, image,<br>
+                                     VK_IMAGE_ASPECT_COLOR_BIT);<br>
+   union isl_color_value fast_clear_value;<br>
+   memcpy(fast_clear_value.u32, att_state->clear_value.color.<wbr>uint32,<br>
+          sizeof(fast_clear_value.u32));<br></blockquote><div><br></div><div>I think we probably want to break the clear value handling code from color_attachment_compute_aux_usage into a helper and use that here instead of the memcpy.  That way things are a bit sanitized.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   /* Clear values are stored at the same bo as the aux surface, right<br>
+    * after the surface.<br>
+    */<br>
+   for (int i = 0; i < cmd_buffer->device->isl_dev.<wbr>ss.clear_value_size / 4; i++) {<br></blockquote><div><br></div><div>This only gets called on gen10+, just make it 4.  If it's ever anything else, we'll have to modify the stuff below since it just pulls from fast_clear_value.u32<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_STORE_DATA_IMM), sdi) {<br>
+         sdi.Address = (struct anv_address) {<br>
+            .bo = <a href="http://clear_address.bo" rel="noreferrer" target="_blank">clear_address.bo</a>,<br>
+            .offset = clear_address.offset + i * 4,<br>
+         };<br>
+         sdi.ImmediateData = fast_clear_value.u32[i];<br>
+      }<br>
+   }<br>
+}<br>
+<br>
 /**<br>
  * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.<br>
  */<br>
@@ -3403,9 +3442,13 @@ cmd_buffer_begin_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
             base_clear_layer++;<br>
             clear_layer_count--;<br>
<br>
-            genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color.state,<br>
-                                         image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
-                                         true /* copy from ss */);<br>
+            if (GEN_GEN < 10) {<br>
+               genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color.state,<br>
+                                            image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+                                            true /* copy from ss */);<br>
+            } else {<br>
+               update_fast_clear_color(cmd_<wbr>buffer, att_state, image);<br>
+            }<br>
<br>
             if (att_state->clear_color_is_<wbr>zero) {<br>
                /* This image has the auxiliary buffer enabled. We can mark the<br>
@@ -3462,7 +3505,8 @@ cmd_buffer_begin_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
          assert(att_state->pending_<wbr>clear_aspects == 0);<br>
       }<br>
<br>
-      if (att_state->pending_load_<wbr>aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV) {<br>
+      if (GEN_GEN < 10 &&<br>
+          (att_state->pending_load_<wbr>aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV)) {<br>
          if (att_state->aux_usage != ISL_AUX_USAGE_NONE) {<br>
             genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color.state,<br>
                                          image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>