diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index 8d2d0037cd4..d9da1477dd2 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -169,8 +169,13 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_EndCommandBuffer( VkCommandBuffer commandBuffer) { LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); - cmd_buffer->status = LVP_CMD_BUFFER_STATUS_EXECUTABLE; - return VK_SUCCESS; + + cmd_buffer->status = + cmd_buffer->vk.cmd_queue.error == VK_SUCCESS ? + LVP_CMD_BUFFER_STATUS_EXECUTABLE : + LVP_CMD_BUFFER_STATUS_INVALID; + + return cmd_buffer->vk.cmd_queue.error; } VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateCommandPool( diff --git a/src/vulkan/util/vk_cmd_queue_gen.py b/src/vulkan/util/vk_cmd_queue_gen.py index 52996b6dd5c..02e75a5a7a8 100644 --- a/src/vulkan/util/vk_cmd_queue_gen.py +++ b/src/vulkan/util/vk_cmd_queue_gen.py @@ -78,6 +78,7 @@ struct vk_device_dispatch_table; struct vk_cmd_queue { const VkAllocationCallbacks *alloc; struct list_head cmds; + VkResult error; }; enum vk_cmd_type { @@ -158,6 +159,7 @@ vk_cmd_queue_init(struct vk_cmd_queue *queue, VkAllocationCallbacks *alloc) { queue->alloc = alloc; list_inithead(&queue->cmds); + queue->error = VK_SUCCESS; } static inline void @@ -165,6 +167,7 @@ vk_cmd_queue_reset(struct vk_cmd_queue *queue) { vk_free_queue(queue); list_inithead(&queue->cmds); + queue->error = VK_SUCCESS; } static inline void @@ -210,26 +213,44 @@ const char *vk_cmd_queue_type_names[] = { }; % for c in commands: -% if c.name in manual_commands or c.name in no_enqueue_commands: -<% continue %> -% endif % if c.guard is not None: #ifdef ${c.guard} % endif +static void +vk_free_${to_underscore(c.name)}(struct vk_cmd_queue *queue, +${' ' * len('vk_free_' + to_underscore(c.name) + '(')}\\ +struct vk_cmd_queue_entry *cmd) +{ + if (cmd->driver_free_cb) + cmd->driver_free_cb(queue, cmd); + else + vk_free(queue->alloc, cmd->driver_data); +% for p in c.params[1:]: +% if p.len: + vk_free(queue->alloc, (${remove_suffix(p.decl.replace("const", ""), p.name)})cmd->u.${to_struct_field_name(c.name)}.${to_field_name(p.name)}); +% elif '*' in p.decl: + ${get_struct_free(c, p, types)} +% endif +% endfor + vk_free(queue->alloc, cmd); +} + +% if c.name not in manual_commands and c.name not in no_enqueue_commands: void vk_enqueue_${to_underscore(c.name)}(struct vk_cmd_queue *queue % for p in c.params[1:]: , ${p.decl} % endfor ) { + if (queue->error) + return; + struct vk_cmd_queue_entry *cmd = vk_zalloc(queue->alloc, sizeof(*cmd), 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - if (!cmd) - return; + if (!cmd) goto err; cmd->type = ${to_enum_name(c.name)}; - list_addtail(&cmd->cmd_link, &queue->cmds); % for p in c.params[1:]: % if p.len: @@ -247,7 +268,16 @@ void vk_enqueue_${to_underscore(c.name)}(struct vk_cmd_queue *queue cmd->u.${to_struct_field_name(c.name)}.${to_field_name(p.name)} = ${p.name}; % endif % endfor + + list_addtail(&cmd->cmd_link, &queue->cmds); + return; + +err: + queue->error = VK_ERROR_OUT_OF_HOST_MEMORY; + if (cmd) + vk_free_${to_underscore(c.name)}(queue, cmd); } +% endif % if c.guard is not None: #endif // ${c.guard} % endif @@ -265,24 +295,13 @@ vk_free_queue(struct vk_cmd_queue *queue) #ifdef ${c.guard} % endif case ${to_enum_name(c.name)}: - if (cmd->driver_free_cb) - cmd->driver_free_cb(queue, cmd); - else - vk_free(queue->alloc, cmd->driver_data); -% for p in c.params[1:]: -% if p.len: - vk_free(queue->alloc, (${remove_suffix(p.decl.replace("const", ""), p.name)})cmd->u.${to_struct_field_name(c.name)}.${to_field_name(p.name)}); -% elif '*' in p.decl: - ${get_struct_free(c, p, types)} -% endif -% endfor + vk_free_${to_underscore(c.name)}(queue, cmd); break; % if c.guard is not None: #endif // ${c.guard} % endif % endfor } - vk_free(queue->alloc, cmd); } } @@ -403,7 +422,7 @@ def get_array_copy(command, param): field_size = "1" else: field_size = "sizeof(*%s)" % field_name - allocation = "%s = vk_zalloc(queue->alloc, %s * %s, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);" % (field_name, field_size, param.len) + allocation = "%s = vk_zalloc(queue->alloc, %s * %s, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);\n if (%s == NULL) goto err;\n" % (field_name, field_size, param.len, field_name) const_cast = remove_suffix(param.decl.replace("const", ""), param.name) copy = "memcpy((%s)%s, %s, %s * %s);" % (const_cast, field_name, param.name, field_size, param.len) return "%s\n %s" % (allocation, copy) @@ -414,7 +433,7 @@ def get_array_member_copy(struct, src_name, member): field_size = "sizeof(*%s)" % (field_name) else: field_size = "sizeof(*%s) * %s->%s" % (field_name, struct, member.len) - allocation = "%s = vk_zalloc(queue->alloc, %s, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);" % (field_name, field_size) + allocation = "%s = vk_zalloc(queue->alloc, %s, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);\n if (%s == NULL) goto err;\n" % (field_name, field_size, field_name) const_cast = remove_suffix(member.decl.replace("const", ""), member.name) copy = "memcpy((%s)%s, %s->%s, %s);" % (const_cast, field_name, src_name, member.name, field_size) return "if (%s->%s) {\n %s\n %s\n}\n" % (src_name, member.name, allocation, copy) @@ -444,7 +463,7 @@ def get_struct_copy(dst, src_name, src_type, size, types, level=0): global tmp_dst_idx global tmp_src_idx - allocation = "%s = vk_zalloc(queue->alloc, %s, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);" % (dst, size) + allocation = "%s = vk_zalloc(queue->alloc, %s, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);\n if (%s == NULL) goto err;\n" % (dst, size, dst) copy = "memcpy((void*)%s, %s, %s);" % (dst, src_name, size) level += 1