[Mesa-dev] [RFC 3/5] vulkan: Add support for in-fences for vkQueuePresent

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Thu Aug 31 05:19:37 UTC 2017


Allow drivers to add a list of semaphores to wait on
when queuing a image to present.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at 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     | 40 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index aa44b7d78a..c69404ddd9 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -516,7 +516,7 @@ VkResult radv_QueuePresentKHR(
 		if (regions && regions->pRegions)
 			region = &regions->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 00edb220b2..2c6c4db4eb 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -426,6 +426,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 8166b7dd34..aee93f6b37 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -47,6 +47,10 @@ struct wsi_image_fns {
                           const VkAllocationCallbacks *pAllocator,
                           VkImage image_h,
                           VkDeviceMemory memory_h);
+   VkResult (*get_semaphores_fd)(VkDevice device,
+                                 const VkSemaphore *semaphores,
+                                 uint32_t semaphore_count,
+                                 int* fd);
 };
 
 struct wsi_swapchain {
@@ -69,6 +73,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 dd283a1211..2867abb77c 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -629,6 +629,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 d132541156..0e6a302f30 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -622,6 +622,7 @@ struct x11_image {
    xcb_pixmap_t                              pixmap;
    bool                                      busy;
    struct xshmfence *                        shm_fence;
+   uint32_t                                  wait_fence;
    uint32_t                                  sync_fence;
 };
 
@@ -708,6 +709,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;
@@ -863,13 +872,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);
@@ -894,10 +904,32 @@ 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;
+   struct x11_image *image = &chain->images[image_index];
+   int merged_fence_fd;
+   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);
+   }
 
    if (chain->threaded) {
       wsi_queue_push(&chain->present_queue, image_index);
@@ -1090,6 +1122,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



More information about the mesa-dev mailing list