Allow drivers to add a list of semaphores to wait on when queuing a image to present.
Signed-off-by: Louis-Francis Ratté-Boulianne <l...@collabora.com> --- src/amd/vulkan/radv_wsi.c | 2 +- src/intel/vulkan/anv_wsi.c | 2 ++ src/vulkan/wsi/wsi_common.h | 6 +++++ src/vulkan/wsi/wsi_common_wayland.c | 2 ++ src/vulkan/wsi/wsi_common_x11.c | 50 +++++++++++++++++++++++++++++++++++-- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index 31448ae981..d73a5766d1 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -575,7 +575,7 @@ VkResult radv_QueuePresentKHR( if (regions && regions->pRegions) region = ®ions->pRegions[i]; - item_result = swapchain->queue_present(swapchain, + item_result = swapchain->queue_present(swapchain, NULL, 0, pPresentInfo->pImageIndices[i], region); /* TODO: What if one of them returns OUT_OF_DATE? */ diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 978a66896f..2e05c3b07b 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -472,6 +472,8 @@ VkResult anv_QueuePresentKHR( anv_QueueSubmit(_queue, 0, NULL, swapchain->fences[0]); item_result = swapchain->queue_present(swapchain, + NULL, + 0, pPresentInfo->pImageIndices[i], region); /* TODO: What if one of them returns OUT_OF_DATE? */ diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 99836054ca..e81c7be11a 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -57,6 +57,10 @@ struct wsi_image_fns { void (*free_wsi_image)(VkDevice device, const VkAllocationCallbacks *pAllocator, struct wsi_image_base *image); + VkResult (*get_semaphores_fd)(VkDevice device, + const VkSemaphore *semaphores, + uint32_t semaphore_count, + int *fd); }; struct wsi_swapchain { @@ -79,6 +83,8 @@ struct wsi_swapchain { uint64_t timeout, VkSemaphore semaphore, uint32_t *image_index); VkResult (*queue_present)(struct wsi_swapchain *swap_chain, + const VkSemaphore *semaphores, + uint32_t semaphore_count, uint32_t image_index, const VkPresentRegionKHR *damage); void (*get_image_and_linear)(struct wsi_swapchain *swapchain, diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index b4dd2d7ff0..6cafa8f178 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -720,6 +720,8 @@ static const struct wl_callback_listener frame_listener = { static VkResult wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, + const VkSemaphore *semaphores, + uint32_t semaphore_count, uint32_t image_index, const VkPresentRegionKHR *damage) { diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index d9467092d2..1179eed9c7 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -654,6 +654,7 @@ struct x11_image { xcb_pixmap_t pixmap; bool busy; struct xshmfence * shm_fence; + uint32_t wait_fence; uint32_t sync_fence; }; @@ -745,6 +746,14 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain, for (unsigned i = 0; i < chain->base.image_count; i++) { if (chain->images[i].pixmap == idle->pixmap) { chain->images[i].busy = false; + if (chain->images[i].wait_fence) { + xcb_void_cookie_t cookie; + + cookie = xcb_sync_destroy_fence(chain->conn, chain->images[i].wait_fence); + xcb_discard_reply(chain->conn, cookie.sequence); + xcb_flush(chain->conn); + chain->images[i].wait_fence = 0; + } if (chain->threaded) wsi_queue_push(&chain->acquire_queue, i); break; @@ -907,13 +916,14 @@ x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index, 0, /* x_off */ 0, /* y_off */ XCB_NONE, /* target_crtc */ - XCB_NONE, + image->wait_fence, image->sync_fence, options, target_msc, divisor, remainder, 0, NULL); xcb_discard_reply(chain->conn, cookie.sequence); + image->busy = true; xcb_flush(chain->conn); @@ -945,11 +955,39 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain, static VkResult x11_queue_present(struct wsi_swapchain *anv_chain, + const VkSemaphore *semaphores, + uint32_t semaphore_count, uint32_t image_index, const VkPresentRegionKHR *damage) { struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; VkResult result; + struct x11_image *image = &chain->images[image_index]; + +#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 2 + if (chain->has_dma_fence) { + int merged_fence_fd = -1; + VkResult ret; + + ret = chain->base.image_fns->get_semaphores_fd(anv_chain->device, + semaphores, + semaphore_count, + &merged_fence_fd); + if (ret != VK_SUCCESS) { + return ret; + } + + if (merged_fence_fd > -1) { + image->wait_fence = xcb_generate_id(chain->conn); + xcb_dri3_fence_from_dma_fence_fd(chain->conn, + image->pixmap, + image->wait_fence, + merged_fence_fd); + xcb_flush(chain->conn); + close(merged_fence_fd); + } + } +#endif if (chain->threaded) { wsi_queue_push(&chain->present_queue, image_index); @@ -1118,6 +1156,9 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, if (chain->has_present_v1_2 && chain->has_dri3_v1_2) wsi_x11_get_present_capabilities(chain); + image->wait_fence = 0; + image->busy = false; + int fence_fd = xshmfence_alloc_shm(); if (fence_fd < 0) goto fail_pixmap; @@ -1133,7 +1174,6 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, false, fence_fd); - image->busy = false; xshmfence_trigger(image->shm_fence); return VK_SUCCESS; @@ -1161,6 +1201,12 @@ x11_image_finish(struct x11_swapchain *chain, xcb_discard_reply(chain->conn, cookie.sequence); xshmfence_unmap_shm(image->shm_fence); + if (image->wait_fence) { + cookie = xcb_sync_destroy_fence(chain->conn, image->wait_fence); + xcb_discard_reply(chain->conn, cookie.sequence); + image->wait_fence = 0; + } + cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); -- 2.13.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev