[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