<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">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>></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">mesa-stable@lists.<wbr>freedesktop.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">daniel.maciel@gmail.com</a>><br>
Signed-off-by: Lionel Landwerlin <<a href="mailto:lionel.g.landwerlin@intel.com">lionel.g.landwerlin@intel.com</a><wbr>><br>
---<br>
src/intel/vulkan/anv_cmd_<wbr>buffer.c | 58 ++++++++++++++++++++++++++++++<wbr>++++-----<br>
src/intel/vulkan/anv_private.h | 3 +-<br>
2 files changed, 52 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_cmd_<wbr>buffer.c b/src/intel/vulkan/anv_cmd_<wbr>buffer.c<br>
index 3b59af8f6f4..2ef7f9bf260 100644<br>
--- a/src/intel/vulkan/anv_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/anv_cmd_<wbr>buffer.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_<wbr>descriptors); i++) {<br>
+ if (state->push_descriptors[i] != NULL) {<br>
+ vk_free(&cmd_buffer->pool-><wbr>alloc, state->push_descriptors[i]);<br></blockquote><div><br></div><div>It's safe to vk_free a null pointer. There's no need for the check.<br></div><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><div>This is a pointer, NULL would be more appropriate.<br></div><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-><wbr>alloc, state->push_constants[i]);<br>
@@ -216,8 +222,8 @@ static VkResult anv_create_cmd_buffer(<br>
anv_state_stream_init(&cmd_<wbr>buffer->dynamic_state_stream,<br>
&device->dynamic_state_pool, 16384);<br>
<br>
- memset(&cmd_buffer->state.<wbr>push_descriptor, 0,<br>
- sizeof(cmd_buffer->state.push_<wbr>descriptor));<br>
+ memset(cmd_buffer->state.push_<wbr>descriptors, 0,<br>
+ sizeof(cmd_buffer->state.push_<wbr>descriptors));<br>
<br>
if (pool) {<br>
list_addtail(&cmd_buffer-><wbr>pool_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_<wbr>link);<br>
<br>
anv_cmd_buffer_fini_batch_bo_<wbr>chain(cmd_buffer);<br>
@@ -276,7 +284,13 @@ anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)<br>
anv_state_stream_finish(&cmd_<wbr>buffer->surface_state_stream);<br>
anv_state_stream_finish(&cmd_<wbr>buffer->dynamic_state_stream);<br>
<br>
- vk_free(&cmd_buffer->pool-><wbr>alloc, cmd_buffer->state.attachments)<wbr>;<br>
+ for (uint32_t i = 0; i < ARRAY_SIZE(state->push_<wbr>descriptors); i++) {<br>
+ if (state->push_descriptors[i] != NULL) {<br>
+ vk_free(&cmd_buffer->pool-><wbr>alloc, state->push_descriptors[i]);<br></blockquote><div><br></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><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-><wbr>alloc, state->attachments);<br>
vk_free(&cmd_buffer->pool-><wbr>alloc, cmd_buffer);<br>
}<br>
<br>
@@ -834,6 +848,26 @@ anv_cmd_buffer_get_depth_<wbr>stencil_view(const struct anv_cmd_buffer *cmd_buffer)<br>
return iview;<br>
}<br>
<br>
+static VkResult<br>
+anv_cmd_buffer_ensure_push_<wbr>descriptor_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_<wbr>descriptors[set];<br>
+<br>
+ if (*push_set == NULL) {<br>
+ *push_set = vk_alloc(&cmd_buffer->pool-><wbr>alloc,<br>
+ sizeof(struct anv_push_descriptor_set), 8,<br>
+ VK_SYSTEM_ALLOCATION_SCOPE_<wbr>OBJECT);<br>
+ if (*push_set == NULL) {<br>
+ anv_batch_set_error(&cmd_<wbr>buffer->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_<wbr>descriptor.set;<br>
+<br>
+ if (anv_cmd_buffer_ensure_push_<wbr>descriptor_set(cmd_buffer, _set) != VK_SUCCESS)<br>
+ return;<br>
+ struct anv_push_descriptor_set *push_set =<br>
+ cmd_buffer->state.push_<wbr>descriptors[_set];<br>
+ struct anv_descriptor_set *set = &push_set->set;<br>
<br>
set->layout = set_layout;<br>
set->size = anv_descriptor_set_layout_<wbr>size(set_layout);<br>
set->buffer_count = set_layout->buffer_count;<br>
- set->buffer_views = cmd_buffer->state.push_<wbr>descriptor.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_<wbr>CmdPushDescriptorSetWithTempla<wbr>teKHR(<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_<wbr>descriptor.set;<br>
+<br>
+ if (anv_cmd_buffer_ensure_push_<wbr>descriptor_set(cmd_buffer, _set) != VK_SUCCESS)<br>
+ return;<br>
+ struct anv_push_descriptor_set *push_set =<br>
+ cmd_buffer->state.push_<wbr>descriptors[_set];<br>
+ struct anv_descriptor_set *set = &push_set->set;<br>
<br>
set->layout = set_layout;<br>
set->size = anv_descriptor_set_layout_<wbr>size(set_layout);<br>
set->buffer_count = set_layout->buffer_count;<br>
- set->buffer_views = cmd_buffer->state.push_<wbr>descriptor.buffer_views;<br>
+ set->buffer_views = push_set->buffer_views;<br>
<br>
anv_descriptor_set_write_<wbr>template(set,<br>
cmd_buffer->device,<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index 3ba623a37fd..e81385263f2 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.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_<wbr>DESCRIPTORS];<br>
-<br>
struct anv_buffer_view buffer_views[MAX_PUSH_<wbr>DESCRIPTORS];<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="HOEnZb"><font color="#888888">--<br>
2.14.2<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>