mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
vulkan/wsi/x11: Refuse to connect to thread-unsafe Displays
We heavily rely on threading in Vulkan WSI. There's no way this is safe if XInitThreads() hasn't been called. Fortunately, this should never be the case since 2022 or so. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13530 Cc: mesa-stable Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36120>
This commit is contained in:
parent
6286c1c66f
commit
cf654be16b
1 changed files with 39 additions and 0 deletions
|
|
@ -21,6 +21,7 @@
|
|||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <X11/xshmfence.h>
|
||||
#define XK_MISCELLANY
|
||||
|
|
@ -609,18 +610,42 @@ wsi_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
xlib_display_is_thread_safe(Display *dpy)
|
||||
{
|
||||
/* 'lock_fns' is the XLockDisplay function pointer of the X11 display 'dpy'.
|
||||
* It will be NULL if XInitThreads wasn't called.
|
||||
*/
|
||||
return dpy->lock_fns != NULL;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
wsi_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
Display *dpy,
|
||||
VisualID visualID)
|
||||
{
|
||||
/* Our WSI implementation for X11 relies on threads. Check Xlib is running
|
||||
* in thread safe mode before advertising support.
|
||||
*/
|
||||
if (!xlib_display_is_thread_safe(dpy))
|
||||
return false;
|
||||
|
||||
return wsi_GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice,
|
||||
queueFamilyIndex,
|
||||
XGetXCBConnection(dpy),
|
||||
visualID);
|
||||
}
|
||||
|
||||
static bool
|
||||
x11_surface_is_thread_safe(VkIcdSurfaceBase *icd_surface)
|
||||
{
|
||||
if (icd_surface->platform == VK_ICD_WSI_PLATFORM_XLIB)
|
||||
return xlib_display_is_thread_safe(((VkIcdSurfaceXlib *)icd_surface)->dpy);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static xcb_connection_t*
|
||||
x11_surface_get_connection(VkIcdSurfaceBase *icd_surface)
|
||||
{
|
||||
|
|
@ -645,6 +670,11 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface,
|
|||
uint32_t queueFamilyIndex,
|
||||
VkBool32* pSupported)
|
||||
{
|
||||
if (!x11_surface_is_thread_safe(icd_surface)) {
|
||||
*pSupported = false;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
xcb_connection_t *conn = x11_surface_get_connection(icd_surface);
|
||||
xcb_window_t window = x11_surface_get_window(icd_surface);
|
||||
|
||||
|
|
@ -2555,6 +2585,15 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
|||
|
||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||
|
||||
/* We really shouldn't get here as we return no WSI support for XLib when
|
||||
* it's not threadsafe. However, one final check doesn't cost much.
|
||||
*/
|
||||
if (!x11_surface_is_thread_safe(icd_surface)) {
|
||||
fprintf(stderr, "vulkan: xlib Display is not thread-safe. Call "
|
||||
"XInitThreads() in your app\n");
|
||||
return VK_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Get xcb connection from the icd_surface and from that our internal struct
|
||||
* representing it.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue