<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Feb 27, 2018 at 4: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"><div class="HOEnZb"><div class="h5">On Tue, Feb 27, 2018 at 02:58:01PM -0800, Jason Ekstrand wrote:<br>
> On Wed, Feb 21, 2018 at 1:45 PM, Rafael Antognolli <<a href="mailto:rafael.antognolli@intel.com">rafael.antognolli@intel.com</a><br>
> > wrote:<br>
><br>
> 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 ++++++++++++++++++++++++++++++<br>
> +++++---<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<br>
> *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,<br>
> 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<br>
> *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<br>
> *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<br>
> *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>
><br>
><br>
> Here you use <a href="http://clear_address.bo" rel="noreferrer" target="_blank">clear_address.bo</a> != NULL but above you use use_clear_address.<br>
> Probably best to just pick one and stick with it.<br>
><br>
><br>
> + 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_<br>
> 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/<br>
> genX_cmd_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<br>
> *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_<br>
> offset,<br>
><br>
><br>
> I'm not sure how comfortable I am with ss.clear_value_offset doing double-duty<br>
> for inline clear values and clear value addresses. I suppose it's probably ok<br>
> because the only overlap is gen10 and we know it matches there.<br>
><br>
><br>
> + image->planes[image_plane].bo,<br>
> 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<br>
> *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>
><br>
><br>
> I think we probably want to break the clear value handling code from<br>
> color_attachment_compute_aux_<wbr>usage into a helper and use that here instead of<br>
> the memcpy. That way things are a bit sanitized.<br>
<br>
</div></div>Hmmm... Reading again this code, I'm trying to remember why I memcpy the<br>
clear color from att_state to fast_clear_value. It looks like I could<br>
just have used it directly, like:<br>
<br>
sdi.ImmediateData = att_state->clear_value.color.<wbr>uint32[i];<br>
<br>
So, do you have a preference between this and the copy done in<br>
color_attachment_compute_aux_<wbr>usage?<br><div class="HOEnZb"><div class="h5"></div></div></blockquote><div><br></div><div>I think I'd prefer the copy done in color_attachment_compute_aux_usage because it sanatizes the value and prevents us from writing undefined garbage into the buffer.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
> +<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 /<br>
> 4; i++) {<br>
><br>
><br>
> This only gets called on gen10+, just make it 4. If it's ever anything else,<br>
> we'll have to modify the stuff below since it just pulls from<br>
> fast_clear_value.u32<br>
><br>
><br>
> + 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<br>
> *cmd_buffer,<br>
> base_clear_layer++;<br>
> clear_layer_count--;<br>
><br>
> - genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state-><br>
> 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-><br>
> color.state,<br>
> + image,<br>
> 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<br>
> the<br>
> @@ -3462,7 +3505,8 @@ cmd_buffer_begin_subpass(<wbr>struct anv_cmd_buffer<br>
> *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_<br>
> ANV) {<br>
> + if (GEN_GEN < 10 &&<br>
> + (att_state->pending_load_<wbr>aspects &<br>
> 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-><br>
> color.state,<br>
> image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
> --<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>
><br>
><br>
</div></div></blockquote></div><br></div></div>