[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 = ®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 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