[RFC v3 22/22] vulkan/wsi: Return VK_SUBOPTIMAL_KHR when X11 window is moved

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Wed Sep 27 05:28:52 UTC 2017


When it is detected that a window has changed CRTC, the
current format modifier for the surface might no longer be
optimal (e.g. it might not allow direct scanout on the new
CRTC). The Vulkan client should then re-create the swapchain.

Note: It might be more performant to actually check the
new optimal modifiers instead of just assuming they have
changed.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
 src/vulkan/wsi/wsi_common_x11.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 1c4267f22d..2dcc92dc90 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -655,6 +655,7 @@ struct x11_swapchain {
 
    bool                                         threaded;
    VkResult                                     status;
+   bool                                         crtc_changed;
    struct wsi_queue                             present_queue;
    struct wsi_queue                             acquire_queue;
    pthread_t                                    queue_manager;
@@ -734,6 +735,11 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain,
       break;
    }
 
+   case XCB_PRESENT_WINDOW_CRTC_NOTIFY: {
+      chain->crtc_changed = true;
+      break;
+   }
+
    default:
       break;
    }
@@ -894,11 +900,18 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
                        uint32_t *image_index)
 {
    struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+   VkResult result;
 
    if (chain->threaded) {
-      return x11_acquire_next_image_from_queue(chain, image_index, timeout);
+      result = x11_acquire_next_image_from_queue(chain, image_index, timeout);
+   } else {
+      result = x11_acquire_next_image_poll_x11(chain, image_index, timeout);
+   }
+
+   if (result != VK_SUCCESS) {
+      return result;
    } else {
-      return x11_acquire_next_image_poll_x11(chain, image_index, timeout);
+      return chain->crtc_changed ? VK_SUBOPTIMAL_KHR : VK_SUCCESS;
    }
 }
 
@@ -908,12 +921,19 @@ x11_queue_present(struct wsi_swapchain *anv_chain,
                   const VkPresentRegionKHR *damage)
 {
    struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+   VkResult result;
 
    if (chain->threaded) {
       wsi_queue_push(&chain->present_queue, image_index);
-      return chain->status;
+      result = chain->status;
+   } else {
+      result = x11_present_to_x11(chain, image_index, 0);
+   }
+
+   if (result != VK_SUCCESS) {
+      return result;
    } else {
-      return x11_present_to_x11(chain, image_index, 0);
+      return chain->crtc_changed ? VK_SUBOPTIMAL_KHR : VK_SUCCESS;
    }
 }
 
@@ -1245,6 +1265,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
    chain->last_present_msc = 0;
    chain->threaded = false;
    chain->status = VK_SUCCESS;
+   chain->crtc_changed = false;
 
    free(geometry);
 
@@ -1267,7 +1288,8 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
    xcb_present_select_input(chain->conn, chain->event_id, chain->window,
                             XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
                             XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
-                            XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);
+                            XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY |
+                            XCB_PRESENT_EVENT_MASK_WINDOW_CRTC_NOTIFY);
 
    /* Create an XCB event queue to hold present events outside of the usual
     * application event queue
-- 
2.13.0



More information about the xorg-devel mailing list