lavapipe: rewrite cmdbufs to always do descriptor binds/pushes first
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 18 Mar 2021 17:34:32 +0000 (13:34 -0400)
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 19 Mar 2021 03:15:53 +0000 (23:15 -0400)
llvmpipe has some crazy dependency ordering with constant buffers that
I don't want to mess with, so instead this ensures that descriptors are
always updated as early in the command stream as possible, avoiding any
use-after-free scenarios which might result from lavapipe freeing memory
in a still-bound descriptor that's pending an update

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9692>

src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
src/gallium/frontends/lavapipe/lvp_private.h

index 8801652..e7a942f 100644 (file)
@@ -42,6 +42,7 @@ static VkResult lvp_create_cmd_buffer(
    cmd_buffer->device = device;
    cmd_buffer->pool = pool;
    list_inithead(&cmd_buffer->cmds);
+   cmd_buffer->last_emit = &cmd_buffer->cmds;
    cmd_buffer->status = LVP_CMD_BUFFER_STATUS_INITIAL;
    if (pool) {
       list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
@@ -70,6 +71,7 @@ static VkResult lvp_reset_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer)
 {
    lvp_cmd_buffer_free_all_cmds(cmd_buffer);
    list_inithead(&cmd_buffer->cmds);
+   cmd_buffer->last_emit = &cmd_buffer->cmds;
    cmd_buffer->status = LVP_CMD_BUFFER_STATUS_INITIAL;
    return VK_SUCCESS;
 }
@@ -288,7 +290,24 @@ static struct lvp_cmd_buffer_entry *cmd_buf_entry_alloc(struct lvp_cmd_buffer *c
 static void cmd_buf_queue(struct lvp_cmd_buffer *cmd_buffer,
                           struct lvp_cmd_buffer_entry *cmd)
 {
-   list_addtail(&cmd->cmd_link, &cmd_buffer->cmds);
+   switch (cmd->cmd_type) {
+   case LVP_CMD_BIND_DESCRIPTOR_SETS:
+   case LVP_CMD_PUSH_DESCRIPTOR_SET:
+      list_add(&cmd->cmd_link, cmd_buffer->last_emit);
+      cmd_buffer->last_emit = &cmd->cmd_link;
+      break;
+   case LVP_CMD_NEXT_SUBPASS:
+   case LVP_CMD_DRAW:
+   case LVP_CMD_DRAW_INDEXED:
+   case LVP_CMD_DRAW_INDIRECT:
+   case LVP_CMD_DRAW_INDEXED_INDIRECT:
+   case LVP_CMD_DISPATCH:
+   case LVP_CMD_DISPATCH_INDIRECT:
+      cmd_buffer->last_emit = &cmd->cmd_link;
+      FALLTHROUGH;
+   default:
+      list_addtail(&cmd->cmd_link, &cmd_buffer->cmds);
+   }
 }
 
 static void
index d6ae01f..713679a 100644 (file)
@@ -560,6 +560,7 @@ struct lvp_cmd_buffer {
    struct list_head                             pool_link;
 
    struct list_head                             cmds;
+   struct list_head                            *last_emit;
 
    uint8_t push_constants[MAX_PUSH_CONSTANTS_SIZE];
 };