<div dir="ltr"><div>Regardless if what you choose to do with my comments, this patch is<br><br></div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 5, 2017 at 9:01 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Thu, Sep 28, 2017 at 5:05 PM, Lionel Landwerlin <span dir="ltr"><<a href="mailto:lionel.g.landwerlin@intel.com" target="_blank">lionel.g.landwerlin@intel.com</a><wbr>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">When writing to set > 0, we were just wrongly writing to set 0. This<br>
commit fixes this by lazily allocating each set as we write to them.<br>
<br>
We didn't go for having them directly into the command buffer as this<br>
would require an additional ~45Kb per command buffer.<br>
<br>
v2: Allocate push descriptors from system memory rather than in BO<br>
    streams. (Lionel)<br>
<br>
Cc: "17.2 17.1" <<a href="mailto:mesa-stable@lists.freedesktop.org" target="_blank">mesa-stable@lists.freedesktop<wbr>.org</a>><br>
Fixes: 9f60ed98e501 ("anv: add VK_KHR_push_descriptor support")<br>
Reported-by: Daniel Ribeiro Maciel <<a href="mailto:daniel.maciel@gmail.com" target="_blank">daniel.maciel@gmail.com</a>><br>
Signed-off-by: Lionel Landwerlin <<a href="mailto:lionel.g.landwerlin@intel.com" target="_blank">lionel.g.landwerlin@intel.com</a><wbr>><br>
---<br>
 src/intel/vulkan/anv_cmd_buff<wbr>er.c | 58 ++++++++++++++++++++++++++++++<wbr>++++-----<br>
 src/intel/vulkan/anv_private.<wbr>h    |  3 +-<br>
 2 files changed, 52 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_cmd_buf<wbr>fer.c b/src/intel/vulkan/anv_cmd_buf<wbr>fer.c<br>
index 3b59af8f6f4..2ef7f9bf260 100644<br>
--- a/src/intel/vulkan/anv_cmd_buf<wbr>fer.c<br>
+++ b/src/intel/vulkan/anv_cmd_buf<wbr>fer.c<br>
@@ -120,6 +120,12 @@ anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)<br>
    cmd_buffer->batch.status = VK_SUCCESS;<br>
<br>
    memset(&state->descriptors, 0, sizeof(state->descriptors));<br>
+   for (uint32_t i = 0; i < ARRAY_SIZE(state->push_descrip<wbr>tors); i++) {<br>
+      if (state->push_descriptors[i] != NULL) {<br>
+         vk_free(&cmd_buffer->pool->al<wbr>loc, state->push_descriptors[i]);<br></blockquote><div><br></div></div></div><div>It's safe to vk_free a null pointer.  There's no need for the check.<br></div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+         state->push_descriptors[i] = 0;<br></blockquote><div><br></div></span><div>This is a pointer, NULL would be more appropriate.<br></div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      }<br>
+   }<br>
    for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) {<br>
       if (state->push_constants[i] != NULL) {<br>
          vk_free(&cmd_buffer->pool->all<wbr>oc, state->push_constants[i]);<br>
@@ -216,8 +222,8 @@ static VkResult anv_create_cmd_buffer(<br>
    anv_state_stream_init(&cmd_buf<wbr>fer->dynamic_state_stream,<br>
                          &device->dynamic_state_pool, 16384);<br>
<br>
-   memset(&cmd_buffer->state.pus<wbr>h_descriptor, 0,<br>
-          sizeof(cmd_buffer->state.push_<wbr>descriptor));<br>
+   memset(cmd_buffer->state.<wbr>push_descriptors, 0,<br>
+          sizeof(cmd_buffer->state.push_<wbr>descriptors));<br>
<br>
    if (pool) {<br>
       list_addtail(&cmd_buffer->poo<wbr>l_link, &pool->cmd_buffers);<br>
@@ -269,6 +275,8 @@ VkResult anv_AllocateCommandBuffers(<br>
 static void<br>
 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)<br>
 {<br>
+   struct anv_cmd_state *state = &cmd_buffer->state;<br>
+<br>
    list_del(&cmd_buffer->pool_lin<wbr>k);<br>
<br>
    anv_cmd_buffer_fini_batch_bo_c<wbr>hain(cmd_buffer);<br>
@@ -276,7 +284,13 @@ anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)<br>
    anv_state_stream_finish(&cmd_b<wbr>uffer->surface_state_stream);<br>
    anv_state_stream_finish(&cmd_b<wbr>uffer->dynamic_state_stream);<br>
<br>
-   vk_free(&cmd_buffer->pool->al<wbr>loc, cmd_buffer->state.attachments)<wbr>;<br>
+   for (uint32_t i = 0; i < ARRAY_SIZE(state->push_descrip<wbr>tors); i++) {<br>
+      if (state->push_descriptors[i] != NULL) {<br>
+         vk_free(&cmd_buffer->pool->al<wbr>loc, state->push_descriptors[i]);<br></blockquote><div><br></div></div></div><div>Same comment as above.  You don't need the NULL check.  Also, I realized while reviewing this that we aren't freeing the push constant structs.  I just sent a patch which calls anv_cmd_state_reset in anv_cmd_buffer_destroy which should let you drop this hunk.<br></div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      }<br>
+   }<br>
+<br>
+   vk_free(&cmd_buffer->pool->al<wbr>loc, state->attachments);<br>
    vk_free(&cmd_buffer->pool->all<wbr>oc, cmd_buffer);<br>
 }<br>
<br>
@@ -834,6 +848,26 @@ anv_cmd_buffer_get_depth_stenc<wbr>il_view(const struct anv_cmd_buffer *cmd_buffer)<br>
    return iview;<br>
 }<br>
<br>
+static VkResult<br>
+anv_cmd_buffer_ensure_push_de<wbr>scriptor_set(struct anv_cmd_buffer *cmd_buffer,<br>
+                                          uint32_t set)<br>
+{<br>
+   struct anv_push_descriptor_set **push_set =<br>
+      &cmd_buffer->state.push_descri<wbr>ptors[set];<br>
+<br>
+   if (*push_set == NULL) {<br>
+      *push_set = vk_alloc(&cmd_buffer->pool->al<wbr>loc,<br>
+                           sizeof(struct anv_push_descriptor_set), 8,<br>
+                           VK_SYSTEM_ALLOCATION_SCOPE_OB<wbr>JECT);<br>
+      if (*push_set == NULL) {<br>
+         anv_batch_set_error(&cmd_buff<wbr>er->batch, VK_ERROR_OUT_OF_HOST_MEMORY);<br>
+         return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+      }<br>
+   }<br>
+<br>
+   return VK_SUCCESS;<br>
+}<br>
+<br>
 void anv_CmdPushDescriptorSetKHR(<br>
     VkCommandBuffer commandBuffer,<br>
     VkPipelineBindPoint pipelineBindPoint,<br>
@@ -851,12 +885,17 @@ void anv_CmdPushDescriptorSetKHR(<br>
<br>
    const struct anv_descriptor_set_layout *set_layout =<br>
       layout->set[_set].layout;<br>
-   struct anv_descriptor_set *set = &cmd_buffer->state.push_descri<wbr>ptor.set;<br>
+<br>
+   if (anv_cmd_buffer_ensure_push_de<wbr>scriptor_set(cmd_buffer, _set) != VK_SUCCESS)<br>
+      return;<br>
+   struct anv_push_descriptor_set *push_set =<br>
+      cmd_buffer->state.push_descrip<wbr>tors[_set];<br>
+   struct anv_descriptor_set *set = &push_set->set;<br>
<br>
    set->layout = set_layout;<br>
    set->size = anv_descriptor_set_layout_size<wbr>(set_layout);<br>
    set->buffer_count = set_layout->buffer_count;<br>
-   set->buffer_views = cmd_buffer->state.push_descrip<wbr>tor.buffer_views;<br>
+   set->buffer_views = push_set->buffer_views;<br>
<br>
    /* Go through the user supplied descriptors. */<br>
    for (uint32_t i = 0; i < descriptorWriteCount; i++) {<br>
@@ -937,12 +976,17 @@ void anv_CmdPushDescriptorSetWithTe<wbr>mplateKHR(<br>
<br>
    const struct anv_descriptor_set_layout *set_layout =<br>
       layout->set[_set].layout;<br>
-   struct anv_descriptor_set *set = &cmd_buffer->state.push_descri<wbr>ptor.set;<br>
+<br>
+   if (anv_cmd_buffer_ensure_push_de<wbr>scriptor_set(cmd_buffer, _set) != VK_SUCCESS)<br>
+      return;<br>
+   struct anv_push_descriptor_set *push_set =<br>
+      cmd_buffer->state.push_descrip<wbr>tors[_set];<br>
+   struct anv_descriptor_set *set = &push_set->set;<br>
<br>
    set->layout = set_layout;<br>
    set->size = anv_descriptor_set_layout_size<wbr>(set_layout);<br>
    set->buffer_count = set_layout->buffer_count;<br>
-   set->buffer_views = cmd_buffer->state.push_descrip<wbr>tor.buffer_views;<br>
+   set->buffer_views = push_set->buffer_views;<br>
<br>
    anv_descriptor_set_write_templ<wbr>ate(set,<br>
                                      cmd_buffer->device,<br>
diff --git a/src/intel/vulkan/anv_private<wbr>.h b/src/intel/vulkan/anv_private<wbr>.h<br>
index 3ba623a37fd..e81385263f2 100644<br>
--- a/src/intel/vulkan/anv_private<wbr>.h<br>
+++ b/src/intel/vulkan/anv_private<wbr>.h<br>
@@ -1268,7 +1268,6 @@ struct anv_push_descriptor_set {<br>
    /* Put this field right behind anv_descriptor_set so it fills up the<br>
     * descriptors[0] field. */<br>
    struct anv_descriptor descriptors[MAX_PUSH_DESCRIPTO<wbr>RS];<br>
-<br>
    struct anv_buffer_view buffer_views[MAX_PUSH_DESCRIPT<wbr>ORS];<br>
 };<br>
<br>
@@ -1686,7 +1685,7 @@ struct anv_cmd_state {<br>
    struct anv_dynamic_state                     dynamic;<br>
    bool                                         need_query_wa;<br>
<br>
-   struct anv_push_descriptor_set               push_descriptor;<br>
+   struct anv_push_descriptor_set *             push_descriptors[MAX_SETS];<br>
<br>
    /**<br>
     * Whether or not the gen8 PMA fix is enabled.  We ensure that, at the top<br>
<span class="m_7999772700490918978HOEnZb"><font color="#888888">--<br>
2.14.2<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">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></div></div><br></div></div>
</blockquote></div><br></div>