render/vulkan: use command buffer pool for stage

This commit is contained in:
Simon Ser 2022-11-04 17:20:41 +01:00
parent f1eae0eeeb
commit 7fdcb45e66
2 changed files with 45 additions and 44 deletions

View file

@ -194,8 +194,7 @@ struct wlr_vk_renderer {
struct wlr_vk_command_buffer command_buffers[VULKAN_COMMAND_BUFFERS_CAP]; struct wlr_vk_command_buffer command_buffers[VULKAN_COMMAND_BUFFERS_CAP];
struct { struct {
VkCommandBuffer cb; struct wlr_vk_command_buffer *cb;
bool recording;
struct wl_list buffers; // wlr_vk_shared_buffer.link struct wl_list buffers; // wlr_vk_shared_buffer.link
} stage; } stage;

View file

@ -329,38 +329,52 @@ error_alloc:
}; };
} }
static struct wlr_vk_command_buffer *acquire_command_buffer(
struct wlr_vk_renderer *renderer);
static uint64_t end_command_buffer(struct wlr_vk_command_buffer *cb,
struct wlr_vk_renderer *renderer);
static bool wait_command_buffer(struct wlr_vk_command_buffer *cb,
struct wlr_vk_renderer *renderer);
VkCommandBuffer vulkan_record_stage_cb(struct wlr_vk_renderer *renderer) { VkCommandBuffer vulkan_record_stage_cb(struct wlr_vk_renderer *renderer) {
if (!renderer->stage.recording) { if (renderer->stage.cb == NULL) {
renderer->stage.cb = acquire_command_buffer(renderer);
if (renderer->stage.cb == NULL) {
return VK_NULL_HANDLE;
}
VkCommandBufferBeginInfo begin_info = { VkCommandBufferBeginInfo begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
}; };
vkBeginCommandBuffer(renderer->stage.cb, &begin_info); vkBeginCommandBuffer(renderer->stage.cb->vk, &begin_info);
renderer->stage.recording = true;
} }
return renderer->stage.cb; return renderer->stage.cb->vk;
} }
bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer) { bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer) {
if (!renderer->stage.recording) { if (renderer->stage.cb == NULL) {
return false; return false;
} }
vkEndCommandBuffer(renderer->stage.cb); struct wlr_vk_command_buffer *cb = renderer->stage.cb;
renderer->stage.recording = false; renderer->stage.cb = NULL;
renderer->timeline_point++; uint64_t timeline_point = end_command_buffer(cb, renderer);
if (timeline_point == 0) {
return false;
}
VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info = { VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info = {
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
.signalSemaphoreValueCount = 1, .signalSemaphoreValueCount = 1,
.pSignalSemaphoreValues = &renderer->timeline_point, .pSignalSemaphoreValues = &timeline_point,
}; };
VkSubmitInfo submit_info = { VkSubmitInfo submit_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = &timeline_submit_info, .pNext = &timeline_submit_info,
.commandBufferCount = 1, .commandBufferCount = 1,
.pCommandBuffers = &renderer->stage.cb, .pCommandBuffers = &cb->vk,
.signalSemaphoreCount = 1, .signalSemaphoreCount = 1,
.pSignalSemaphores = &renderer->timeline_semaphore, .pSignalSemaphores = &renderer->timeline_semaphore,
}; };
@ -370,22 +384,10 @@ bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer) {
return false; return false;
} }
VkSemaphoreWaitInfoKHR wait_info = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR,
.semaphoreCount = 1,
.pSemaphores = &renderer->timeline_semaphore,
.pValues = &renderer->timeline_point,
};
res = renderer->dev->api.waitSemaphoresKHR(renderer->dev->dev, &wait_info, UINT64_MAX);
if (res != VK_SUCCESS) {
wlr_vk_error("vkWaitSemaphoresKHR", res);
return false;
}
// NOTE: don't release stage allocations here since they may still be // NOTE: don't release stage allocations here since they may still be
// used for reading. Will be done next frame. // used for reading. Will be done next frame.
return true; return wait_command_buffer(cb, renderer);
} }
struct wlr_vk_format_props *vulkan_format_props_from_drm( struct wlr_vk_format_props *vulkan_format_props_from_drm(
@ -849,16 +851,30 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
unsigned submit_count = 0u; unsigned submit_count = 0u;
VkSubmitInfo submit_infos[2] = {0}; VkSubmitInfo submit_infos[2] = {0};
struct wlr_vk_command_buffer *stage_cb = renderer->stage.cb;
renderer->stage.cb = NULL;
// No semaphores needed here. // No semaphores needed here.
// We don't need a semaphore from the stage/transfer submission // We don't need a semaphore from the stage/transfer submission
// to the render submissions since they are on the same queue // to the render submissions since they are on the same queue
// and we have a renderpass dependency for that. // and we have a renderpass dependency for that.
if (renderer->stage.recording) { uint64_t stage_timeline_point;
vkEndCommandBuffer(renderer->stage.cb); VkTimelineSemaphoreSubmitInfoKHR stage_timeline_submit_info;
renderer->stage.recording = false; if (stage_cb != NULL) {
stage_timeline_point = end_command_buffer(stage_cb, renderer);
if (stage_timeline_point == 0) {
return;
}
stage_timeline_submit_info = (VkTimelineSemaphoreSubmitInfoKHR){
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
.signalSemaphoreValueCount = 1,
.pSignalSemaphoreValues = &stage_timeline_point,
};
VkSubmitInfo *stage_sub = &submit_infos[submit_count]; VkSubmitInfo *stage_sub = &submit_infos[submit_count];
stage_sub->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; stage_sub->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
stage_sub->pNext = &stage_timeline_submit_info;
stage_sub->commandBufferCount = 1u; stage_sub->commandBufferCount = 1u;
stage_sub->pCommandBuffers = &pre_cb; stage_sub->pCommandBuffers = &pre_cb;
++submit_count; ++submit_count;
@ -869,7 +885,7 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
return; return;
} }
VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info = { VkTimelineSemaphoreSubmitInfoKHR render_timeline_submit_info = {
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
.signalSemaphoreValueCount = 1, .signalSemaphoreValueCount = 1,
.pSignalSemaphoreValues = &render_timeline_point, .pSignalSemaphoreValues = &render_timeline_point,
@ -877,7 +893,7 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
VkSubmitInfo *render_sub = &submit_infos[submit_count]; VkSubmitInfo *render_sub = &submit_infos[submit_count];
render_sub->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; render_sub->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
render_sub->pNext = &timeline_submit_info; render_sub->pNext = &render_timeline_submit_info;
render_sub->pCommandBuffers = &render_cb->vk; render_sub->pCommandBuffers = &render_cb->vk;
render_sub->commandBufferCount = 1u; render_sub->commandBufferCount = 1u;
render_sub->signalSemaphoreCount = 1; render_sub->signalSemaphoreCount = 1;
@ -1893,20 +1909,6 @@ struct wlr_renderer *vulkan_renderer_create_for_device(struct wlr_vk_device *dev
goto error; goto error;
} }
// staging command buffer
VkCommandBufferAllocateInfo cmd_buf_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = renderer->command_pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1u,
};
res = vkAllocateCommandBuffers(dev->dev, &cmd_buf_info,
&renderer->stage.cb);
if (res != VK_SUCCESS) {
wlr_vk_error("vkAllocateCommandBuffers", res);
goto error;
}
return &renderer->wlr_renderer; return &renderer->wlr_renderer;
error: error: