mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-20 11:18:11 +02:00
the year is 2024 and we have the technology Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31044>
153 lines
4.9 KiB
C
153 lines
4.9 KiB
C
/*
|
|
* Copyright © 2013 Keith Packard
|
|
* Copyright © 2015 Boyan Ding
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
* that the name of the copyright holders not be used in advertising or
|
|
* publicity pertaining to distribution of the software without specific,
|
|
* written prior permission. The copyright holders make no representations
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
* is" without express or implied warranty.
|
|
*
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
* OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <xcb/xcb.h>
|
|
#include <xcb/dri3.h>
|
|
#include <xcb/present.h>
|
|
#include <xcb/xfixes.h>
|
|
#include "loader_x11.h"
|
|
/** x11_dri3_open
|
|
*
|
|
* Wrapper around xcb_dri3_open
|
|
*/
|
|
int
|
|
x11_dri3_open(xcb_connection_t *conn,
|
|
xcb_window_t root,
|
|
uint32_t provider)
|
|
{
|
|
xcb_dri3_open_cookie_t cookie;
|
|
xcb_dri3_open_reply_t *reply;
|
|
xcb_xfixes_query_version_cookie_t fixes_cookie;
|
|
xcb_xfixes_query_version_reply_t *fixes_reply;
|
|
int fd;
|
|
const xcb_query_extension_reply_t *extension;
|
|
|
|
xcb_prefetch_extension_data(conn, &xcb_dri3_id);
|
|
extension = xcb_get_extension_data(conn, &xcb_dri3_id);
|
|
if (!(extension && extension->present))
|
|
return -1;
|
|
|
|
cookie = xcb_dri3_open(conn,
|
|
root,
|
|
provider);
|
|
|
|
reply = xcb_dri3_open_reply(conn, cookie, NULL);
|
|
|
|
if (!reply || reply->nfd != 1) {
|
|
free(reply);
|
|
return -1;
|
|
}
|
|
|
|
fd = xcb_dri3_open_reply_fds(conn, reply)[0];
|
|
free(reply);
|
|
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
|
|
|
/* let the server know our xfixes level */
|
|
fixes_cookie = xcb_xfixes_query_version(conn,
|
|
XCB_XFIXES_MAJOR_VERSION,
|
|
XCB_XFIXES_MINOR_VERSION);
|
|
fixes_reply = xcb_xfixes_query_version_reply(conn, fixes_cookie, NULL);
|
|
if (fixes_reply->major_version < 2) {
|
|
close(fd);
|
|
fd = -1;
|
|
}
|
|
free(fixes_reply);
|
|
|
|
return fd;
|
|
}
|
|
|
|
/* Only request versions of these protocols which we actually support. */
|
|
#define DRI3_SUPPORTED_MAJOR 1
|
|
#define PRESENT_SUPPORTED_MAJOR 1
|
|
|
|
#ifdef HAVE_X11_DRM
|
|
#define DRI3_SUPPORTED_MINOR 2
|
|
#define PRESENT_SUPPORTED_MINOR 2
|
|
#else
|
|
#define PRESENT_SUPPORTED_MINOR 0
|
|
#define DRI3_SUPPORTED_MINOR 0
|
|
#endif
|
|
|
|
bool
|
|
x11_dri3_check_multibuffer(xcb_connection_t *c, bool *err, bool *explicit_modifiers)
|
|
{
|
|
xcb_dri3_query_version_cookie_t dri3_cookie;
|
|
xcb_dri3_query_version_reply_t *dri3_reply;
|
|
xcb_present_query_version_cookie_t present_cookie;
|
|
xcb_present_query_version_reply_t *present_reply;
|
|
xcb_generic_error_t *error;
|
|
const xcb_query_extension_reply_t *extension;
|
|
|
|
xcb_prefetch_extension_data(c, &xcb_dri3_id);
|
|
xcb_prefetch_extension_data(c, &xcb_present_id);
|
|
|
|
extension = xcb_get_extension_data(c, &xcb_dri3_id);
|
|
if (!(extension && extension->present))
|
|
goto error;
|
|
|
|
extension = xcb_get_extension_data(c, &xcb_present_id);
|
|
if (!(extension && extension->present))
|
|
goto error;
|
|
|
|
dri3_cookie = xcb_dri3_query_version(c,
|
|
DRI3_SUPPORTED_MAJOR,
|
|
DRI3_SUPPORTED_MINOR);
|
|
present_cookie = xcb_present_query_version(c,
|
|
PRESENT_SUPPORTED_MAJOR,
|
|
PRESENT_SUPPORTED_MINOR);
|
|
|
|
dri3_reply = xcb_dri3_query_version_reply(c, dri3_cookie, &error);
|
|
if (!dri3_reply) {
|
|
free(error);
|
|
goto error;
|
|
}
|
|
|
|
int dri3Major = dri3_reply->major_version;
|
|
int dri3Minor = dri3_reply->minor_version;
|
|
free(dri3_reply);
|
|
|
|
present_reply = xcb_present_query_version_reply(c, present_cookie, &error);
|
|
if (!present_reply) {
|
|
free(error);
|
|
goto error;
|
|
}
|
|
int presentMajor = present_reply->major_version;
|
|
int presentMinor = present_reply->minor_version;
|
|
free(present_reply);
|
|
|
|
#ifdef HAVE_X11_DRM
|
|
if (presentMajor > 1 || (presentMajor == 1 && presentMinor >= 2)) {
|
|
*explicit_modifiers = dri3Major > 1 || (dri3Major == 1 && dri3Minor >= 2);
|
|
if (dri3Major >= 1)
|
|
return true;
|
|
}
|
|
#endif
|
|
return false;
|
|
error:
|
|
*err = true;
|
|
return false;
|
|
}
|