xref: /aosp_15_r20/external/mesa3d/src/glx/dri3_glx.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2013 Keith Packard
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission to use, copy, modify, distribute, and sell this software and its
5*61046927SAndroid Build Coastguard Worker  * documentation for any purpose is hereby granted without fee, provided that
6*61046927SAndroid Build Coastguard Worker  * the above copyright notice appear in all copies and that both that copyright
7*61046927SAndroid Build Coastguard Worker  * notice and this permission notice appear in supporting documentation, and
8*61046927SAndroid Build Coastguard Worker  * that the name of the copyright holders not be used in advertising or
9*61046927SAndroid Build Coastguard Worker  * publicity pertaining to distribution of the software without specific,
10*61046927SAndroid Build Coastguard Worker  * written prior permission.  The copyright holders make no representations
11*61046927SAndroid Build Coastguard Worker  * about the suitability of this software for any purpose.  It is provided "as
12*61046927SAndroid Build Coastguard Worker  * is" without express or implied warranty.
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*61046927SAndroid Build Coastguard Worker  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*61046927SAndroid Build Coastguard Worker  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*61046927SAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*61046927SAndroid Build Coastguard Worker  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*61046927SAndroid Build Coastguard Worker  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20*61046927SAndroid Build Coastguard Worker  * OF THIS SOFTWARE.
21*61046927SAndroid Build Coastguard Worker  */
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker /*
24*61046927SAndroid Build Coastguard Worker  * Portions of this code were adapted from dri2_glx.c which carries the
25*61046927SAndroid Build Coastguard Worker  * following copyright:
26*61046927SAndroid Build Coastguard Worker  *
27*61046927SAndroid Build Coastguard Worker  * Copyright © 2008 Red Hat, Inc.
28*61046927SAndroid Build Coastguard Worker  *
29*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
30*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Soft-
31*61046927SAndroid Build Coastguard Worker  * ware"), to deal in the Software without restriction, including without
32*61046927SAndroid Build Coastguard Worker  * limitation the rights to use, copy, modify, merge, publish, distribute,
33*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
34*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, provided that the above copyright
35*61046927SAndroid Build Coastguard Worker  * notice(s) and this permission notice appear in all copies of the Soft-
36*61046927SAndroid Build Coastguard Worker  * ware and that both the above copyright notice(s) and this permission
37*61046927SAndroid Build Coastguard Worker  * notice appear in supporting documentation.
38*61046927SAndroid Build Coastguard Worker  *
39*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
40*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
41*61046927SAndroid Build Coastguard Worker  * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
42*61046927SAndroid Build Coastguard Worker  * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
43*61046927SAndroid Build Coastguard Worker  * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
44*61046927SAndroid Build Coastguard Worker  * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
45*61046927SAndroid Build Coastguard Worker  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
46*61046927SAndroid Build Coastguard Worker  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
47*61046927SAndroid Build Coastguard Worker  * MANCE OF THIS SOFTWARE.
48*61046927SAndroid Build Coastguard Worker  *
49*61046927SAndroid Build Coastguard Worker  * Except as contained in this notice, the name of a copyright holder shall
50*61046927SAndroid Build Coastguard Worker  * not be used in advertising or otherwise to promote the sale, use or
51*61046927SAndroid Build Coastguard Worker  * other dealings in this Software without prior written authorization of
52*61046927SAndroid Build Coastguard Worker  * the copyright holder.
53*61046927SAndroid Build Coastguard Worker  *
54*61046927SAndroid Build Coastguard Worker  * Authors:
55*61046927SAndroid Build Coastguard Worker  *   Kristian Høgsberg ([email protected])
56*61046927SAndroid Build Coastguard Worker  */
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker #include <X11/Xlib.h>
61*61046927SAndroid Build Coastguard Worker #include <X11/extensions/Xfixes.h>
62*61046927SAndroid Build Coastguard Worker #include <X11/Xlib-xcb.h>
63*61046927SAndroid Build Coastguard Worker #include <X11/xshmfence.h>
64*61046927SAndroid Build Coastguard Worker #include <xcb/xcb.h>
65*61046927SAndroid Build Coastguard Worker #include <xcb/dri3.h>
66*61046927SAndroid Build Coastguard Worker #include <xcb/present.h>
67*61046927SAndroid Build Coastguard Worker #include <GL/gl.h>
68*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
69*61046927SAndroid Build Coastguard Worker #include <dlfcn.h>
70*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
71*61046927SAndroid Build Coastguard Worker #include <unistd.h>
72*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
73*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
74*61046927SAndroid Build Coastguard Worker #include <sys/time.h>
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker #include "dri_common.h"
77*61046927SAndroid Build Coastguard Worker #include "dri3_priv.h"
78*61046927SAndroid Build Coastguard Worker #include "loader.h"
79*61046927SAndroid Build Coastguard Worker #include "loader_x11.h"
80*61046927SAndroid Build Coastguard Worker #include "loader_dri_helper.h"
81*61046927SAndroid Build Coastguard Worker #include "dri2.h"
82*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
83*61046927SAndroid Build Coastguard Worker #include "dri_util.h"
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker static struct dri3_drawable *
loader_drawable_to_dri3_drawable(struct loader_dri3_drawable * draw)86*61046927SAndroid Build Coastguard Worker loader_drawable_to_dri3_drawable(struct loader_dri3_drawable *draw) {
87*61046927SAndroid Build Coastguard Worker    size_t offset = offsetof(struct dri3_drawable, loader_drawable);
88*61046927SAndroid Build Coastguard Worker    if (!draw)
89*61046927SAndroid Build Coastguard Worker       return NULL;
90*61046927SAndroid Build Coastguard Worker    return (struct dri3_drawable *)(((void*) draw) - offset);
91*61046927SAndroid Build Coastguard Worker }
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker static void
glx_dri3_set_drawable_size(struct loader_dri3_drawable * draw,int width,int height)94*61046927SAndroid Build Coastguard Worker glx_dri3_set_drawable_size(struct loader_dri3_drawable *draw,
95*61046927SAndroid Build Coastguard Worker                            int width, int height)
96*61046927SAndroid Build Coastguard Worker {
97*61046927SAndroid Build Coastguard Worker    /* Nothing to do */
98*61046927SAndroid Build Coastguard Worker }
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker static bool
glx_dri3_in_current_context(struct loader_dri3_drawable * draw)101*61046927SAndroid Build Coastguard Worker glx_dri3_in_current_context(struct loader_dri3_drawable *draw)
102*61046927SAndroid Build Coastguard Worker {
103*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = loader_drawable_to_dri3_drawable(draw);
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    if (!priv)
106*61046927SAndroid Build Coastguard Worker       return false;
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    struct glx_context *pcp = __glXGetCurrentContext();
109*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc = (struct dri3_screen *) priv->base.psc;
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker    return (pcp != &dummyContext) && pcp->psc == &psc->base;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker static __DRIcontext *
glx_dri3_get_dri_context(struct loader_dri3_drawable * draw)115*61046927SAndroid Build Coastguard Worker glx_dri3_get_dri_context(struct loader_dri3_drawable *draw)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    return (gc != &dummyContext) ? gc->driContext : NULL;
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker static __DRIscreen *
glx_dri3_get_dri_screen(void)123*61046927SAndroid Build Coastguard Worker glx_dri3_get_dri_screen(void)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
126*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc = (struct dri3_screen *) gc->psc;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    return (gc != &dummyContext && psc) ? psc->base.frontend_screen : NULL;
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker static void
glx_dri3_flush_drawable(struct loader_dri3_drawable * draw,unsigned flags)132*61046927SAndroid Build Coastguard Worker glx_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
133*61046927SAndroid Build Coastguard Worker {
134*61046927SAndroid Build Coastguard Worker    loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
135*61046927SAndroid Build Coastguard Worker }
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker static const struct loader_dri3_vtable glx_dri3_vtable = {
138*61046927SAndroid Build Coastguard Worker    .set_drawable_size = glx_dri3_set_drawable_size,
139*61046927SAndroid Build Coastguard Worker    .in_current_context = glx_dri3_in_current_context,
140*61046927SAndroid Build Coastguard Worker    .get_dri_context = glx_dri3_get_dri_context,
141*61046927SAndroid Build Coastguard Worker    .get_dri_screen = glx_dri3_get_dri_screen,
142*61046927SAndroid Build Coastguard Worker    .flush_drawable = glx_dri3_flush_drawable,
143*61046927SAndroid Build Coastguard Worker };
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable dri3_context_vtable;
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker static void
dri3_destroy_drawable(__GLXDRIdrawable * base)149*61046927SAndroid Build Coastguard Worker dri3_destroy_drawable(__GLXDRIdrawable *base)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *pdraw = (struct dri3_drawable *) base;
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker    loader_dri3_drawable_fini(&pdraw->loader_drawable);
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    free(pdraw);
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker static enum loader_dri3_drawable_type
glx_to_loader_dri3_drawable_type(int type)159*61046927SAndroid Build Coastguard Worker glx_to_loader_dri3_drawable_type(int type)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker    switch (type) {
162*61046927SAndroid Build Coastguard Worker    case GLX_WINDOW_BIT:
163*61046927SAndroid Build Coastguard Worker       return LOADER_DRI3_DRAWABLE_WINDOW;
164*61046927SAndroid Build Coastguard Worker    case GLX_PIXMAP_BIT:
165*61046927SAndroid Build Coastguard Worker       return LOADER_DRI3_DRAWABLE_PIXMAP;
166*61046927SAndroid Build Coastguard Worker    case GLX_PBUFFER_BIT:
167*61046927SAndroid Build Coastguard Worker       return LOADER_DRI3_DRAWABLE_PBUFFER;
168*61046927SAndroid Build Coastguard Worker    default:
169*61046927SAndroid Build Coastguard Worker       return LOADER_DRI3_DRAWABLE_UNKNOWN;
170*61046927SAndroid Build Coastguard Worker    }
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker static __GLXDRIdrawable *
dri3_create_drawable(struct glx_screen * base,XID xDrawable,GLXDrawable drawable,int type,struct glx_config * config_base)174*61046927SAndroid Build Coastguard Worker dri3_create_drawable(struct glx_screen *base, XID xDrawable,
175*61046927SAndroid Build Coastguard Worker                      GLXDrawable drawable, int type,
176*61046927SAndroid Build Coastguard Worker                      struct glx_config *config_base)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *pdraw;
179*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc = (struct dri3_screen *) base;
180*61046927SAndroid Build Coastguard Worker    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
181*61046927SAndroid Build Coastguard Worker    bool has_multibuffer = false;
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker    pdraw = calloc(1, sizeof(*pdraw));
184*61046927SAndroid Build Coastguard Worker    if (!pdraw)
185*61046927SAndroid Build Coastguard Worker       return NULL;
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    pdraw->base.destroyDrawable = dri3_destroy_drawable;
188*61046927SAndroid Build Coastguard Worker    pdraw->base.xDrawable = xDrawable;
189*61046927SAndroid Build Coastguard Worker    pdraw->base.drawable = drawable;
190*61046927SAndroid Build Coastguard Worker    pdraw->base.psc = &psc->base;
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker #ifdef HAVE_X11_DRM
193*61046927SAndroid Build Coastguard Worker    has_multibuffer = base->display->has_multibuffer;
194*61046927SAndroid Build Coastguard Worker #endif
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    (void) __glXInitialize(psc->base.dpy);
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker    if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy),
199*61046927SAndroid Build Coastguard Worker                                  xDrawable,
200*61046927SAndroid Build Coastguard Worker                                  glx_to_loader_dri3_drawable_type(type),
201*61046927SAndroid Build Coastguard Worker                                  psc->base.frontend_screen, psc->driScreenDisplayGPU,
202*61046927SAndroid Build Coastguard Worker                                  has_multibuffer,
203*61046927SAndroid Build Coastguard Worker                                  psc->prefer_back_buffer_reuse,
204*61046927SAndroid Build Coastguard Worker                                  config->driConfig,
205*61046927SAndroid Build Coastguard Worker                                  &glx_dri3_vtable,
206*61046927SAndroid Build Coastguard Worker                                  &pdraw->loader_drawable)) {
207*61046927SAndroid Build Coastguard Worker       free(pdraw);
208*61046927SAndroid Build Coastguard Worker       return NULL;
209*61046927SAndroid Build Coastguard Worker    }
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker    pdraw->base.dri_drawable = pdraw->loader_drawable.dri_drawable;
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker    return &pdraw->base;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker /** dri3_wait_for_msc
217*61046927SAndroid Build Coastguard Worker  *
218*61046927SAndroid Build Coastguard Worker  * Get the X server to send an event when the target msc/divisor/remainder is
219*61046927SAndroid Build Coastguard Worker  * reached.
220*61046927SAndroid Build Coastguard Worker  */
221*61046927SAndroid Build Coastguard Worker static int
dri3_wait_for_msc(__GLXDRIdrawable * pdraw,int64_t target_msc,int64_t divisor,int64_t remainder,int64_t * ust,int64_t * msc,int64_t * sbc)222*61046927SAndroid Build Coastguard Worker dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
223*61046927SAndroid Build Coastguard Worker                   int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
224*61046927SAndroid Build Coastguard Worker {
225*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker    loader_dri3_wait_for_msc(&priv->loader_drawable, target_msc, divisor,
228*61046927SAndroid Build Coastguard Worker                             remainder, ust, msc, sbc);
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker    return 1;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker /** dri3_drawable_get_msc
234*61046927SAndroid Build Coastguard Worker  *
235*61046927SAndroid Build Coastguard Worker  * Return the current UST/MSC/SBC triplet by asking the server
236*61046927SAndroid Build Coastguard Worker  * for an event
237*61046927SAndroid Build Coastguard Worker  */
238*61046927SAndroid Build Coastguard Worker static int
dri3_drawable_get_msc(struct glx_screen * psc,__GLXDRIdrawable * pdraw,int64_t * ust,int64_t * msc,int64_t * sbc)239*61046927SAndroid Build Coastguard Worker dri3_drawable_get_msc(struct glx_screen *psc, __GLXDRIdrawable *pdraw,
240*61046927SAndroid Build Coastguard Worker                       int64_t *ust, int64_t *msc, int64_t *sbc)
241*61046927SAndroid Build Coastguard Worker {
242*61046927SAndroid Build Coastguard Worker    return dri3_wait_for_msc(pdraw, 0, 0, 0, ust, msc,sbc);
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker /** dri3_wait_for_sbc
246*61046927SAndroid Build Coastguard Worker  *
247*61046927SAndroid Build Coastguard Worker  * Wait for the completed swap buffer count to reach the specified
248*61046927SAndroid Build Coastguard Worker  * target. Presumably the application knows that this will be reached with
249*61046927SAndroid Build Coastguard Worker  * outstanding complete events, or we're going to be here awhile.
250*61046927SAndroid Build Coastguard Worker  */
251*61046927SAndroid Build Coastguard Worker static int
dri3_wait_for_sbc(__GLXDRIdrawable * pdraw,int64_t target_sbc,int64_t * ust,int64_t * msc,int64_t * sbc)252*61046927SAndroid Build Coastguard Worker dri3_wait_for_sbc(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
253*61046927SAndroid Build Coastguard Worker                   int64_t *msc, int64_t *sbc)
254*61046927SAndroid Build Coastguard Worker {
255*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker    return loader_dri3_wait_for_sbc(&priv->loader_drawable, target_sbc,
258*61046927SAndroid Build Coastguard Worker                                    ust, msc, sbc);
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker static void
dri3_copy_sub_buffer(__GLXDRIdrawable * pdraw,int x,int y,int width,int height,Bool flush)262*61046927SAndroid Build Coastguard Worker dri3_copy_sub_buffer(__GLXDRIdrawable *pdraw, int x, int y,
263*61046927SAndroid Build Coastguard Worker                      int width, int height,
264*61046927SAndroid Build Coastguard Worker                      Bool flush)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    loader_dri3_copy_sub_buffer(&priv->loader_drawable, x, y,
269*61046927SAndroid Build Coastguard Worker                                width, height, flush);
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker static void
dri3_wait_x(struct glx_context * gc)273*61046927SAndroid Build Coastguard Worker dri3_wait_x(struct glx_context *gc)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *)
276*61046927SAndroid Build Coastguard Worker       GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker    if (priv)
279*61046927SAndroid Build Coastguard Worker       loader_dri3_wait_x(&priv->loader_drawable);
280*61046927SAndroid Build Coastguard Worker }
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker static void
dri3_wait_gl(struct glx_context * gc)283*61046927SAndroid Build Coastguard Worker dri3_wait_gl(struct glx_context *gc)
284*61046927SAndroid Build Coastguard Worker {
285*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *)
286*61046927SAndroid Build Coastguard Worker       GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    if (priv)
289*61046927SAndroid Build Coastguard Worker       loader_dri3_wait_gl(&priv->loader_drawable);
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker /**
293*61046927SAndroid Build Coastguard Worker  * Called by the driver when it needs to update the real front buffer with the
294*61046927SAndroid Build Coastguard Worker  * contents of its fake front buffer.
295*61046927SAndroid Build Coastguard Worker  */
296*61046927SAndroid Build Coastguard Worker static void
dri3_flush_front_buffer(__DRIdrawable * driDrawable,void * loaderPrivate)297*61046927SAndroid Build Coastguard Worker dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
298*61046927SAndroid Build Coastguard Worker {
299*61046927SAndroid Build Coastguard Worker    struct loader_dri3_drawable *draw = loaderPrivate;
300*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *pdraw = loader_drawable_to_dri3_drawable(draw);
301*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc;
302*61046927SAndroid Build Coastguard Worker 
303*61046927SAndroid Build Coastguard Worker    if (!pdraw)
304*61046927SAndroid Build Coastguard Worker       return;
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker    if (!pdraw->base.psc)
307*61046927SAndroid Build Coastguard Worker       return;
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker    psc = (struct dri3_screen *) pdraw->base.psc;
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    (void) __glXInitialize(psc->base.dpy);
312*61046927SAndroid Build Coastguard Worker 
313*61046927SAndroid Build Coastguard Worker    loader_dri3_flush(draw, __DRI2_FLUSH_DRAWABLE, __DRI2_THROTTLE_FLUSHFRONT);
314*61046927SAndroid Build Coastguard Worker 
315*61046927SAndroid Build Coastguard Worker    dri_invalidate_drawable(driDrawable);
316*61046927SAndroid Build Coastguard Worker    loader_dri3_wait_gl(draw);
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker /**
320*61046927SAndroid Build Coastguard Worker  * Make sure all pending swapbuffers have been submitted to hardware
321*61046927SAndroid Build Coastguard Worker  *
322*61046927SAndroid Build Coastguard Worker  * \param driDrawable[in]  Pointer to the dri drawable whose swaps we are
323*61046927SAndroid Build Coastguard Worker  * flushing.
324*61046927SAndroid Build Coastguard Worker  * \param loaderPrivate[in]  Pointer to the corresponding struct
325*61046927SAndroid Build Coastguard Worker  * loader_dri_drawable.
326*61046927SAndroid Build Coastguard Worker  */
327*61046927SAndroid Build Coastguard Worker static void
dri3_flush_swap_buffers(__DRIdrawable * driDrawable,void * loaderPrivate)328*61046927SAndroid Build Coastguard Worker dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate)
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker    struct loader_dri3_drawable *draw = loaderPrivate;
331*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *pdraw = loader_drawable_to_dri3_drawable(draw);
332*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc;
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker    if (!pdraw)
335*61046927SAndroid Build Coastguard Worker       return;
336*61046927SAndroid Build Coastguard Worker 
337*61046927SAndroid Build Coastguard Worker    if (!pdraw->base.psc)
338*61046927SAndroid Build Coastguard Worker       return;
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker    psc = (struct dri3_screen *) pdraw->base.psc;
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker    (void) __glXInitialize(psc->base.dpy);
343*61046927SAndroid Build Coastguard Worker    loader_dri3_swapbuffer_barrier(draw);
344*61046927SAndroid Build Coastguard Worker }
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker static void
dri_set_background_context(void * loaderPrivate)347*61046927SAndroid Build Coastguard Worker dri_set_background_context(void *loaderPrivate)
348*61046927SAndroid Build Coastguard Worker {
349*61046927SAndroid Build Coastguard Worker    __glXSetCurrentContext(loaderPrivate);
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker static GLboolean
dri_is_thread_safe(void * loaderPrivate)353*61046927SAndroid Build Coastguard Worker dri_is_thread_safe(void *loaderPrivate)
354*61046927SAndroid Build Coastguard Worker {
355*61046927SAndroid Build Coastguard Worker    /* Unlike DRI2, DRI3 doesn't call GetBuffers/GetBuffersWithFormat
356*61046927SAndroid Build Coastguard Worker     * during draw so we're safe here.
357*61046927SAndroid Build Coastguard Worker     */
358*61046927SAndroid Build Coastguard Worker    return true;
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker /* The image loader extension record for DRI3
362*61046927SAndroid Build Coastguard Worker  */
363*61046927SAndroid Build Coastguard Worker static const __DRIimageLoaderExtension imageLoaderExtension = {
364*61046927SAndroid Build Coastguard Worker    .base = { __DRI_IMAGE_LOADER, 3 },
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    .getBuffers          = loader_dri3_get_buffers,
367*61046927SAndroid Build Coastguard Worker    .flushFrontBuffer    = dri3_flush_front_buffer,
368*61046927SAndroid Build Coastguard Worker    .flushSwapBuffers    = dri3_flush_swap_buffers,
369*61046927SAndroid Build Coastguard Worker };
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker const __DRIuseInvalidateExtension dri3UseInvalidate = {
372*61046927SAndroid Build Coastguard Worker    .base = { __DRI_USE_INVALIDATE, 1 }
373*61046927SAndroid Build Coastguard Worker };
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker static const __DRIbackgroundCallableExtension dri3BackgroundCallable = {
376*61046927SAndroid Build Coastguard Worker    .base = { __DRI_BACKGROUND_CALLABLE, 2 },
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker    .setBackgroundContext = dri_set_background_context,
379*61046927SAndroid Build Coastguard Worker    .isThreadSafe         = dri_is_thread_safe,
380*61046927SAndroid Build Coastguard Worker };
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker static const __DRIextension *loader_extensions[] = {
383*61046927SAndroid Build Coastguard Worker    &imageLoaderExtension.base,
384*61046927SAndroid Build Coastguard Worker    &dri3UseInvalidate.base,
385*61046927SAndroid Build Coastguard Worker    &dri3BackgroundCallable.base,
386*61046927SAndroid Build Coastguard Worker    NULL
387*61046927SAndroid Build Coastguard Worker };
388*61046927SAndroid Build Coastguard Worker 
389*61046927SAndroid Build Coastguard Worker /** dri3_swap_buffers
390*61046927SAndroid Build Coastguard Worker  *
391*61046927SAndroid Build Coastguard Worker  * Make the current back buffer visible using the present extension
392*61046927SAndroid Build Coastguard Worker  */
393*61046927SAndroid Build Coastguard Worker static int64_t
dri3_swap_buffers(__GLXDRIdrawable * pdraw,int64_t target_msc,int64_t divisor,int64_t remainder,Bool flush)394*61046927SAndroid Build Coastguard Worker dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
395*61046927SAndroid Build Coastguard Worker                   int64_t remainder, Bool flush)
396*61046927SAndroid Build Coastguard Worker {
397*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
398*61046927SAndroid Build Coastguard Worker    unsigned flags = __DRI2_FLUSH_DRAWABLE;
399*61046927SAndroid Build Coastguard Worker 
400*61046927SAndroid Build Coastguard Worker    if (flush)
401*61046927SAndroid Build Coastguard Worker       flags |= __DRI2_FLUSH_CONTEXT;
402*61046927SAndroid Build Coastguard Worker 
403*61046927SAndroid Build Coastguard Worker    return loader_dri3_swap_buffers_msc(&priv->loader_drawable,
404*61046927SAndroid Build Coastguard Worker                                        target_msc, divisor, remainder,
405*61046927SAndroid Build Coastguard Worker                                        flags, NULL, 0, false);
406*61046927SAndroid Build Coastguard Worker }
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker int
409*61046927SAndroid Build Coastguard Worker dri3_get_buffer_age(__GLXDRIdrawable *pdraw);
410*61046927SAndroid Build Coastguard Worker int
dri3_get_buffer_age(__GLXDRIdrawable * pdraw)411*61046927SAndroid Build Coastguard Worker dri3_get_buffer_age(__GLXDRIdrawable *pdraw)
412*61046927SAndroid Build Coastguard Worker {
413*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv = (struct dri3_drawable *)pdraw;
414*61046927SAndroid Build Coastguard Worker 
415*61046927SAndroid Build Coastguard Worker    return loader_dri3_query_buffer_age(&priv->loader_drawable);
416*61046927SAndroid Build Coastguard Worker }
417*61046927SAndroid Build Coastguard Worker 
418*61046927SAndroid Build Coastguard Worker /** dri3_destroy_screen
419*61046927SAndroid Build Coastguard Worker  */
420*61046927SAndroid Build Coastguard Worker static void
dri3_deinit_screen(struct glx_screen * base)421*61046927SAndroid Build Coastguard Worker dri3_deinit_screen(struct glx_screen *base)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc = (struct dri3_screen *) base;
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker    /* Free the direct rendering per screen data */
426*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu != psc->fd_display_gpu && psc->driScreenDisplayGPU) {
427*61046927SAndroid Build Coastguard Worker       loader_dri3_close_screen(psc->driScreenDisplayGPU);
428*61046927SAndroid Build Coastguard Worker       driDestroyScreen(psc->driScreenDisplayGPU);
429*61046927SAndroid Build Coastguard Worker    }
430*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu != psc->fd_display_gpu)
431*61046927SAndroid Build Coastguard Worker       close(psc->fd_display_gpu);
432*61046927SAndroid Build Coastguard Worker    loader_dri3_close_screen(psc->base.frontend_screen);
433*61046927SAndroid Build Coastguard Worker    close(psc->fd_render_gpu);
434*61046927SAndroid Build Coastguard Worker }
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker /** dri3_set_swap_interval
437*61046927SAndroid Build Coastguard Worker  *
438*61046927SAndroid Build Coastguard Worker  * Record the application swap interval specification,
439*61046927SAndroid Build Coastguard Worker  */
440*61046927SAndroid Build Coastguard Worker static int
dri3_set_swap_interval(__GLXDRIdrawable * pdraw,int interval)441*61046927SAndroid Build Coastguard Worker dri3_set_swap_interval(__GLXDRIdrawable *pdraw, int interval)
442*61046927SAndroid Build Coastguard Worker {
443*61046927SAndroid Build Coastguard Worker    assert(pdraw != NULL);
444*61046927SAndroid Build Coastguard Worker 
445*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv =  (struct dri3_drawable *) pdraw;
446*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc = (struct dri3_screen *) priv->base.psc;
447*61046927SAndroid Build Coastguard Worker 
448*61046927SAndroid Build Coastguard Worker    if (!dri_valid_swap_interval(psc->base.frontend_screen, interval))
449*61046927SAndroid Build Coastguard Worker       return GLX_BAD_VALUE;
450*61046927SAndroid Build Coastguard Worker 
451*61046927SAndroid Build Coastguard Worker    loader_dri3_set_swap_interval(&priv->loader_drawable, interval);
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker    return 0;
454*61046927SAndroid Build Coastguard Worker }
455*61046927SAndroid Build Coastguard Worker 
456*61046927SAndroid Build Coastguard Worker /** dri3_get_swap_interval
457*61046927SAndroid Build Coastguard Worker  *
458*61046927SAndroid Build Coastguard Worker  * Return the stored swap interval
459*61046927SAndroid Build Coastguard Worker  */
460*61046927SAndroid Build Coastguard Worker static int
dri3_get_swap_interval(__GLXDRIdrawable * pdraw)461*61046927SAndroid Build Coastguard Worker dri3_get_swap_interval(__GLXDRIdrawable *pdraw)
462*61046927SAndroid Build Coastguard Worker {
463*61046927SAndroid Build Coastguard Worker    assert(pdraw != NULL);
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker    struct dri3_drawable *priv =  (struct dri3_drawable *) pdraw;
466*61046927SAndroid Build Coastguard Worker 
467*61046927SAndroid Build Coastguard Worker   return priv->loader_drawable.swap_interval;
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker 
470*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable dri3_context_vtable = {
471*61046927SAndroid Build Coastguard Worker    .destroy             = dri_destroy_context,
472*61046927SAndroid Build Coastguard Worker    .bind                = dri_bind_context,
473*61046927SAndroid Build Coastguard Worker    .unbind              = dri_unbind_context,
474*61046927SAndroid Build Coastguard Worker    .wait_gl             = dri3_wait_gl,
475*61046927SAndroid Build Coastguard Worker    .wait_x              = dri3_wait_x,
476*61046927SAndroid Build Coastguard Worker };
477*61046927SAndroid Build Coastguard Worker 
478*61046927SAndroid Build Coastguard Worker /** dri3_create_screen
479*61046927SAndroid Build Coastguard Worker  *
480*61046927SAndroid Build Coastguard Worker  * Initialize DRI3 on the specified screen.
481*61046927SAndroid Build Coastguard Worker  *
482*61046927SAndroid Build Coastguard Worker  * Opens the DRI device, locates the appropriate DRI driver
483*61046927SAndroid Build Coastguard Worker  * and loads that.
484*61046927SAndroid Build Coastguard Worker  *
485*61046927SAndroid Build Coastguard Worker  * Checks to see if the driver supports the necessary extensions
486*61046927SAndroid Build Coastguard Worker  *
487*61046927SAndroid Build Coastguard Worker  * Initializes the driver for the screen and sets up our structures
488*61046927SAndroid Build Coastguard Worker  */
489*61046927SAndroid Build Coastguard Worker 
490*61046927SAndroid Build Coastguard Worker struct glx_screen *
dri3_create_screen(int screen,struct glx_display * priv,bool driver_name_is_inferred,bool * return_zink)491*61046927SAndroid Build Coastguard Worker dri3_create_screen(int screen, struct glx_display * priv, bool driver_name_is_inferred, bool *return_zink)
492*61046927SAndroid Build Coastguard Worker {
493*61046927SAndroid Build Coastguard Worker    xcb_connection_t *c = XGetXCBConnection(priv->dpy);
494*61046927SAndroid Build Coastguard Worker    const __DRIconfig **driver_configs;
495*61046927SAndroid Build Coastguard Worker    struct dri3_screen *psc;
496*61046927SAndroid Build Coastguard Worker    __GLXDRIscreen *psp;
497*61046927SAndroid Build Coastguard Worker    char *driverName, *driverNameDisplayGPU;
498*61046927SAndroid Build Coastguard Worker    *return_zink = false;
499*61046927SAndroid Build Coastguard Worker 
500*61046927SAndroid Build Coastguard Worker    psc = calloc(1, sizeof *psc);
501*61046927SAndroid Build Coastguard Worker    if (psc == NULL)
502*61046927SAndroid Build Coastguard Worker       return NULL;
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker    psc->fd_display_gpu = -1;
505*61046927SAndroid Build Coastguard Worker 
506*61046927SAndroid Build Coastguard Worker    psc->fd_render_gpu = x11_dri3_open(c, RootWindow(priv->dpy, screen), None);
507*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu < 0) {
508*61046927SAndroid Build Coastguard Worker       int conn_error = xcb_connection_has_error(c);
509*61046927SAndroid Build Coastguard Worker 
510*61046927SAndroid Build Coastguard Worker       glx_screen_cleanup(&psc->base);
511*61046927SAndroid Build Coastguard Worker       free(psc);
512*61046927SAndroid Build Coastguard Worker       InfoMessageF("screen %d does not appear to be DRI3 capable\n", screen);
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker       if (conn_error)
515*61046927SAndroid Build Coastguard Worker          ErrorMessageF("Connection closed during DRI3 initialization failure");
516*61046927SAndroid Build Coastguard Worker 
517*61046927SAndroid Build Coastguard Worker       return NULL;
518*61046927SAndroid Build Coastguard Worker    }
519*61046927SAndroid Build Coastguard Worker 
520*61046927SAndroid Build Coastguard Worker    loader_get_user_preferred_fd(&psc->fd_render_gpu, &psc->fd_display_gpu);
521*61046927SAndroid Build Coastguard Worker 
522*61046927SAndroid Build Coastguard Worker    driverName = loader_get_driver_for_fd(psc->fd_render_gpu);
523*61046927SAndroid Build Coastguard Worker    if (!driverName) {
524*61046927SAndroid Build Coastguard Worker       ErrorMessageF("No driver found\n");
525*61046927SAndroid Build Coastguard Worker       goto handle_error;
526*61046927SAndroid Build Coastguard Worker    }
527*61046927SAndroid Build Coastguard Worker    psc->base.driverName = driverName;
528*61046927SAndroid Build Coastguard Worker 
529*61046927SAndroid Build Coastguard Worker    if (!strcmp(driverName, "zink") && !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false)) {
530*61046927SAndroid Build Coastguard Worker       *return_zink = true;
531*61046927SAndroid Build Coastguard Worker       goto handle_error;
532*61046927SAndroid Build Coastguard Worker    }
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu != psc->fd_display_gpu) {
535*61046927SAndroid Build Coastguard Worker       driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu);
536*61046927SAndroid Build Coastguard Worker       if (driverNameDisplayGPU) {
537*61046927SAndroid Build Coastguard Worker 
538*61046927SAndroid Build Coastguard Worker          /* check if driver name is matching so that non mesa drivers
539*61046927SAndroid Build Coastguard Worker           * will not crash. Also need this check since image extension
540*61046927SAndroid Build Coastguard Worker           * pointer from render gpu is shared with display gpu. Image
541*61046927SAndroid Build Coastguard Worker           * extension pointer is shared because it keeps things simple.
542*61046927SAndroid Build Coastguard Worker           */
543*61046927SAndroid Build Coastguard Worker          if (strcmp(driverName, driverNameDisplayGPU) == 0) {
544*61046927SAndroid Build Coastguard Worker             psc->driScreenDisplayGPU = driCreateNewScreen3(screen, psc->fd_display_gpu,
545*61046927SAndroid Build Coastguard Worker                                                            loader_extensions,
546*61046927SAndroid Build Coastguard Worker                                                            DRI_SCREEN_DRI3,
547*61046927SAndroid Build Coastguard Worker                                                            &driver_configs, driver_name_is_inferred,
548*61046927SAndroid Build Coastguard Worker                                                            priv->has_multibuffer, psc);
549*61046927SAndroid Build Coastguard Worker          }
550*61046927SAndroid Build Coastguard Worker 
551*61046927SAndroid Build Coastguard Worker          free(driverNameDisplayGPU);
552*61046927SAndroid Build Coastguard Worker       }
553*61046927SAndroid Build Coastguard Worker    }
554*61046927SAndroid Build Coastguard Worker    priv->driver = GLX_DRIVER_DRI3;
555*61046927SAndroid Build Coastguard Worker 
556*61046927SAndroid Build Coastguard Worker    if (!dri_screen_init(&psc->base, priv, screen, psc->fd_render_gpu, loader_extensions, driver_name_is_inferred)) {
557*61046927SAndroid Build Coastguard Worker       ErrorMessageF("glx: failed to create dri3 screen\n");
558*61046927SAndroid Build Coastguard Worker       goto handle_error;
559*61046927SAndroid Build Coastguard Worker    }
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu == psc->fd_display_gpu)
562*61046927SAndroid Build Coastguard Worker       psc->driScreenDisplayGPU = psc->base.frontend_screen;
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker    psc->base.context_vtable = &dri3_context_vtable;
565*61046927SAndroid Build Coastguard Worker    psp = &psc->base.driScreen;
566*61046927SAndroid Build Coastguard Worker    psp->deinitScreen = dri3_deinit_screen;
567*61046927SAndroid Build Coastguard Worker    psp->createDrawable = dri3_create_drawable;
568*61046927SAndroid Build Coastguard Worker    psp->swapBuffers = dri3_swap_buffers;
569*61046927SAndroid Build Coastguard Worker 
570*61046927SAndroid Build Coastguard Worker    psp->getDrawableMSC = dri3_drawable_get_msc;
571*61046927SAndroid Build Coastguard Worker    psp->waitForMSC = dri3_wait_for_msc;
572*61046927SAndroid Build Coastguard Worker    psp->waitForSBC = dri3_wait_for_sbc;
573*61046927SAndroid Build Coastguard Worker    psp->setSwapInterval = dri3_set_swap_interval;
574*61046927SAndroid Build Coastguard Worker    psp->getSwapInterval = dri3_get_swap_interval;
575*61046927SAndroid Build Coastguard Worker    psp->maxSwapInterval = INT_MAX;
576*61046927SAndroid Build Coastguard Worker 
577*61046927SAndroid Build Coastguard Worker    /* when on a different gpu than the server, the server pixmaps
578*61046927SAndroid Build Coastguard Worker     * can have a tiling mode we can't read. Thus we can't create
579*61046927SAndroid Build Coastguard Worker     * a texture from them.
580*61046927SAndroid Build Coastguard Worker     */
581*61046927SAndroid Build Coastguard Worker    psc->base.can_EXT_texture_from_pixmap = psc->fd_render_gpu == psc->fd_display_gpu;
582*61046927SAndroid Build Coastguard Worker    psp->copySubBuffer = dri3_copy_sub_buffer;
583*61046927SAndroid Build Coastguard Worker 
584*61046927SAndroid Build Coastguard Worker    InfoMessageF("Using DRI3 for screen %d\n", screen);
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker    psc->prefer_back_buffer_reuse = 1;
587*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu != psc->fd_display_gpu) {
588*61046927SAndroid Build Coastguard Worker       unsigned value;
589*61046927SAndroid Build Coastguard Worker       if (dri_query_renderer_integer(psc->base.frontend_screen,
590*61046927SAndroid Build Coastguard Worker                                      __DRI2_RENDERER_PREFER_BACK_BUFFER_REUSE,
591*61046927SAndroid Build Coastguard Worker                                      &value) == 0)
592*61046927SAndroid Build Coastguard Worker          psc->prefer_back_buffer_reuse = value;
593*61046927SAndroid Build Coastguard Worker    }
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker 
596*61046927SAndroid Build Coastguard Worker    return &psc->base;
597*61046927SAndroid Build Coastguard Worker 
598*61046927SAndroid Build Coastguard Worker handle_error:
599*61046927SAndroid Build Coastguard Worker    if (!*return_zink)
600*61046927SAndroid Build Coastguard Worker       CriticalErrorMessageF("failed to load driver: %s\n", driverName ? driverName : "(null)");
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu != psc->fd_display_gpu && psc->driScreenDisplayGPU)
603*61046927SAndroid Build Coastguard Worker        driDestroyScreen(psc->driScreenDisplayGPU);
604*61046927SAndroid Build Coastguard Worker    psc->driScreenDisplayGPU = NULL;
605*61046927SAndroid Build Coastguard Worker    if (psc->fd_display_gpu >= 0 && psc->fd_render_gpu != psc->fd_display_gpu)
606*61046927SAndroid Build Coastguard Worker       close(psc->fd_display_gpu);
607*61046927SAndroid Build Coastguard Worker    if (psc->fd_render_gpu >= 0)
608*61046927SAndroid Build Coastguard Worker       close(psc->fd_render_gpu);
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker    glx_screen_cleanup(&psc->base);
611*61046927SAndroid Build Coastguard Worker    free(psc);
612*61046927SAndroid Build Coastguard Worker 
613*61046927SAndroid Build Coastguard Worker    return NULL;
614*61046927SAndroid Build Coastguard Worker }
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING */
617