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
This commit is contained in:
Simon Ser 2022-11-04 16:54:49 +01:00
parent a8a194d695
commit f1eae0eeeb
3 changed files with 165 additions and 39 deletions

View file

@ -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;