From 007bf1d1dcf79028948e0e4207e445763faa6894 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 18 Mar 2021 13:34:32 -0400 Subject: [PATCH] lavapipe: rewrite cmdbufs to always do descriptor binds/pushes first 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 Part-of: --- .../frontends/lavapipe/lvp_cmd_buffer.c | 21 ++++++++++++++++++- src/gallium/frontends/lavapipe/lvp_private.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index 8801652c9df..e7a942fa1b1 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -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 diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index d6ae01f3d46..713679a68b6 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -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]; };