From a59dd1d567bfdac639c1045d2e0ecd58ead3c986 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 24 Nov 2023 18:08:36 +0100 Subject: [PATCH] render/vulkan: add upload timeline semaphore Doesn't do much at the moment, since it's always signalled when we submit the stage buffer. --- include/render/vulkan.h | 4 ++++ render/vulkan/pass.c | 35 +++++++++++++++++++++++------------ render/vulkan/renderer.c | 7 +++++++ render/vulkan/texture.c | 14 ++++++++++++++ render/vulkan/vulkan.c | 2 ++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/include/render/vulkan.h b/include/render/vulkan.h index a518ee4a8..1f12ab4da 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -51,6 +51,7 @@ struct wlr_vk_device { PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR; PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR; PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR; + PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR; PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR; PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR; PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR; @@ -252,6 +253,9 @@ struct wlr_vk_renderer { VkSemaphore timeline_semaphore; uint64_t timeline_point; + VkSemaphore upload_timeline_semaphore; + uint64_t upload_timeline_point; + size_t last_pool_size; struct wl_list descriptor_pools; // wlr_vk_descriptor_pool.link struct wl_list render_format_setups; // wlr_vk_render_format_setup.link diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 42bd6b4e1..4fe8ce5ac 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -296,27 +296,38 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { .semaphore = renderer->timeline_semaphore, .value = stage_timeline_point, }; - VkSubmitInfo2KHR stage_submit = { - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR, - .commandBufferInfoCount = 1, - .pCommandBufferInfos = &stage_cb_info, - .signalSemaphoreInfoCount = 1, - .pSignalSemaphoreInfos = &stage_signal, - }; - VkSemaphoreSubmitInfoKHR stage_wait; + VkSemaphoreSubmitInfoKHR stage_wait[2]; + uint32_t stage_wait_len = 0; + + if (renderer->upload_timeline_point > 0) { + stage_wait[stage_wait_len++] = (VkSemaphoreSubmitInfoKHR){ + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, + .semaphore = renderer->upload_timeline_semaphore, + .value = renderer->upload_timeline_point, + .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, + }; + } + if (renderer->stage.last_timeline_point > 0) { - stage_wait = (VkSemaphoreSubmitInfoKHR){ + stage_wait[stage_wait_len++] = (VkSemaphoreSubmitInfoKHR){ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, .semaphore = renderer->timeline_semaphore, .value = renderer->stage.last_timeline_point, .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, }; - - stage_submit.waitSemaphoreInfoCount = 1; - stage_submit.pWaitSemaphoreInfos = &stage_wait; } + VkSubmitInfo2KHR stage_submit = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR, + .commandBufferInfoCount = 1, + .pCommandBufferInfos = &stage_cb_info, + .waitSemaphoreInfoCount = stage_wait_len, + .pWaitSemaphoreInfos = stage_wait, + .signalSemaphoreInfoCount = 1, + .pSignalSemaphoreInfos = &stage_signal, + }; + renderer->stage.last_timeline_point = stage_timeline_point; uint64_t render_timeline_point = vulkan_end_command_buffer(render_cb, renderer); diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index b3f764017..63fad5e3b 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -1047,6 +1047,7 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) { } vkDestroySemaphore(dev->dev, renderer->timeline_semaphore, NULL); + vkDestroySemaphore(dev->dev, renderer->upload_timeline_semaphore, NULL); vkDestroyPipelineLayout(dev->dev, renderer->output_pipe_layout, NULL); vkDestroyDescriptorSetLayout(dev->dev, renderer->output_ds_layout, NULL); vkDestroyCommandPool(dev->dev, renderer->command_pool, NULL); @@ -2193,6 +2194,12 @@ struct wlr_renderer *vulkan_renderer_create_for_device(struct wlr_vk_device *dev wlr_vk_error("vkCreateSemaphore", res); goto error; } + res = vkCreateSemaphore(dev->dev, &semaphore_info, NULL, + &renderer->upload_timeline_semaphore); + if (res != VK_SUCCESS) { + wlr_vk_error("vkCreateSemaphore", res); + goto error; + } return &renderer->wlr_renderer; diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c index 20aa12f1e..35dd8e50f 100644 --- a/render/vulkan/texture.c +++ b/render/vulkan/texture.c @@ -81,6 +81,8 @@ static bool write_pixels(struct wlr_vk_texture *texture, return false; } + uint64_t timeline_point = ++renderer->upload_timeline_point; + void *vmap; res = vkMapMemory(dev, span.buffer->memory, span.alloc.start, bsize, 0, &vmap); @@ -141,6 +143,18 @@ static bool write_pixels(struct wlr_vk_texture *texture, assert((uint32_t)(map - (char *)vmap) == bsize); vkUnmapMemory(dev, span.buffer->memory); + VkSemaphoreSignalInfoKHR signal_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR, + .semaphore = renderer->upload_timeline_semaphore, + .value = timeline_point, + }; + res = renderer->dev->api.vkSignalSemaphoreKHR(renderer->dev->dev, &signal_info); + if (res != VK_SUCCESS) { + free(copies); + wlr_vk_error("vkMapMemory", res); + return false; + } + // record staging cb // will be executed before next frame VkCommandBuffer cb = vulkan_record_stage_cb(renderer); diff --git a/render/vulkan/vulkan.c b/render/vulkan/vulkan.c index b8ba0b480..67a720e00 100644 --- a/render/vulkan/vulkan.c +++ b/render/vulkan/vulkan.c @@ -617,6 +617,8 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini, load_device_proc(dev, "vkWaitSemaphoresKHR", &dev->api.vkWaitSemaphoresKHR); load_device_proc(dev, "vkGetSemaphoreCounterValueKHR", &dev->api.vkGetSemaphoreCounterValueKHR); + load_device_proc(dev, "vkSignalSemaphoreKHR", + &dev->api.vkSignalSemaphoreKHR); load_device_proc(dev, "vkGetSemaphoreFdKHR", &dev->api.vkGetSemaphoreFdKHR); load_device_proc(dev, "vkImportSemaphoreFdKHR", &dev->api.vkImportSemaphoreFdKHR); load_device_proc(dev, "vkQueueSubmit2KHR", &dev->api.vkQueueSubmit2KHR);