aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2023-04-14 15:49:43 +0200
committerSimon Zeni <simon@bl4ckb0ne.ca>2023-04-28 15:36:39 +0000
commitf5a5712a026340a4aa3204ca4fec668f32d9ac61 (patch)
treefd979c86c7e9254195872dc1621102ebb9457c84
parent6830bfc17fd94709e2cdd4da0af989f102a26e59 (diff)
render/vulkan: use VK_KHR_synchronization2
This simplifies the vkQueueSubmit call, removing the need to pass timeline semaphore point values as separate arrays.
-rw-r--r--include/render/vulkan.h1
-rw-r--r--render/vulkan/renderer.c111
-rw-r--r--render/vulkan/vulkan.c7
3 files changed, 61 insertions, 58 deletions
diff --git a/include/render/vulkan.h b/include/render/vulkan.h
index 1071c20b..01565cb6 100644
--- a/include/render/vulkan.h
+++ b/include/render/vulkan.h
@@ -50,6 +50,7 @@ struct wlr_vk_device {
PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR;
PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
+ PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR;
} api;
uint32_t format_prop_count;
diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c
index 8d93e936..658cc4b7 100644
--- a/render/vulkan/renderer.c
+++ b/render/vulkan/renderer.c
@@ -919,7 +919,7 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
unsigned barrier_count = wl_list_length(&renderer->foreign_textures) + 1;
VkImageMemoryBarrier *acquire_barriers = calloc(barrier_count, sizeof(VkImageMemoryBarrier));
VkImageMemoryBarrier *release_barriers = calloc(barrier_count, sizeof(VkImageMemoryBarrier));
- VkSemaphore *render_wait = calloc(barrier_count * WLR_DMABUF_MAX_PLANES, sizeof(VkSemaphore));
+ VkSemaphoreSubmitInfoKHR *render_wait = calloc(barrier_count * WLR_DMABUF_MAX_PLANES, sizeof(VkSemaphoreSubmitInfoKHR));
if (acquire_barriers == NULL || release_barriers == NULL || render_wait == NULL) {
wlr_log_errno(WLR_ERROR, "Allocation failed");
free(acquire_barriers);
@@ -976,7 +976,11 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) {
if (texture->foreign_semaphores[i] != VK_NULL_HANDLE) {
assert(render_wait_len < barrier_count * WLR_DMABUF_MAX_PLANES);
- render_wait[render_wait_len++] = texture->foreign_semaphores[i];
+ render_wait[render_wait_len++] = (VkSemaphoreSubmitInfoKHR){
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
+ .semaphore = texture->foreign_semaphores[i],
+ .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR,
+ };
}
}
}
@@ -1037,22 +1041,6 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
free(acquire_barriers);
free(release_barriers);
- VkSubmitInfo submit_infos[2] = {0};
- VkSubmitInfo *stage_sub = &submit_infos[0];
- VkSubmitInfo *render_sub = &submit_infos[1];
-
- VkPipelineStageFlags *render_wait_stages = NULL;
- if (render_wait_len > 0) {
- render_wait_stages = calloc(render_wait_len, sizeof(VkPipelineStageFlags));
- if (render_wait_stages == NULL) {
- wlr_log(WLR_ERROR, "Allocation failed");
- return;
- }
- for (size_t i = 0; i < render_wait_len; i++) {
- render_wait_stages[i] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
- }
- }
-
// No semaphores needed here.
// We don't need a semaphore from the stage/transfer submission
// to the render submissions since they are on the same queue
@@ -1062,30 +1050,34 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
return;
}
- VkTimelineSemaphoreSubmitInfoKHR stage_timeline_submit_info = {
- .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
- .signalSemaphoreValueCount = 1,
- .pSignalSemaphoreValues = &stage_timeline_point,
+ VkCommandBufferSubmitInfoKHR stage_cb_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR,
+ .commandBuffer = stage_cb->vk,
};
- *stage_sub = (VkSubmitInfo){
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
- .pNext = &stage_timeline_submit_info,
- .commandBufferCount = 1,
- .pCommandBuffers = &stage_cb->vk,
- .signalSemaphoreCount = 1,
- .pSignalSemaphores = &renderer->timeline_semaphore,
+ VkSemaphoreSubmitInfoKHR stage_signal = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
+ .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,
};
- uint64_t stage_wait_timeline_point;
- VkPipelineStageFlags stage_wait_stage;
+ VkSemaphoreSubmitInfoKHR stage_wait;
if (renderer->stage.last_timeline_point > 0) {
- stage_wait_timeline_point = renderer->stage.last_timeline_point;
- stage_wait_stage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
- stage_sub->waitSemaphoreCount = 1;
- stage_sub->pWaitSemaphores = &renderer->timeline_semaphore;
- stage_sub->pWaitDstStageMask = &stage_wait_stage;
- stage_timeline_submit_info.waitSemaphoreValueCount = 1;
- stage_timeline_submit_info.pWaitSemaphoreValues = &stage_wait_timeline_point;
+ stage_wait = (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;
}
renderer->stage.last_timeline_point = stage_timeline_point;
@@ -1096,9 +1088,12 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
}
size_t render_signal_len = 1;
- VkSemaphore render_signal[2] = { renderer->timeline_semaphore };
- uint64_t render_signal_timeline_points[2] = { render_timeline_point };
-
+ VkSemaphoreSubmitInfoKHR render_signal[2] = {0};
+ render_signal[0] = (VkSemaphoreSubmitInfoKHR){
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
+ .semaphore = renderer->timeline_semaphore,
+ .value = render_timeline_point,
+ };
if (renderer->dev->implicit_sync_interop) {
if (render_cb->binary_semaphore == VK_NULL_HANDLE) {
VkExportSemaphoreCreateInfo export_info = {
@@ -1117,28 +1112,28 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
}
}
- render_signal[render_signal_len++] = render_cb->binary_semaphore;
+ render_signal[render_signal_len++] = (VkSemaphoreSubmitInfoKHR){
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
+ .semaphore = render_cb->binary_semaphore,
+ };
}
- VkTimelineSemaphoreSubmitInfoKHR render_timeline_submit_info = {
- .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
- .signalSemaphoreValueCount = render_signal_len,
- .pSignalSemaphoreValues = render_signal_timeline_points,
+ VkCommandBufferSubmitInfoKHR render_cb_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR,
+ .commandBuffer = render_cb->vk,
};
- *render_sub = (VkSubmitInfo){
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
- .pNext = &render_timeline_submit_info,
- .pCommandBuffers = &render_cb->vk,
- .commandBufferCount = 1,
- .waitSemaphoreCount = render_wait_len,
- .pWaitSemaphores = render_wait,
- .pWaitDstStageMask = render_wait_stages,
- .signalSemaphoreCount = render_signal_len,
- .pSignalSemaphores = render_signal,
+ VkSubmitInfo2KHR render_submit = {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR,
+ .waitSemaphoreInfoCount = render_wait_len,
+ .pWaitSemaphoreInfos = render_wait,
+ .commandBufferInfoCount = 1,
+ .pCommandBufferInfos = &render_cb_info,
+ .signalSemaphoreInfoCount = render_signal_len,
+ .pSignalSemaphoreInfos = render_signal,
};
- uint32_t submit_count = sizeof(submit_infos) / sizeof(submit_infos[0]);
- VkResult res = vkQueueSubmit(renderer->dev->queue, submit_count, submit_infos, VK_NULL_HANDLE);
+ VkSubmitInfo2KHR submit_infos[] = { stage_submit, render_submit };
+ VkResult res = renderer->dev->api.vkQueueSubmit2KHR(renderer->dev->queue, 2, submit_infos, VK_NULL_HANDLE);
if (res == VK_ERROR_DEVICE_LOST) {
wlr_log(WLR_ERROR, "vkQueueSubmit failed with VK_ERROR_DEVICE_LOST");
wl_signal_emit_mutable(&wlr_renderer->events.lost, NULL);
diff --git a/render/vulkan/vulkan.c b/render/vulkan/vulkan.c
index c285ea52..e2efee09 100644
--- a/render/vulkan/vulkan.c
+++ b/render/vulkan/vulkan.c
@@ -473,6 +473,7 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini,
VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, // or vulkan 1.2
+ VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, // or vulkan 1.3
};
size_t extensions_len = sizeof(extensions) / sizeof(extensions[0]);
@@ -547,8 +548,13 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini,
.pQueuePriorities = &prio,
};
+ VkPhysicalDeviceSynchronization2FeaturesKHR sync2_features = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR,
+ .synchronization2 = VK_TRUE,
+ };
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_features = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR,
+ .pNext = &sync2_features,
.timelineSemaphore = VK_TRUE,
};
VkDeviceCreateInfo dev_info = {
@@ -575,6 +581,7 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini,
&dev->api.vkGetSemaphoreCounterValueKHR);
load_device_proc(dev, "vkGetSemaphoreFdKHR", &dev->api.vkGetSemaphoreFdKHR);
load_device_proc(dev, "vkImportSemaphoreFdKHR", &dev->api.vkImportSemaphoreFdKHR);
+ load_device_proc(dev, "vkQueueSubmit2KHR", &dev->api.vkQueueSubmit2KHR);
// - check device format support -
size_t max_fmts;