diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 5857acbcdf3..1d2e6fd2b3c 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -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); } diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index 527d19049b2..c6983132826 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -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) { diff --git a/src/egl/meson.build b/src/egl/meson.build index 68814270b61..8ddde46d105 100644 --- a/src/egl/meson.build +++ b/src/egl/meson.build @@ -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 diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index 2d19f1f6401..428fbc4de85 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -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); diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 039857110ed..a8874defab3 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -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) diff --git a/src/glx/meson.build b/src/glx/meson.build index da2eeddb7d2..812521b5c3c 100644 --- a/src/glx/meson.build +++ b/src/glx/meson.build @@ -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 : [ diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 6375143e290..317207286d6 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -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; -} diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 0277f3d7828..9820c49cdd9 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -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 diff --git a/src/meson.build b/src/meson.build index b53dc86ee6e..f3dcac5b4bf 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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 diff --git a/src/x11/loader_x11.c b/src/x11/loader_x11.c new file mode 100644 index 00000000000..a417af86507 --- /dev/null +++ b/src/x11/loader_x11.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/src/x11/loader_x11.h b/src/x11/loader_x11.h new file mode 100644 index 00000000000..27edd478148 --- /dev/null +++ b/src/x11/loader_x11.h @@ -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 +#include +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 diff --git a/src/x11/meson.build b/src/x11/meson.build new file mode 100644 index 00000000000..7daea877cea --- /dev/null +++ b/src/x11/meson.build @@ -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