From f1eae0eeebcae0eed8754f6c6db0a14cf8ad401f Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 4 Nov 2022 16:54:49 +0100 Subject: render/vulkan: add a command buffer pool Before re-using a VkCommandBuffer, we need to wait for its operations to complete. Right now we unconditionally wait for rendering to complete in vulkan_end(), however we have plans to fix this [1]. To fully avoid blocking, we need to handle multiple command buffers in flight at the same time (e.g. for multi-output, or for rendering followed by texture uploads). Implement a pool of command buffers. When we need to render, we pick a command buffer from the pool which has completed its operations. If we don't find one, try to allocate a new command buffer. If we don't have slots in the pool anymore, block like we did before. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3574 --- include/render/vulkan.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/render') diff --git a/include/render/vulkan.h b/include/render/vulkan.h index a22d224f..d0a2ad85 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -45,6 +45,7 @@ struct wlr_vk_device { struct { PFN_vkGetMemoryFdPropertiesKHR getMemoryFdPropertiesKHR; PFN_vkWaitSemaphoresKHR waitSemaphoresKHR; + PFN_vkGetSemaphoreCounterValueKHR getSemaphoreCounterValueKHR; } api; uint32_t format_prop_count; @@ -136,6 +137,14 @@ struct wlr_vk_render_buffer { bool transitioned; }; +struct wlr_vk_command_buffer { + VkCommandBuffer vk; + bool recording; + uint64_t timeline_point; +}; + +#define VULKAN_COMMAND_BUFFERS_CAP 64 + // Vulkan wlr_renderer implementation on top of a wlr_vk_device. struct wlr_vk_renderer { struct wlr_renderer wlr_renderer; @@ -156,13 +165,13 @@ struct wlr_vk_renderer { uint64_t timeline_point; struct wlr_vk_render_buffer *current_render_buffer; + struct wlr_vk_command_buffer *current_command_buffer; // current frame id. Used in wlr_vk_texture.last_used // Increased every time a frame is ended for the renderer uint32_t frame; VkRect2D scissor; // needed for clearing - VkCommandBuffer cb; VkPipeline bound_pipe; uint32_t render_width; @@ -181,6 +190,9 @@ struct wlr_vk_renderer { struct wl_list render_buffers; // wlr_vk_render_buffer.link + // Pool of command buffers + struct wlr_vk_command_buffer command_buffers[VULKAN_COMMAND_BUFFERS_CAP]; + struct { VkCommandBuffer cb; bool recording; -- cgit v1.2.3