render/vulkan: add upload timeline semaphore

Doesn't do much at the moment, since it's always signalled when
we submit the stage buffer.
This commit is contained in:
Simon Ser 2023-11-24 18:08:36 +01:00
parent 361804c727
commit a59dd1d567
5 changed files with 50 additions and 12 deletions

View file

@ -51,6 +51,7 @@ struct wlr_vk_device {
PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR; PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR;
PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR; PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR;
PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR; PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR;
PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR;
PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR; PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR; PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR; PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR;
@ -252,6 +253,9 @@ struct wlr_vk_renderer {
VkSemaphore timeline_semaphore; VkSemaphore timeline_semaphore;
uint64_t timeline_point; uint64_t timeline_point;
VkSemaphore upload_timeline_semaphore;
uint64_t upload_timeline_point;
size_t last_pool_size; size_t last_pool_size;
struct wl_list descriptor_pools; // wlr_vk_descriptor_pool.link struct wl_list descriptor_pools; // wlr_vk_descriptor_pool.link
struct wl_list render_format_setups; // wlr_vk_render_format_setup.link struct wl_list render_format_setups; // wlr_vk_render_format_setup.link

View file

@ -296,27 +296,38 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
.semaphore = renderer->timeline_semaphore, .semaphore = renderer->timeline_semaphore,
.value = stage_timeline_point, .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) { if (renderer->stage.last_timeline_point > 0) {
stage_wait = (VkSemaphoreSubmitInfoKHR){ stage_wait[stage_wait_len++] = (VkSemaphoreSubmitInfoKHR){
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
.semaphore = renderer->timeline_semaphore, .semaphore = renderer->timeline_semaphore,
.value = renderer->stage.last_timeline_point, .value = renderer->stage.last_timeline_point,
.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, .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; renderer->stage.last_timeline_point = stage_timeline_point;
uint64_t render_timeline_point = vulkan_end_command_buffer(render_cb, renderer); uint64_t render_timeline_point = vulkan_end_command_buffer(render_cb, renderer);

View file

@ -1047,6 +1047,7 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) {
} }
vkDestroySemaphore(dev->dev, renderer->timeline_semaphore, NULL); vkDestroySemaphore(dev->dev, renderer->timeline_semaphore, NULL);
vkDestroySemaphore(dev->dev, renderer->upload_timeline_semaphore, NULL);
vkDestroyPipelineLayout(dev->dev, renderer->output_pipe_layout, NULL); vkDestroyPipelineLayout(dev->dev, renderer->output_pipe_layout, NULL);
vkDestroyDescriptorSetLayout(dev->dev, renderer->output_ds_layout, NULL); vkDestroyDescriptorSetLayout(dev->dev, renderer->output_ds_layout, NULL);
vkDestroyCommandPool(dev->dev, renderer->command_pool, 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); wlr_vk_error("vkCreateSemaphore", res);
goto error; 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; return &renderer->wlr_renderer;

View file

@ -81,6 +81,8 @@ static bool write_pixels(struct wlr_vk_texture *texture,
return false; return false;
} }
uint64_t timeline_point = ++renderer->upload_timeline_point;
void *vmap; void *vmap;
res = vkMapMemory(dev, span.buffer->memory, span.alloc.start, res = vkMapMemory(dev, span.buffer->memory, span.alloc.start,
bsize, 0, &vmap); bsize, 0, &vmap);
@ -141,6 +143,18 @@ static bool write_pixels(struct wlr_vk_texture *texture,
assert((uint32_t)(map - (char *)vmap) == bsize); assert((uint32_t)(map - (char *)vmap) == bsize);
vkUnmapMemory(dev, span.buffer->memory); 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 // record staging cb
// will be executed before next frame // will be executed before next frame
VkCommandBuffer cb = vulkan_record_stage_cb(renderer); VkCommandBuffer cb = vulkan_record_stage_cb(renderer);

View file

@ -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, "vkWaitSemaphoresKHR", &dev->api.vkWaitSemaphoresKHR);
load_device_proc(dev, "vkGetSemaphoreCounterValueKHR", load_device_proc(dev, "vkGetSemaphoreCounterValueKHR",
&dev->api.vkGetSemaphoreCounterValueKHR); &dev->api.vkGetSemaphoreCounterValueKHR);
load_device_proc(dev, "vkSignalSemaphoreKHR",
&dev->api.vkSignalSemaphoreKHR);
load_device_proc(dev, "vkGetSemaphoreFdKHR", &dev->api.vkGetSemaphoreFdKHR); load_device_proc(dev, "vkGetSemaphoreFdKHR", &dev->api.vkGetSemaphoreFdKHR);
load_device_proc(dev, "vkImportSemaphoreFdKHR", &dev->api.vkImportSemaphoreFdKHR); load_device_proc(dev, "vkImportSemaphoreFdKHR", &dev->api.vkImportSemaphoreFdKHR);
load_device_proc(dev, "vkQueueSubmit2KHR", &dev->api.vkQueueSubmit2KHR); load_device_proc(dev, "vkQueueSubmit2KHR", &dev->api.vkQueueSubmit2KHR);