<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 28, 2017 at 2:14 PM, Nanley Chery <span dir="ltr"><<a href="mailto:nanleychery@gmail.com" target="_blank">nanleychery@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">v2: Rewrite functions, change location of synchronization.<br>
<br>
Signed-off-by: Nanley Chery <<a href="mailto:nanley.g.chery@intel.com">nanley.g.chery@intel.com</a>><br>
---<br>
src/intel/vulkan/genX_cmd_<wbr>buffer.c | 114 ++++++++++++++++++++++++++++++<wbr>+++++++<br>
1 file changed, 114 insertions(+)<br>
<br>
diff --git a/src/intel/vulkan/genX_cmd_<wbr>buffer.c b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
index 253e68cd1f..decf0b28d6 100644<br>
--- a/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
@@ -479,6 +479,51 @@ init_fast_clear_state_entry(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
}<br>
}<br>
<br>
+/* Copy the fast-clear value dword(s) between a surface state object and an<br>
+ * image's fast clear state buffer.<br>
+ */<br>
+static void<br>
+genX(copy_fast_clear_dwords)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
+ struct anv_state surface_state,<br>
+ const struct anv_image *image,<br>
+ unsigned level,<br>
+ bool copy_from_surface_state)<br>
+{<br>
+ assert(cmd_buffer && image);<br>
+ assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+ assert(level < anv_image_aux_levels(image));<br>
+<br>
+ struct anv_bo *ss_bo =<br>
+ &cmd_buffer->device-><a href="http://surface_state_pool.block_pool.bo" rel="noreferrer" target="_blank">surface_<wbr>state_pool.block_pool.bo</a>;<br>
+ uint32_t ss_clear_offset = surface_state.offset +<br>
+ cmd_buffer->device->isl_dev.<wbr>ss.clear_value_offset;<br>
+ uint32_t entry_offset =<br>
+ get_fast_clear_state_entry_<wbr>offset(cmd_buffer->device, image, level);<br>
+ unsigned copy_size = cmd_buffer->device->isl_dev.<wbr>ss.clear_value_size;<br>
+<br>
+ if (copy_from_surface_state) {<br>
+ genX(cmd_buffer_mi_memcpy)(<wbr>cmd_buffer, image->bo, entry_offset,<br>
+ ss_bo, ss_clear_offset, copy_size);<br>
+ } else {<br>
+ genX(cmd_buffer_mi_memcpy)(<wbr>cmd_buffer, ss_bo, ss_clear_offset,<br>
+ image->bo, entry_offset, copy_size);<br>
+<br>
+ /* Updating a surface state object may require that the state cache be<br>
+ * invalidated. From the SKL PRM, Shared Functions -> State -> State<br>
+ * Caching:<br>
+ *<br>
+ * Whenever the RENDER_SURFACE_STATE object in memory pointed to by<br>
+ * the Binding Table Pointer (BTP) and Binding Table Index (BTI) is<br>
+ * modified [...], the L1 state cache must be invalidated to ensure<br>
+ * the new surface or sampler state is fetched from system memory.<br>
+ *<br>
+ * In testing, SKL doesn't actually seem to need this, but HSW does.<br>
+ */<br>
+ cmd_buffer->state.pending_<wbr>pipe_bits |=<br>
+ ANV_PIPE_STATE_CACHE_<wbr>INVALIDATE_BIT;<br>
+ }<br>
+}<br>
+<br>
static void<br>
transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
@@ -2615,6 +2660,66 @@ cmd_buffer_subpass_transition_<wbr>layouts(struct anv_cmd_buffer * const cmd_buffer,<br>
}<br>
}<br>
<br>
+/* Update the clear value dword(s) in surface state objects or the fast clear<br>
+ * state buffer entry for the color attachments used in this subpass.<br>
+ */<br>
+static void<br>
+cmd_buffer_subpass_sync_fast_<wbr>clear_values(struct anv_cmd_buffer *cmd_buffer)<br>
+{<br>
+ assert(cmd_buffer && cmd_buffer->state.subpass);<br>
+<br>
+ const struct anv_cmd_state *state = &cmd_buffer->state;<br>
+<br>
+ /* Iterate through every color attachment used in this subpass. */<br>
+ for (uint32_t i = 0; i < state->subpass->color_count; ++i) {<br>
+<br>
+ /* The attachment should be one of the attachments described in the<br>
+ * render pass and used in the subpass.<br>
+ */<br>
+ const uint32_t a = state->subpass->color_<wbr>attachments[i].attachment;<br>
+ assert(a < state->pass->attachment_count)<wbr>;<br>
+ if (a == VK_ATTACHMENT_UNUSED)<br>
+ continue;<br>
+<br>
+ /* Store some information regarding this attachment. */<br>
+ const struct anv_attachment_state *att_state = &state->attachments[a];<br>
+ const struct anv_image_view *iview = state->framebuffer-><wbr>attachments[a];<br>
+ const struct anv_render_pass_attachment *rp_att =<br>
+ &state->pass->attachments[a];<br>
+<br>
+ if (att_state->aux_usage == ISL_AUX_USAGE_NONE)<br>
+ continue;<br>
+<br>
+ /* The fast clear state entry must be updated if a fast clear is going to<br>
+ * happen. The surface state must be updated if the clear value from a<br>
+ * prior fast clear may be needed.<br>
+ */<br>
+ if (att_state->pending_clear_<wbr>aspects && att_state->fast_clear) {<br>
+ /* Update the fast clear state entry. */<br>
+ genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color_rt_state,<br>
+ iview->image, iview->isl.base_level,<br>
+ true /* copy from ss */);<br></blockquote><div><br></div><div>In the future, I think we will want to do this as part of the fast-clear operation rather than as a "synchronization" step. Why? Because we're going to want to store the fast-clear color in two formats: floats/ints and encoded pixel value. Since we won't know the encoded pixel value here, setting it up-front will be better.<br><br></div><div>That said, I can definitely see how doing it this way is more convenient for now and I'm fine with it. It's not hard to switch to the other.<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ } else if (rp_att->load_op == VK_ATTACHMENT_LOAD_OP_LOAD) {<br>
+ /* The attachment may have been fast-cleared in a previous render<br>
+ * pass and the value is needed now. Update the surface state(s).<br>
+ *<br>
+ * TODO: Do this only once per render pass instead of every subpass.<br>
+ */<br>
+ genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color_rt_state,<br>
+ iview->image, iview->isl.base_level,<br>
+ false /* copy to ss */);<br>
+<br>
+ if (need_input_attachment_state(<wbr>rp_att) &&<br>
+ att_state->input_aux_usage != ISL_AUX_USAGE_NONE) {<br>
+ genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->input_att_state,<br>
+ iview->image, iview->isl.base_level,<br>
+ false /* copy to ss */);<br>
+ }<br>
+ }<br>
+ }<br>
+}<br>
+<br>
+<br>
static void<br>
genX(cmd_buffer_set_subpass)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
struct anv_subpass *subpass)<br>
@@ -2638,6 +2743,15 @@ genX(cmd_buffer_set_subpass)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
*/<br>
cmd_buffer_subpass_transition_<wbr>layouts(cmd_buffer, false);<br>
<br>
+ /* Update clear values *after* performing automatic layout transitions.<br>
+ * This ensures that transitions from the UNDEFINED layout have had a chance<br>
+ * to populate the clear value buffer with the correct values for the<br>
+ * LOAD_OP_LOAD loadOp and that the fast-clears will update the buffer<br>
+ * without the aforementioned layout transition overwriting the fast-clear<br>
+ * value.<br>
+ */<br>
+ cmd_buffer_subpass_sync_fast_<wbr>clear_values(cmd_buffer);<br>
+<br>
cmd_buffer_emit_depth_stencil(<wbr>cmd_buffer);<br>
<br>
anv_cmd_buffer_clear_subpass(<wbr>cmd_buffer);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.13.1<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>