<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>