diff --git a/src/virtio/vulkan/vn_command_buffer.c b/src/virtio/vulkan/vn_command_buffer.c index bd9f1362858..2fe5375502e 100644 --- a/src/virtio/vulkan/vn_command_buffer.c +++ b/src/virtio/vulkan/vn_command_buffer.c @@ -41,25 +41,29 @@ vn_image_memory_barrier_has_present_src( return false; } +static void * +vn_cmd_get_tmp_data(struct vn_command_buffer *cmd, size_t size) +{ + /* avoid shrinking in case of non efficient reallocation implementation */ + if (size > cmd->builder.tmp.size) { + void *data = + vk_realloc(&cmd->allocator, cmd->builder.tmp.data, size, + VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!data) + return NULL; + + cmd->builder.tmp.data = data; + cmd->builder.tmp.size = size; + } + + return cmd->builder.tmp.data; +} + static VkImageMemoryBarrier * vn_cmd_get_image_memory_barriers(struct vn_command_buffer *cmd, uint32_t count) { - /* avoid shrinking in case of non efficient reallocation implementation */ - if (count > cmd->builder.image_barrier_count) { - size_t size = sizeof(VkImageMemoryBarrier) * count; - VkImageMemoryBarrier *img_barriers = - vk_realloc(&cmd->allocator, cmd->builder.image_barriers, size, - VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (!img_barriers) - return NULL; - - /* update upon successful reallocation */ - cmd->builder.image_barrier_count = count; - cmd->builder.image_barriers = img_barriers; - } - - return cmd->builder.image_barriers; + return vn_cmd_get_tmp_data(cmd, count * sizeof(VkImageMemoryBarrier)); } /* About VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, the spec says @@ -605,8 +609,8 @@ vn_FreeCommandBuffers(VkDevice device, if (!cmd) continue; - if (cmd->builder.image_barriers) - vk_free(alloc, cmd->builder.image_barriers); + if (cmd->builder.tmp.data) + vk_free(alloc, cmd->builder.tmp.data); vn_cs_encoder_fini(&cmd->cs); list_del(&cmd->head); diff --git a/src/virtio/vulkan/vn_command_buffer.h b/src/virtio/vulkan/vn_command_buffer.h index 07312e25c3a..3ed16236cb8 100644 --- a/src/virtio/vulkan/vn_command_buffer.h +++ b/src/virtio/vulkan/vn_command_buffer.h @@ -36,9 +36,14 @@ enum vn_command_buffer_state { }; struct vn_command_buffer_builder { - /* for scrubbing VK_IMAGE_LAYOUT_PRESENT_SRC_KHR */ - uint32_t image_barrier_count; - VkImageMemoryBarrier *image_barriers; + /* Temporary storage for scrubbing VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. The + * storage's lifetime is the command buffer's lifetime. We increase the + * storage as needed, but never shrink it. + */ + struct { + void *data; + size_t size; + } tmp; const struct vn_render_pass *render_pass; const struct vn_framebuffer *framebuffer;