summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2022-11-02 21:14:02 +0100
committerDylan Baker <dylan.c.baker@intel.com>2022-11-14 12:00:20 -0800
commitcce6fffe18b13f90be46c2a12b27cdc624dc004f (patch)
treebde2dda2a305358881facbf0dc691e76da9cd6ce
parent1c54e9a8164d5940ddd1ab869c7884f25087de67 (diff)
downloadmesa-cce6fffe18b13f90be46c2a12b27cdc624dc004f.tar.gz
vulkan/wsi/display: Reset connector state in vkReleaseDisplay().
If an application was transitioning out of fullscreen exclusive display mode, the wsi_display_connector->active state was not reset in vkReleaseDisplay() from fullscreen. When the app then later tried to go to fullscreen display mode again on the same display output with the same video mode, this caused _wsi_display_queue_next() to skip a required drmModeSetCrtc() during the first vkQueuePresent() after entering direct display mode. While this often worked by pure luck on a single-display setup, it goes sideways on a multi-display setup where the viewport of the associated crtc does not have a (x,y) offset of (0,0). E.g., XOrg/X11 RandR output leasing of an output whose viewport starts at x = 1920: 1. X-Server has RandR outputs viewport at x = 1920, in a shared framebuffer, shared across all crtc's on a X-Screen. 2. Application leases that output for direct display mode, 1st vkQueuePresent() triggers drmModeSetCrtc() of output to (x,y) = 0,0, as required for Vulkan/wsi/direct framebuffer setup. 3. Application does rendering and presenting. 4. Application vkReleaseDisplay() the output, terminates the RandR lease. X-Server takes over again. 5. X-Server modesets to reconfigure output back to viewport with (x,y) = 1920, 0. 6. Application leases same output again later on, and tries vkQueuePresent() again. Because of the bug fixed in this commit, the required drmModeSetCrtc() to (x,y) = 0,0 is erroneously skipped due to the stale cached connector state. 7. drmModePageflip() fails due to the wrong crtc viewport (x,y) = 1920, 0, mismatched for the need of the Vulkan framebuffer of (x,y) = 0,0. Kernel returns -ENOSPACE, Swapchain goes into permanent VK_ERROR_SURFACE_LOST state. Destroying and recreating the swapchain, as recommended by the Vulkan spec for error handling won't help. Game over! Resetting wsi_display_connector->active = false; fixes the problem of wrong / stale connector state and Vulkan/wsi/display clients are happy on multi-display setups again, as tested in various single- and multi-display configurations. This bug affects all Mesa releases with Vulkan/WSI/Display support and should therefore be backported. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Fixes: 352d320a0745 ("vulkan: Add EXT_direct_mode_display [v2]") Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19484> (cherry picked from commit 24094ee03d625fbcd2d154e8c2dd5434ba88f166)
-rw-r--r--.pick_status.json2
-rw-r--r--src/vulkan/wsi/wsi_common_display.c2
2 files changed, 3 insertions, 1 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 97b395874f2..4bcf1598857 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -2209,7 +2209,7 @@
"description": "vulkan/wsi/display: Reset connector state in vkReleaseDisplay().",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": "352d320a07458eb05e4929fdc1e0d1dbe1b07dda"
},
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 418ef6e1481..6421a3d58a5 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -2243,6 +2243,8 @@ wsi_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice,
wsi->fd = -1;
}
+ wsi_display_connector_from_handle(display)->active = false;
+
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
wsi_display_connector_from_handle(display)->output = None;
#endif