loader: move some common dri3 functions out of dri3 loader

fixing dependency hell

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30400>
This commit is contained in:
Mike Blumenkrantz 2024-07-19 13:03:47 -04:00 committed by Marge Bot
parent eebb6cd236
commit 4095fac72b
12 changed files with 217 additions and 133 deletions

View file

@ -56,6 +56,7 @@
#ifdef HAVE_X11_PLATFORM
#include "X11/Xlibint.h"
#include "loader_x11.h"
#endif
#include "GL/mesa_glinterop.h"
@ -963,7 +964,7 @@ dri2_setup_extensions(_EGLDisplay *disp)
#ifdef HAVE_X11_PLATFORM
if (dri2_dpy->conn) {
bool err;
dri2_dpy->multibuffers_available = loader_dri3_check_multibuffer(dri2_dpy->conn, &err) &&
dri2_dpy->multibuffers_available = x11_dri3_check_multibuffer(dri2_dpy->conn, &err) &&
!err &&
(dri2_dpy->image && dri2_dpy->image->base.version >= 15);
}

View file

@ -38,6 +38,7 @@
#include "platform_x11_dri3.h"
#include "loader.h"
#include "loader_x11.h"
#include "loader_dri3_helper.h"
static struct dri3_egl_surface *
@ -530,7 +531,7 @@ enum dri2_egl_driver_fail
dri3_x11_connect(struct dri2_egl_display *dri2_dpy, bool swrast)
{
dri2_dpy->fd_render_gpu =
loader_dri3_open(dri2_dpy->conn, dri2_dpy->screen->root, 0);
x11_dri3_open(dri2_dpy->conn, dri2_dpy->screen->root, 0);
if (dri2_dpy->fd_render_gpu < 0) {
int conn_error = xcb_connection_has_error(dri2_dpy->conn);
if (!swrast) {

View file

@ -85,6 +85,7 @@ if with_dri
deps_for_egl += idep_xmlconfig
link_for_egl += libloader
incs_for_egl += inc_loader
incs_for_egl += inc_loader_x11
incs_for_egl += inc_gallium
incs_for_egl += inc_gallium_aux
incs_for_egl += inc_mesa
@ -99,7 +100,7 @@ if with_dri
files_egl += files('drivers/dri2/platform_x11.c')
if with_dri3
files_egl += files('drivers/dri2/platform_x11_dri3.c')
link_for_egl += libloader_dri3_helper
link_for_egl += [libloader_dri3_helper, libloader_x11]
endif
deps_for_egl += [dep_x11_xcb, dep_xcb_dri2, dep_xcb_xrandr, dep_xcb_xfixes, dep_xcb_shm]
endif

View file

@ -76,6 +76,7 @@
#include "dri_common.h"
#include "dri3_priv.h"
#include "loader.h"
#include "loader_x11.h"
#include "loader_dri_helper.h"
#include "dri2.h"
#include "util/u_debug.h"
@ -809,7 +810,7 @@ dri3_create_screen(int screen, struct glx_display * priv, bool driver_name_is_in
return NULL;
}
psc->fd_render_gpu = loader_dri3_open(c, RootWindow(priv->dpy, screen), None);
psc->fd_render_gpu = x11_dri3_open(c, RootWindow(priv->dpy, screen), None);
if (psc->fd_render_gpu < 0) {
int conn_error = xcb_connection_has_error(c);

View file

@ -32,6 +32,7 @@
#include "dri_common.h"
#endif
#include "loader_x11.h"
#ifdef HAVE_DRI3
#include "loader_dri3_helper.h"
#endif
@ -907,7 +908,7 @@ __glXInitialize(Display * dpy)
#if defined(GLX_USE_DRM)
bool dri3_err = false;
if (glx_direct && glx_accel && dri3)
dpyPriv->has_multibuffer = loader_dri3_check_multibuffer(XGetXCBConnection(dpy), &dri3_err);
dpyPriv->has_multibuffer = x11_dri3_check_multibuffer(XGetXCBConnection(dpy), &dri3_err);
if (glx_direct && glx_accel &&
(!(glx_driver & GLX_DRIVER_ZINK_YES) || !kopper)) {
#if defined(HAVE_DRI3)

View file

@ -115,13 +115,13 @@ endif
libglx = static_library(
'glx',
[files_libglx, glx_generated],
include_directories : [inc_include, inc_src, inc_glapi, inc_loader, inc_gallium],
include_directories : [inc_include, inc_src, inc_glapi, inc_loader, inc_loader_x11, inc_gallium],
c_args : [
'-DGL_LIB_NAME="lib@0@.so.@1@"'.format(gl_lib_name, gl_lib_version.split('.')[0]),
],
gnu_symbol_visibility : 'hidden',
link_with : [
libloader, libloader_dri3_helper,
libloader, libloader_dri3_helper, libloader_x11,
extra_libs_libglx, glx_gallium_link
],
dependencies : [

View file

@ -1276,56 +1276,6 @@ loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
return ret;
}
/** loader_dri3_open
*
* Wrapper around xcb_dri3_open
*/
int
loader_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;
}
static uint32_t
dri3_cpp_for_fourcc(uint32_t format) {
switch (format) {
@ -2414,73 +2364,3 @@ dri3_find_back_alloc(struct loader_dri3_drawable *draw)
return back;
}
/* Only request versions of these protocols which we actually support. */
#define DRI3_SUPPORTED_MAJOR 1
#define PRESENT_SUPPORTED_MAJOR 1
#ifdef HAVE_DRI3_MODIFIERS
#define DRI3_SUPPORTED_MINOR 2
#define PRESENT_SUPPORTED_MINOR 2
#else
#define PRESENT_SUPPORTED_MINOR 0
#define DRI3_SUPPORTED_MINOR 0
#endif
bool
loader_dri3_check_multibuffer(xcb_connection_t *c, bool *err)
{
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_DRI3_MODIFIERS
if ((dri3Major > 1 || (dri3Major == 1 && dri3Minor >= 2)) &&
(presentMajor > 1 || (presentMajor == 1 && presentMinor >= 2)))
return true;
#endif
return false;
error:
*err = true;
return false;
}

View file

@ -259,10 +259,6 @@ loader_dri3_wait_x(struct loader_dri3_drawable *draw);
void
loader_dri3_wait_gl(struct loader_dri3_drawable *draw);
int loader_dri3_open(xcb_connection_t *conn,
xcb_window_t root,
uint32_t provider);
__DRIimage *
loader_dri3_create_image(xcb_connection_t *c,
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
@ -297,6 +293,4 @@ loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
void
loader_dri3_close_screen(__DRIscreen *dri_screen);
bool
loader_dri3_check_multibuffer(xcb_connection_t *c, bool *err);
#endif

View file

@ -46,6 +46,7 @@ if cc.get_argument_syntax() == 'msvc'
else
idep_getopt = null_dep
endif
subdir('x11')
if with_gallium or with_gbm or with_platform_wayland
subdir('loader')
endif

151
src/x11/loader_x11.c Normal file
View file

@ -0,0 +1,151 @@
/*
* 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_DRI3_MODIFIERS
#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)
{
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_DRI3_MODIFIERS
if ((dri3Major > 1 || (dri3Major == 1 && dri3Minor >= 2)) &&
(presentMajor > 1 || (presentMajor == 1 && presentMinor >= 2)))
return true;
#endif
return false;
error:
*err = true;
return false;
}

32
src/x11/loader_x11.h Normal file
View file

@ -0,0 +1,32 @@
/*
* 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.
*/
#ifndef LOADER_X11_H
#define LOADER_X11_H
#include <xcb/xcb.h>
#include <inttypes.h>
int x11_dri3_open(xcb_connection_t *conn, xcb_window_t root, uint32_t provider);
bool x11_dri3_check_multibuffer(xcb_connection_t *c, bool *err);
#endif

21
src/x11/meson.build Normal file
View file

@ -0,0 +1,21 @@
# Copyright © 2017 Intel Corporation
# SPDX-License-Identifier: MIT
inc_loader_x11 = include_directories('.')
if with_platform_x11 and with_dri3
libloader_x11 = static_library(
'loader_x11',
'loader_x11.c',
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_gallium],
dependencies : [
idep_mesautil,
dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence,
dep_xcb_xfixes,
],
build_by_default : false,
)
else
libloader_x11 = []
endif