<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 6, 2017 at 11:15 PM, Iago Toral Quiroga <span dir="ltr"><<a href="mailto:itoral@igalia.com" target="_blank">itoral@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The vkCmd*() functions do not report errors, instead, any errors should be<br>
reported by the time we call vkEndCommandBuffer(). This means that we<br>
need to track things such as "out of host memory" and use that information<br>
to avoid executing code that could lead to crashes (due to the fact that the<br>
command buffer could not allocate the memory it needs) and report the error<br>
when the client calls vkEndCommandBuffer().<br>
<br>
Notice this patch is not sufficient to track and report all possible cases<br>
of out of host memory situations that can be produced while recording<br>
command buffers. Later patches will fix some of the missing cases. Also,<br>
some allocations may occur deep into the driver code (for example during<br>
batch emissions) and are more difficult to track because at that point we<br>
don't even have access to the command buffer object. Dealing with these<br>
scenarios would require more changes but for now this is sufficient to make<br>
CTS happy.<br></blockquote><div><br></div><div>Thinking about things a bit more, I don't think that is actually all that hard...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Fixes:<br>
dEQP-VK.api.out_of_host_<wbr>memory.cmd_begin_render_pass<br>
---<br>
 src/intel/vulkan/anv_cmd_<wbr>buffer.c  |  5 +++++<br>
 src/intel/vulkan/anv_private.h     |  7 +++++++<br>
 src/intel/vulkan/genX_cmd_<wbr>buffer.c | 22 +++++++++++++++++++---<br>
 3 files changed, 31 insertions(+), 3 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 cab1dd7..01447b0 100644<br>
--- a/src/intel/vulkan/anv_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/anv_cmd_<wbr>buffer.c<br>
@@ -117,6 +117,8 @@ anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)<br>
 {<br>
    struct anv_cmd_state *state = &cmd_buffer->state;<br>
<br>
+   cmd_buffer->error_status = VK_SUCCESS;<br>
+<br>
    memset(&state->descriptors, 0, sizeof(state->descriptors));<br>
    memset(&state->push_constants, 0, sizeof(state->push_constants))<wbr>;<br>
    memset(state->binding_tables, 0, sizeof(state->binding_tables))<wbr>;<br>
@@ -185,6 +187,8 @@ static VkResult anv_create_cmd_buffer(<br>
    if (cmd_buffer == NULL)<br>
       return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
<br>
+   cmd_buffer->error_status = VK_SUCCESS;<br>
+<br>
    cmd_buffer->_loader_data.<wbr>loaderMagic = ICD_LOADER_MAGIC;<br>
    cmd_buffer->device = device;<br>
    cmd_buffer->pool = pool;<br>
@@ -217,6 +221,7 @@ static VkResult anv_create_cmd_buffer(<br>
    return VK_SUCCESS;<br>
<br>
  fail:<br>
+   cmd_buffer->error_status = result;<br>
    vk_free(&cmd_buffer->pool-><wbr>alloc, cmd_buffer);<br>
<br>
    return result;<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index d3e32bc..46b51a9 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -1377,6 +1377,13 @@ struct anv_cmd_buffer {<br>
    VkCommandBufferLevel                         level;<br>
<br>
    struct anv_cmd_state                         state;<br>
+<br>
+   /**<br>
+    * Current error status of the command buffer. Used to track inconsistent<br>
+    * or incomplete command buffer states that are the consequence of run-time<br>
+    * errors such as out of memory scenarios.<br>
+    */<br>
+   VkResult                                     error_status;<br></blockquote><div><br></div><div>If we put this in anv_batch, we can easily set the status from "deep" parts of the driver.  Also, I'm not sure the "error" part of the name is needed.  "status" should be ok.<br><br></div><div>One other thing we may want to do is to add a anv_batch_set_error helper and only take first error.  That way we can track OUT_OF_HOST_MEMORY vs. OUT_OF_DEVICE_MEMORY.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 };<br>
<br>
 VkResult anv_cmd_buffer_init_batch_bo_<wbr>chain(struct anv_cmd_buffer *cmd_buffer);<br>
diff --git a/src/intel/vulkan/genX_cmd_<wbr>buffer.c b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
index b46a922..cbad144 100644<br>
--- a/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
@@ -401,8 +401,8 @@ genX(cmd_buffer_setup_<wbr>attachments)(struct anv_cmd_buffer *cmd_buffer,<br>
                                       sizeof(state->attachments[0]),<br>
                                  8, VK_SYSTEM_ALLOCATION_SCOPE_<wbr>OBJECT);<br>
    if (state->attachments == NULL) {<br>
-      /* FIXME: Propagate VK_ERROR_OUT_OF_HOST_MEMORY to vkEndCommandBuffer */<br>
-      return VK_ERROR_OUT_OF_HOST_MEMORY;<br>
+      /* Propagate VK_ERROR_OUT_OF_HOST_MEMORY to vkEndCommandBuffer */<br>
+      return cmd_buffer->error_status = VK_ERROR_OUT_OF_HOST_MEMORY;<br>
    }<br>
<br>
    bool need_null_state = false;<br>
@@ -615,6 +615,9 @@ genX(EndCommandBuffer)(<br>
 {<br>
    ANV_FROM_HANDLE(anv_cmd_<wbr>buffer, cmd_buffer, commandBuffer);<br>
<br>
+   if (cmd_buffer->error_status != VK_SUCCESS)<br>
+      return cmd_buffer->error_status;<br>
+<br>
    /* We want every command buffer to start with the PMA fix in a known state,<br>
     * so we disable it at the end of the command buffer.<br>
     */<br>
@@ -2470,7 +2473,14 @@ void genX(CmdBeginRenderPass)(<br>
    cmd_buffer->state.framebuffer = framebuffer;<br>
    cmd_buffer->state.pass = pass;<br>
    cmd_buffer->state.render_area = pRenderPassBegin->renderArea;<br>
-   genX(cmd_buffer_setup_<wbr>attachments)(cmd_buffer, pass, pRenderPassBegin);<br>
+   VkResult result =<br>
+      genX(cmd_buffer_setup_<wbr>attachments)(cmd_buffer, pass, pRenderPassBegin);<br>
+<br>
+   /* If we failed to setup the attachments we should not try to go further */<br>
+   if (result != VK_SUCCESS) {<br>
+      assert(cmd_buffer->error_<wbr>status != VK_SUCCESS);<br>
+      return;<br>
+   }<br>
<br>
    genX(flush_pipeline_select_3d)<wbr>(cmd_buffer);<br>
<br>
@@ -2483,6 +2493,9 @@ void genX(CmdNextSubpass)(<br>
 {<br>
    ANV_FROM_HANDLE(anv_cmd_<wbr>buffer, cmd_buffer, commandBuffer);<br>
<br>
+   if (cmd_buffer->error_status != VK_SUCCESS)<br>
+      return;<br>
+<br>
    assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_<wbr>PRIMARY);<br>
<br>
    anv_cmd_buffer_resolve_<wbr>subpass(cmd_buffer);<br>
@@ -2499,6 +2512,9 @@ void genX(CmdEndRenderPass)(<br>
 {<br>
    ANV_FROM_HANDLE(anv_cmd_<wbr>buffer, cmd_buffer, commandBuffer);<br>
<br>
+   if (cmd_buffer->error_status != VK_SUCCESS)<br>
+      return;<br>
+<br>
    anv_cmd_buffer_resolve_<wbr>subpass(cmd_buffer);<br>
<br>
    /* Perform transitions to the final layout after all writes have occurred.<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.7.4<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>