1 /*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: SGI-B-2.0
6 */
7
8 /**
9 * \file glxext.c
10 * GLX protocol interface boot-strap code.
11 *
12 * Direct rendering support added by Precision Insight, Inc.
13 *
14 * \author Kevin E. Martin <[email protected]>
15 */
16
17 #include <assert.h>
18 #include <stdbool.h>
19 #include <stdarg.h>
20
21 #include "glxclient.h"
22 #include <X11/extensions/Xext.h>
23 #include <X11/extensions/extutil.h>
24 #ifdef GLX_USE_APPLEGL
25 #include "apple/apple_glx.h"
26 #include "apple/apple_visual.h"
27 #endif
28 #include "glxextensions.h"
29
30 #include "util/u_debug.h"
31 #ifndef GLX_USE_APPLEGL
32 #include "dri_common.h"
33 #endif
34
35 #include "loader_x11.h"
36 #ifdef HAVE_LIBDRM
37 #include "loader_dri3_helper.h"
38 #endif
39
40 #include <X11/Xlib-xcb.h>
41 #include <xcb/xcb.h>
42 #include <xcb/glx.h>
43 #include "dri_util.h"
44 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
45 #include <dlfcn.h>
46 #endif
47
48 #define __GLX_MIN_CONFIG_PROPS 18
49 #define __GLX_EXT_CONFIG_PROPS 32
50
51 /*
52 ** Since we send all non-core visual properties as token, value pairs,
53 ** we require 2 words across the wire. In order to maintain backwards
54 ** compatibility, we need to send the total number of words that the
55 ** VisualConfigs are sent back in so old libraries can simply "ignore"
56 ** the new properties.
57 */
58 #define __GLX_TOTAL_CONFIG \
59 (__GLX_MIN_CONFIG_PROPS + 2 * __GLX_EXT_CONFIG_PROPS)
60
61 _X_HIDDEN void
glx_message(int level,const char * f,...)62 glx_message(int level, const char *f, ...)
63 {
64 va_list args;
65 int threshold = _LOADER_WARNING;
66 const char *libgl_debug;
67
68 libgl_debug = getenv("LIBGL_DEBUG");
69 if (libgl_debug) {
70 if (strstr(libgl_debug, "quiet"))
71 threshold = _LOADER_FATAL;
72 else if (strstr(libgl_debug, "verbose"))
73 threshold = _LOADER_DEBUG;
74 }
75
76 /* Note that the _LOADER_* levels are lower numbers for more severe. */
77 if (level <= threshold) {
78 va_start(args, f);
79 vfprintf(stderr, f, args);
80 va_end(args);
81 }
82 }
83
84 /*
85 ** You can set this cell to 1 to force the gl drawing stuff to be
86 ** one command per packet
87 */
88 _X_HIDDEN int __glXDebug = 0;
89
90 /* Extension required boiler plate */
91
92 static const char __glXExtensionName[] = GLX_EXTENSION_NAME;
93 static struct glx_display *glx_displays;
94
95 static /* const */ char *error_list[] = {
96 "GLXBadContext",
97 "GLXBadContextState",
98 "GLXBadDrawable",
99 "GLXBadPixmap",
100 "GLXBadContextTag",
101 "GLXBadCurrentWindow",
102 "GLXBadRenderRequest",
103 "GLXBadLargeRequest",
104 "GLXUnsupportedPrivateRequest",
105 "GLXBadFBConfig",
106 "GLXBadPbuffer",
107 "GLXBadCurrentDrawable",
108 "GLXBadWindow",
109 "GLXBadProfileARB",
110 };
111
112 #ifdef GLX_USE_APPLEGL
113 static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes,
114 char *buf, int n);
115 #endif
116
117 static
XEXT_GENERATE_ERROR_STRING(__glXErrorString,__glXExtensionName,__GLX_NUMBER_ERRORS,error_list)118 XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
119 __GLX_NUMBER_ERRORS, error_list)
120
121 /*
122 * GLX events are a bit funky. We don't stuff the X event code into
123 * our user exposed (via XNextEvent) structure. Instead we use the GLX
124 * private event code namespace (and hope it doesn't conflict). Clients
125 * have to know that bit 15 in the event type field means they're getting
126 * a GLX event, and then handle the various sub-event types there, rather
127 * than simply checking the event code and handling it directly.
128 */
129
130 static Bool
131 __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
132 {
133 struct glx_display *glx_dpy = __glXInitialize(dpy);
134
135 if (glx_dpy == NULL)
136 return False;
137
138 switch ((wire->u.u.type & 0x7f) - glx_dpy->codes.first_event) {
139 case GLX_PbufferClobber:
140 {
141 GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
142 xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire;
143 aevent->event_type = awire->event_type;
144 aevent->serial = awire->sequenceNumber;
145 aevent->draw_type = awire->draw_type;
146 aevent->drawable = awire->drawable;
147 aevent->buffer_mask = awire->buffer_mask;
148 aevent->aux_buffer = awire->aux_buffer;
149 aevent->x = awire->x;
150 aevent->y = awire->y;
151 aevent->width = awire->width;
152 aevent->height = awire->height;
153 aevent->count = awire->count;
154 return True;
155 }
156 case GLX_BufferSwapComplete:
157 {
158 GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
159 xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
160 struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
161
162 if (!glxDraw)
163 return False;
164
165 aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
166 aevent->send_event = (awire->type & 0x80) != 0;
167 aevent->display = dpy;
168 aevent->event_type = awire->event_type;
169 aevent->drawable = glxDraw->xDrawable;
170 aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
171 aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
172
173 /* Handle 32-Bit wire sbc wraparound in both directions to cope with out
174 * of sequence 64-Bit sbc's
175 */
176 if ((int64_t) awire->sbc < ((int64_t) glxDraw->lastEventSbc - 0x40000000))
177 glxDraw->eventSbcWrap += 0x100000000;
178 if ((int64_t) awire->sbc > ((int64_t) glxDraw->lastEventSbc + 0x40000000))
179 glxDraw->eventSbcWrap -= 0x100000000;
180 glxDraw->lastEventSbc = awire->sbc;
181 aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
182 return True;
183 }
184 default:
185 /* client doesn't support server event */
186 break;
187 }
188
189 return False;
190 }
191
192 /* We don't actually support this. It doesn't make sense for clients to
193 * send each other GLX events.
194 */
195 static Status
__glXEventToWire(Display * dpy,XEvent * event,xEvent * wire)196 __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
197 {
198 struct glx_display *glx_dpy = __glXInitialize(dpy);
199
200 if (glx_dpy == NULL)
201 return False;
202
203 switch (event->type) {
204 case GLX_DAMAGED:
205 break;
206 case GLX_SAVED:
207 break;
208 case GLX_EXCHANGE_COMPLETE_INTEL:
209 break;
210 case GLX_COPY_COMPLETE_INTEL:
211 break;
212 case GLX_FLIP_COMPLETE_INTEL:
213 break;
214 default:
215 /* client doesn't support server event */
216 break;
217 }
218
219 return Success;
220 }
221
222 /************************************************************************/
223 /*
224 ** Free the per screen configs data as well as the array of
225 ** __glXScreenConfigs.
226 */
227 static void
FreeScreenConfigs(struct glx_display * priv)228 FreeScreenConfigs(struct glx_display * priv)
229 {
230 struct glx_screen *psc;
231 GLint i, screens;
232
233 /* Free screen configuration information */
234 screens = ScreenCount(priv->dpy);
235 for (i = 0; i < screens; i++) {
236 psc = priv->screens[i];
237 if (!psc)
238 continue;
239 glx_screen_cleanup(psc);
240
241 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
242 if (psc->driScreen.deinitScreen)
243 psc->driScreen.deinitScreen(psc);
244 /* Free the direct rendering per screen data */
245 driDestroyScreen(psc->frontend_screen);
246 #endif
247 free(psc);
248 }
249 free((char *) priv->screens);
250 priv->screens = NULL;
251 }
252
253 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
254 static void
free_zombie_glx_drawable(struct set_entry * entry)255 free_zombie_glx_drawable(struct set_entry *entry)
256 {
257 __GLXDRIdrawable *pdraw = (__GLXDRIdrawable *)entry->key;
258
259 pdraw->destroyDrawable(pdraw);
260 }
261 #endif
262
263 static void
glx_display_free(struct glx_display * priv)264 glx_display_free(struct glx_display *priv)
265 {
266 struct glx_context *gc;
267
268 gc = __glXGetCurrentContext();
269 if (priv->dpy == gc->currentDpy) {
270 if (gc != &dummyContext)
271 gc->vtable->unbind(gc);
272
273 gc->vtable->destroy(gc);
274 __glXSetCurrentContextNull();
275 }
276
277 /* Needs to be done before free screen. */
278 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
279 _mesa_set_destroy(priv->zombieGLXDrawable, free_zombie_glx_drawable);
280 #endif
281
282 FreeScreenConfigs(priv);
283
284 __glxHashDestroy(priv->glXDrawHash);
285
286 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
287 __glxHashDestroy(priv->drawHash);
288 if (priv->dri2Hash)
289 __glxHashDestroy(priv->dri2Hash);
290
291 #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
292
293 free((char *) priv);
294 }
295
296 static int
__glXCloseDisplay(Display * dpy,XExtCodes * codes)297 __glXCloseDisplay(Display * dpy, XExtCodes * codes)
298 {
299 struct glx_display *priv, **prev;
300
301 _XLockMutex(_Xglobal_lock);
302 prev = &glx_displays;
303 for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) {
304 if (priv->dpy == dpy) {
305 *prev = priv->next;
306 break;
307 }
308 }
309 _XUnlockMutex(_Xglobal_lock);
310
311 if (priv != NULL)
312 glx_display_free(priv);
313
314 return 1;
315 }
316
317 /*
318 ** Query the version of the GLX extension. This procedure works even if
319 ** the client extension is not completely set up.
320 */
321 static Bool
QueryVersion(Display * dpy,int opcode,int * major,int * minor)322 QueryVersion(Display * dpy, int opcode, int *major, int *minor)
323 {
324 xcb_connection_t *c = XGetXCBConnection(dpy);
325 xcb_glx_query_version_reply_t *reply = xcb_glx_query_version_reply(c,
326 xcb_glx_query_version
327 (c,
328 GLX_MAJOR_VERSION,
329 GLX_MINOR_VERSION),
330 NULL);
331
332 if (!reply)
333 return GL_FALSE;
334
335 if (reply->major_version != GLX_MAJOR_VERSION) {
336 free(reply);
337 return GL_FALSE;
338 }
339 *major = reply->major_version;
340 *minor = min(reply->minor_version, GLX_MINOR_VERSION);
341 free(reply);
342 return GL_TRUE;
343 }
344
345 /*
346 * We don't want to enable this GLX_OML_swap_method in glxext.h,
347 * because we can't support it. The X server writes it out though,
348 * so we should handle it somehow, to avoid false warnings.
349 */
350 enum {
351 IGNORE_GLX_SWAP_METHOD_OML = 0x8060
352 };
353
354
355 static GLint
convert_from_x_visual_type(int visualType)356 convert_from_x_visual_type(int visualType)
357 {
358 static const int glx_visual_types[] = {
359 [StaticGray] = GLX_STATIC_GRAY,
360 [GrayScale] = GLX_GRAY_SCALE,
361 [StaticColor] = GLX_STATIC_COLOR,
362 [PseudoColor] = GLX_PSEUDO_COLOR,
363 [TrueColor] = GLX_TRUE_COLOR,
364 [DirectColor] = GLX_DIRECT_COLOR,
365 };
366
367 if (visualType < ARRAY_SIZE(glx_visual_types))
368 return glx_visual_types[visualType];
369
370 return GLX_NONE;
371 }
372
373 /*
374 * getVisualConfigs uses the !tagged_only path.
375 * getFBConfigs uses the tagged_only path.
376 */
377 _X_HIDDEN void
__glXInitializeVisualConfigFromTags(struct glx_config * config,int count,const INT32 * bp,Bool tagged_only,Bool fbconfig_style_tags)378 __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
379 const INT32 * bp, Bool tagged_only,
380 Bool fbconfig_style_tags)
381 {
382 int i;
383
384 if (!tagged_only) {
385 /* Copy in the first set of properties */
386 config->visualID = *bp++;
387
388 config->visualType = convert_from_x_visual_type(*bp++);
389
390 config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
391
392 config->redBits = *bp++;
393 config->greenBits = *bp++;
394 config->blueBits = *bp++;
395 config->alphaBits = *bp++;
396 config->accumRedBits = *bp++;
397 config->accumGreenBits = *bp++;
398 config->accumBlueBits = *bp++;
399 config->accumAlphaBits = *bp++;
400
401 config->doubleBufferMode = *bp++;
402 config->stereoMode = *bp++;
403
404 config->rgbBits = *bp++;
405 config->depthBits = *bp++;
406 config->stencilBits = *bp++;
407 config->numAuxBuffers = *bp++;
408 config->level = *bp++;
409
410 #ifdef GLX_USE_APPLEGL
411 /* AppleSGLX supports pixmap and pbuffers with all config. */
412 config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
413 /* Unfortunately this can create an ABI compatibility problem. */
414 count -= 18;
415 #else
416 count -= __GLX_MIN_CONFIG_PROPS;
417 #endif
418 }
419
420 /*
421 ** Additional properties may be in a list at the end
422 ** of the reply. They are in pairs of property type
423 ** and property value.
424 */
425
426 #define FETCH_OR_SET(tag) \
427 config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
428
429 for (i = 0; i < count; i += 2) {
430 long int tag = *bp++;
431
432 switch (tag) {
433 case GLX_RGBA:
434 if (fbconfig_style_tags)
435 config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
436 else
437 config->renderType = GLX_RGBA_BIT;
438 break;
439 case GLX_BUFFER_SIZE:
440 config->rgbBits = *bp++;
441 break;
442 case GLX_LEVEL:
443 config->level = *bp++;
444 break;
445 case GLX_DOUBLEBUFFER:
446 FETCH_OR_SET(doubleBufferMode);
447 break;
448 case GLX_STEREO:
449 FETCH_OR_SET(stereoMode);
450 break;
451 case GLX_AUX_BUFFERS:
452 config->numAuxBuffers = *bp++;
453 break;
454 case GLX_RED_SIZE:
455 config->redBits = *bp++;
456 break;
457 case GLX_GREEN_SIZE:
458 config->greenBits = *bp++;
459 break;
460 case GLX_BLUE_SIZE:
461 config->blueBits = *bp++;
462 break;
463 case GLX_ALPHA_SIZE:
464 config->alphaBits = *bp++;
465 break;
466 case GLX_DEPTH_SIZE:
467 config->depthBits = *bp++;
468 break;
469 case GLX_STENCIL_SIZE:
470 config->stencilBits = *bp++;
471 break;
472 case GLX_ACCUM_RED_SIZE:
473 config->accumRedBits = *bp++;
474 break;
475 case GLX_ACCUM_GREEN_SIZE:
476 config->accumGreenBits = *bp++;
477 break;
478 case GLX_ACCUM_BLUE_SIZE:
479 config->accumBlueBits = *bp++;
480 break;
481 case GLX_ACCUM_ALPHA_SIZE:
482 config->accumAlphaBits = *bp++;
483 break;
484 case GLX_VISUAL_CAVEAT_EXT:
485 config->visualRating = *bp++;
486 break;
487 case GLX_X_VISUAL_TYPE:
488 config->visualType = *bp++;
489 break;
490 case GLX_TRANSPARENT_TYPE:
491 config->transparentPixel = *bp++;
492 break;
493 case GLX_TRANSPARENT_INDEX_VALUE:
494 config->transparentIndex = *bp++;
495 break;
496 case GLX_TRANSPARENT_RED_VALUE:
497 config->transparentRed = *bp++;
498 break;
499 case GLX_TRANSPARENT_GREEN_VALUE:
500 config->transparentGreen = *bp++;
501 break;
502 case GLX_TRANSPARENT_BLUE_VALUE:
503 config->transparentBlue = *bp++;
504 break;
505 case GLX_TRANSPARENT_ALPHA_VALUE:
506 config->transparentAlpha = *bp++;
507 break;
508 case GLX_VISUAL_ID:
509 config->visualID = *bp++;
510 break;
511 case GLX_DRAWABLE_TYPE:
512 config->drawableType = *bp++;
513 #ifdef GLX_USE_APPLEGL
514 /* AppleSGLX supports pixmap and pbuffers with all config. */
515 config->drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
516 #endif
517 break;
518 case GLX_RENDER_TYPE: /* fbconfig render type bits */
519 config->renderType = *bp++;
520 break;
521 case GLX_X_RENDERABLE:
522 config->xRenderable = *bp++;
523 break;
524 case GLX_FBCONFIG_ID:
525 config->fbconfigID = *bp++;
526 break;
527 case GLX_MAX_PBUFFER_WIDTH:
528 config->maxPbufferWidth = *bp++;
529 break;
530 case GLX_MAX_PBUFFER_HEIGHT:
531 config->maxPbufferHeight = *bp++;
532 break;
533 case GLX_MAX_PBUFFER_PIXELS:
534 config->maxPbufferPixels = *bp++;
535 break;
536 #ifndef GLX_USE_APPLEGL
537 case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
538 config->optimalPbufferWidth = *bp++;
539 break;
540 case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
541 config->optimalPbufferHeight = *bp++;
542 break;
543 case GLX_VISUAL_SELECT_GROUP_SGIX:
544 config->visualSelectGroup = *bp++;
545 break;
546 #endif
547 case GLX_SAMPLE_BUFFERS_SGIS:
548 config->sampleBuffers = *bp++;
549 break;
550 case GLX_SAMPLES_SGIS:
551 config->samples = *bp++;
552 break;
553 case IGNORE_GLX_SWAP_METHOD_OML:
554 /* We ignore this tag. See the comment above this function. */
555 ++bp;
556 break;
557 #ifndef GLX_USE_APPLEGL
558 case GLX_BIND_TO_TEXTURE_RGB_EXT:
559 config->bindToTextureRgb = *bp++;
560 break;
561 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
562 config->bindToTextureRgba = *bp++;
563 break;
564 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
565 config->bindToMipmapTexture = *bp++;
566 break;
567 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
568 config->bindToTextureTargets = *bp++;
569 break;
570 case GLX_Y_INVERTED_EXT:
571 config->yInverted = *bp++;
572 break;
573 #endif
574 case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
575 config->sRGBCapable = *bp++;
576 break;
577
578 case GLX_USE_GL:
579 if (fbconfig_style_tags)
580 bp++;
581 break;
582 case GLX_FLOAT_COMPONENTS_NV:
583 config->floatComponentsNV = *bp++;
584 break;
585 case None:
586 i = count;
587 break;
588 default: {
589 long int tagvalue = *bp++;
590 DebugMessageF("WARNING: unknown fbconfig attribute from server: "
591 "tag 0x%lx value 0x%lx\n", tag, tagvalue);
592 break;
593 }
594 }
595 }
596 }
597
598 static struct glx_config *
createConfigsFromProperties(Display * dpy,int nvisuals,int nprops,int screen,GLboolean tagged_only)599 createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
600 int screen, GLboolean tagged_only)
601 {
602 INT32 buf[__GLX_TOTAL_CONFIG], *props;
603 unsigned prop_size;
604 struct glx_config *modes, *m;
605 int i;
606
607 if (nprops == 0)
608 return NULL;
609
610 /* Check number of properties */
611 if (nprops < __GLX_MIN_CONFIG_PROPS)
612 return NULL;
613
614 /* Allocate memory for our config structure */
615 modes = glx_config_create_list(nvisuals);
616 if (!modes)
617 return NULL;
618
619 prop_size = nprops * __GLX_SIZE_INT32;
620 if (prop_size <= sizeof(buf))
621 props = buf;
622 else
623 props = malloc(prop_size);
624
625 /* Read each config structure and convert it into our format */
626 m = modes;
627 for (i = 0; i < nvisuals; i++) {
628 _XRead(dpy, (char *) props, prop_size);
629 /* If this is GLXGetVisualConfigs then the reply will not include
630 * any drawable type info, but window support is implied because
631 * that's what a Visual describes, and pixmap support is implied
632 * because you almost certainly have a pixmap format corresponding
633 * to your visual format.
634 */
635 if (!tagged_only)
636 m->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
637 __glXInitializeVisualConfigFromTags(m, nprops, props,
638 tagged_only, GL_TRUE);
639 m->screen = screen;
640 m = m->next;
641 }
642
643 if (props != buf)
644 free(props);
645
646 return modes;
647 }
648
649 static GLboolean
getVisualConfigs(struct glx_screen * psc,struct glx_display * priv,int screen)650 getVisualConfigs(struct glx_screen *psc,
651 struct glx_display *priv, int screen)
652 {
653 xGLXGetVisualConfigsReq *req;
654 xGLXGetVisualConfigsReply reply;
655 Display *dpy = priv->dpy;
656
657 LockDisplay(dpy);
658
659 psc->visuals = NULL;
660 GetReq(GLXGetVisualConfigs, req);
661 req->reqType = priv->codes.major_opcode;
662 req->glxCode = X_GLXGetVisualConfigs;
663 req->screen = screen;
664
665 if (!_XReply(dpy, (xReply *) & reply, 0, False))
666 goto out;
667
668 psc->visuals = createConfigsFromProperties(dpy,
669 reply.numVisuals,
670 reply.numProps,
671 screen, GL_FALSE);
672
673 out:
674 UnlockDisplay(dpy);
675 return psc->visuals != NULL;
676 }
677
678 static GLboolean
getFBConfigs(struct glx_screen * psc,struct glx_display * priv,int screen)679 getFBConfigs(struct glx_screen *psc, struct glx_display *priv, int screen)
680 {
681 xGLXGetFBConfigsReq *fb_req;
682 xGLXGetFBConfigsReply reply;
683 Display *dpy = priv->dpy;
684
685 psc->serverGLXexts = __glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
686
687 if (psc->serverGLXexts == NULL) {
688 return GL_FALSE;
689 }
690
691 LockDisplay(dpy);
692
693 psc->configs = NULL;
694 GetReq(GLXGetFBConfigs, fb_req);
695 fb_req->reqType = priv->codes.major_opcode;
696 fb_req->glxCode = X_GLXGetFBConfigs;
697 fb_req->screen = screen;
698
699 if (!_XReply(dpy, (xReply *) & reply, 0, False))
700 goto out;
701
702 psc->configs = createConfigsFromProperties(dpy,
703 reply.numFBConfigs,
704 reply.numAttribs * 2,
705 screen, GL_TRUE);
706
707 out:
708 UnlockDisplay(dpy);
709 return psc->configs != NULL;
710 }
711
712 _X_HIDDEN Bool
glx_screen_init(struct glx_screen * psc,int screen,struct glx_display * priv)713 glx_screen_init(struct glx_screen *psc,
714 int screen, struct glx_display * priv)
715 {
716 /* Initialize per screen dynamic client GLX extensions */
717 psc->ext_list_first_time = GL_TRUE;
718 psc->scr = screen;
719 psc->dpy = priv->dpy;
720 psc->display = priv;
721
722 if (!getVisualConfigs(psc, priv, screen))
723 return GL_FALSE;
724
725 if (!getFBConfigs(psc, priv, screen))
726 return GL_FALSE;
727
728 return GL_TRUE;
729 }
730
731 _X_HIDDEN void
glx_screen_cleanup(struct glx_screen * psc)732 glx_screen_cleanup(struct glx_screen *psc)
733 {
734 if (psc->configs) {
735 glx_config_destroy_list(psc->configs);
736 free(psc->effectiveGLXexts);
737 psc->configs = NULL; /* NOTE: just for paranoia */
738 }
739 if (psc->visuals) {
740 glx_config_destroy_list(psc->visuals);
741 psc->visuals = NULL; /* NOTE: just for paranoia */
742 }
743 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
744 if (psc->driver_configs) {
745 driDestroyConfigs(psc->driver_configs);
746 psc->driver_configs = NULL;
747 }
748 #endif
749 free((char *) psc->serverGLXexts);
750 free((char *) psc->serverGLXvendor);
751 free((char *) psc->serverGLXversion);
752 free(psc->driverName);
753 }
754
755 static void
bind_extensions(struct glx_screen * psc,const char * driverName)756 bind_extensions(struct glx_screen *psc, const char *driverName)
757 {
758 unsigned mask;
759
760 if (psc->display->driver != GLX_DRIVER_SW) {
761 __glXEnableDirectExtension(psc, "GLX_EXT_buffer_age");
762 __glXEnableDirectExtension(psc, "GLX_EXT_swap_control");
763 __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
764 __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
765 __glXEnableDirectExtension(psc, "GLX_OML_sync_control");
766 __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
767 // for zink this needs to check whether RELAXED is available
768 if (psc->display->driver == GLX_DRIVER_DRI3)
769 __glXEnableDirectExtension(psc, "GLX_EXT_swap_control_tear");
770 }
771 if (psc->display->driver != GLX_DRIVER_ZINK_YES)
772 __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
773 __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
774
775 if (psc->can_EXT_texture_from_pixmap)
776 __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
777
778 /*
779 * GLX_INTEL_swap_event is broken on the server side, where it's
780 * currently unconditionally enabled. This completely breaks
781 * systems running on drivers which don't support that extension.
782 * There's no way to test for its presence on this side, so instead
783 * of disabling it unconditionally, just disable it for drivers
784 * which are known to not support it.
785 *
786 * This was fixed in xserver 1.15.0 (190b03215), so now we only
787 * disable the broken driver.
788 */
789 if (!driverName || strcmp(driverName, "vmwgfx") != 0) {
790 __glXEnableDirectExtension(psc, "GLX_INTEL_swap_event");
791 }
792
793 mask = driGetAPIMask(psc->frontend_screen);
794
795 __glXEnableDirectExtension(psc, "GLX_ARB_create_context");
796 __glXEnableDirectExtension(psc, "GLX_ARB_create_context_profile");
797 __glXEnableDirectExtension(psc, "GLX_ARB_create_context_no_error");
798 __glXEnableDirectExtension(psc, "GLX_EXT_no_config_context");
799
800 if ((mask & ((1 << __DRI_API_GLES) |
801 (1 << __DRI_API_GLES2) |
802 (1 << __DRI_API_GLES3))) != 0) {
803 __glXEnableDirectExtension(psc,
804 "GLX_EXT_create_context_es_profile");
805 __glXEnableDirectExtension(psc,
806 "GLX_EXT_create_context_es2_profile");
807 }
808
809 if (dri_get_screen_param(psc->frontend_screen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY))
810 __glXEnableDirectExtension(psc,
811 "GLX_ARB_create_context_robustness");
812
813 __glXEnableDirectExtension(psc, "GLX_ARB_context_flush_control");
814 __glXEnableDirectExtension(psc, "GLX_MESA_query_renderer");
815
816 __glXEnableDirectExtension(psc, "GLX_MESA_gl_interop");
817
818 char *tmp;
819 if (dri2GalliumConfigQuerys(psc->frontend_screen, "glx_extension_override",
820 &tmp) == 0)
821 __glXParseExtensionOverride(psc, tmp);
822
823 if (dri2GalliumConfigQuerys(psc->frontend_screen,
824 "indirect_gl_extension_override",
825 &tmp) == 0)
826 __IndirectGlParseExtensionOverride(psc, tmp);
827
828 {
829 uint8_t force = false;
830 if (dri2GalliumConfigQueryb(psc->frontend_screen, "force_direct_glx_context",
831 &force) == 0) {
832 psc->force_direct_context = force;
833 }
834
835 uint8_t invalid_glx_destroy_window = false;
836 if (dri2GalliumConfigQueryb(psc->frontend_screen,
837 "allow_invalid_glx_destroy_window",
838 &invalid_glx_destroy_window) == 0) {
839 psc->allow_invalid_glx_destroy_window = invalid_glx_destroy_window;
840 }
841
842 uint8_t keep_native_window_glx_drawable = false;
843 if (dri2GalliumConfigQueryb(psc->frontend_screen,
844 "keep_native_window_glx_drawable",
845 &keep_native_window_glx_drawable) == 0) {
846 psc->keep_native_window_glx_drawable = keep_native_window_glx_drawable;
847 }
848 }
849 }
850
851
852 /*
853 ** Allocate the memory for the per screen configs for each screen.
854 ** If that works then fetch the per screen configs data.
855 */
856 static Bool
AllocAndFetchScreenConfigs(Display * dpy,struct glx_display * priv,enum glx_driver glx_driver,Bool driver_name_is_inferred)857 AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv, enum glx_driver glx_driver, Bool driver_name_is_inferred)
858 {
859 struct glx_screen *psc;
860 GLint i, screens;
861 unsigned screen_count = 0;
862 bool zink = (glx_driver & (GLX_DRIVER_ZINK_INFER | GLX_DRIVER_ZINK_YES)) > 0;
863
864 /*
865 ** First allocate memory for the array of per screen configs.
866 */
867 screens = ScreenCount(dpy);
868 priv->screens = calloc(screens, sizeof *priv->screens);
869 if (!priv->screens)
870 return GL_FALSE;
871
872 for (i = 0; i < screens; i++) {
873 psc = NULL;
874 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
875 #if defined(GLX_USE_DRM)
876 if (glx_driver & GLX_DRIVER_DRI3) {
877 bool use_zink;
878 psc = dri3_create_screen(i, priv, driver_name_is_inferred, &use_zink);
879 if (use_zink) {
880 glx_driver |= GLX_DRIVER_ZINK_YES;
881 zink = true;
882 driver_name_is_inferred = false;
883 }
884 }
885 #if defined(HAVE_X11_DRI2)
886 if (psc == NULL && glx_driver & GLX_DRIVER_DRI2 && dri2CheckSupport(dpy)) {
887 psc = dri2CreateScreen(i, priv, driver_name_is_inferred);
888 if (psc)
889 priv->dri2Hash = __glxHashCreate();
890 }
891 #endif
892 #endif /* GLX_USE_DRM */
893
894 #ifdef GLX_USE_WINDOWSGL
895 if (psc == NULL && glx_driver & GLX_DRIVER_WINDOWS) {
896 psc = driwindowsCreateScreen(i, priv, driver_name_is_inferred);
897 }
898 #endif
899
900 #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
901 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
902 if (psc == NULL &&
903 (glx_driver & GLX_DRIVER_SW || zink)) {
904 psc = driswCreateScreen(i, priv, glx_driver, driver_name_is_inferred);
905 }
906 #endif
907
908 bool indirect = false;
909
910 #if defined(GLX_USE_APPLEGL) && !defined(GLX_USE_APPLE)
911 if (psc == NULL)
912 psc = applegl_create_screen(i, priv);
913 #else
914 if (psc == NULL && !zink)
915 {
916 psc = indirect_create_screen(i, priv);
917 indirect = true;
918 }
919 #endif
920 priv->screens[i] = psc;
921 if (psc)
922 screen_count++;
923
924 if(indirect) /* Load extensions required only for indirect glx */
925 glxSendClientInfo(priv, i);
926 else if (priv->driver != GLX_DRIVER_WINDOWS)
927 bind_extensions(psc, psc->driverName);
928 }
929 if (zink && !screen_count)
930 return GL_FALSE;
931 SyncHandle();
932 return GL_TRUE;
933 }
934
935 /*
936 ** Initialize the client side extension code.
937 */
938 _X_HIDDEN struct glx_display *
__glXInitialize(Display * dpy)939 __glXInitialize(Display * dpy)
940 {
941 XExtCodes *codes;
942 struct glx_display *dpyPriv, *d;
943 int i, majorVersion = 0;
944
945 _XLockMutex(_Xglobal_lock);
946
947 for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) {
948 if (dpyPriv->dpy == dpy) {
949 _XUnlockMutex(_Xglobal_lock);
950 return dpyPriv;
951 }
952 }
953
954 /* Drop the lock while we create the display private. */
955 _XUnlockMutex(_Xglobal_lock);
956
957 dpyPriv = calloc(1, sizeof *dpyPriv);
958 if (!dpyPriv)
959 return NULL;
960
961 codes = XInitExtension(dpy, __glXExtensionName);
962 if (!codes) {
963 free(dpyPriv);
964 return NULL;
965 }
966
967 dpyPriv->codes = *codes;
968 dpyPriv->dpy = dpy;
969
970 /* This GLX implementation requires GLX 1.3 */
971 if (!QueryVersion(dpy, dpyPriv->codes.major_opcode,
972 &majorVersion, &dpyPriv->minorVersion)
973 || (majorVersion != 1)
974 || (majorVersion == 1 && dpyPriv->minorVersion < 3)) {
975 free(dpyPriv);
976 return NULL;
977 }
978
979 for (i = 0; i < __GLX_NUMBER_EVENTS; i++) {
980 XESetWireToEvent(dpy, dpyPriv->codes.first_event + i, __glXWireToEvent);
981 XESetEventToWire(dpy, dpyPriv->codes.first_event + i, __glXEventToWire);
982 }
983
984 XESetCloseDisplay(dpy, dpyPriv->codes.extension, __glXCloseDisplay);
985 XESetErrorString (dpy, dpyPriv->codes.extension, __glXErrorString);
986
987 dpyPriv->glXDrawHash = __glxHashCreate();
988
989 enum glx_driver glx_driver = 0;
990 const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE");
991
992 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
993 Bool glx_direct = !debug_get_bool_option("LIBGL_ALWAYS_INDIRECT", false);
994 Bool glx_accel = !debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false);
995 Bool dri3 = !debug_get_bool_option("LIBGL_DRI3_DISABLE", false);
996 Bool kopper = !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false);
997
998 if (env && !strcmp(env, "zink"))
999 glx_driver |= GLX_DRIVER_ZINK_YES;
1000
1001 dpyPriv->drawHash = __glxHashCreate();
1002
1003 dpyPriv->zombieGLXDrawable = _mesa_pointer_set_create(NULL);
1004
1005 /* Set the logger before the *CreateDisplay functions. */
1006 loader_set_logger(glx_message);
1007
1008 /*
1009 ** Initialize the direct rendering per display data and functions.
1010 ** Note: This _must_ be done before calling any other DRI routines
1011 ** (e.g., those called in AllocAndFetchScreenConfigs).
1012 */
1013 #if defined(GLX_USE_DRM)
1014 bool dri3_err = false;
1015 if (glx_direct && glx_accel && dri3)
1016 dpyPriv->has_multibuffer = x11_dri3_check_multibuffer(XGetXCBConnection(dpy), &dri3_err, &dpyPriv->has_explicit_modifiers);
1017 if (glx_direct && glx_accel &&
1018 (!(glx_driver & GLX_DRIVER_ZINK_YES) || !kopper)) {
1019 if (dri3) {
1020 /* dri3 is tried as long as this doesn't error; whether modifiers work is not relevant */
1021 if (!dri3_err) {
1022 glx_driver |= GLX_DRIVER_DRI3;
1023 /* nouveau wants to fallback to zink so if we get a screen enable try_zink */
1024 if (!debug_get_bool_option("LIBGL_KOPPER_DISABLE", false))
1025 glx_driver |= GLX_DRIVER_ZINK_INFER;
1026 }
1027 }
1028 #if defined(HAVE_X11_DRI2)
1029 if (!debug_get_bool_option("LIBGL_DRI2_DISABLE", false))
1030 glx_driver |= GLX_DRIVER_DRI2;
1031 #endif
1032 #if defined(HAVE_ZINK)
1033 if (!(glx_driver & (GLX_DRIVER_DRI2 | GLX_DRIVER_DRI3)))
1034 if (kopper && !getenv("GALLIUM_DRIVER"))
1035 glx_driver |= GLX_DRIVER_ZINK_INFER;
1036 #endif /* HAVE_ZINK */
1037 }
1038 #endif /* GLX_USE_DRM */
1039 if (glx_direct)
1040 glx_driver |= GLX_DRIVER_SW;
1041
1042 if (!dpyPriv->has_explicit_modifiers && glx_accel && !debug_get_bool_option("LIBGL_KOPPER_DRI2", false)) {
1043 if (glx_driver & GLX_DRIVER_ZINK_YES) {
1044 /* only print error if zink was explicitly requested */
1045 CriticalErrorMessageF("DRI3 not available\n");
1046 free(dpyPriv);
1047 return NULL;
1048 }
1049 /* if no dri3 and not using dri2, disable zink */
1050 glx_driver &= ~GLX_DRIVER_ZINK_INFER;
1051 }
1052
1053 #ifdef GLX_USE_WINDOWSGL
1054 if (glx_direct && glx_accel)
1055 glx_driver |= GLX_DRIVER_WINDOWS;
1056 #else
1057 #ifndef RTLD_NOW
1058 #define RTLD_NOW 0
1059 #endif
1060 #ifndef RTLD_GLOBAL
1061 #define RTLD_GLOBAL 0
1062 #endif
1063
1064 #ifndef GL_LIB_NAME
1065 #define GL_LIB_NAME "libGL.so.1"
1066 #endif
1067
1068 void *glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL);
1069 if (glhandle)
1070 dlclose(glhandle);
1071
1072 #endif
1073 #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
1074
1075 #if defined(GLX_USE_APPLEGL) && !defined(GLX_USE_APPLE)
1076 glx_driver |= GLX_DRIVER_SW;
1077 #endif
1078
1079 if (!AllocAndFetchScreenConfigs(dpy, dpyPriv, glx_driver, !env)) {
1080 Bool fail = True;
1081 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
1082 if (glx_driver & GLX_DRIVER_ZINK_INFER) {
1083 fail = !AllocAndFetchScreenConfigs(dpy, dpyPriv, GLX_DRIVER_SW, true);
1084 }
1085 #endif
1086 if (fail) {
1087 free(dpyPriv);
1088 return NULL;
1089 }
1090 }
1091
1092 glxSendClientInfo(dpyPriv, -1);
1093
1094 /* Grab the lock again and add the display private, unless somebody
1095 * beat us to initializing on this display in the meantime. */
1096 _XLockMutex(_Xglobal_lock);
1097
1098 for (d = glx_displays; d; d = d->next) {
1099 if (d->dpy == dpy) {
1100 _XUnlockMutex(_Xglobal_lock);
1101 glx_display_free(dpyPriv);
1102 return d;
1103 }
1104 }
1105
1106 dpyPriv->next = glx_displays;
1107 glx_displays = dpyPriv;
1108
1109 _XUnlockMutex(_Xglobal_lock);
1110
1111 return dpyPriv;
1112 }
1113
1114 /*
1115 ** Setup for sending a GLX command on dpy. Make sure the extension is
1116 ** initialized. Try to avoid calling __glXInitialize as its kinda slow.
1117 */
1118 _X_HIDDEN CARD8
__glXSetupForCommand(Display * dpy)1119 __glXSetupForCommand(Display * dpy)
1120 {
1121 struct glx_context *gc;
1122 struct glx_display *priv;
1123
1124 /* If this thread has a current context, flush its rendering commands */
1125 gc = __glXGetCurrentContext();
1126 if (gc->currentDpy) {
1127 /* Flush rendering buffer of the current context, if any */
1128 (void) __glXFlushRenderBuffer(gc, gc->pc);
1129
1130 if (gc->currentDpy == dpy) {
1131 /* Use opcode from gc because its right */
1132 return gc->majorOpcode;
1133 }
1134 else {
1135 /*
1136 ** Have to get info about argument dpy because it might be to
1137 ** a different server
1138 */
1139 }
1140 }
1141
1142 /* Forced to lookup extension via the slow initialize route */
1143 priv = __glXInitialize(dpy);
1144 if (!priv) {
1145 return 0;
1146 }
1147 return priv->codes.major_opcode;
1148 }
1149
1150 /**
1151 * Flush the drawing command transport buffer.
1152 *
1153 * \param ctx Context whose transport buffer is to be flushed.
1154 * \param pc Pointer to first unused buffer location.
1155 *
1156 * \todo
1157 * Modify this function to use \c ctx->pc instead of the explicit
1158 * \c pc parameter.
1159 */
1160 _X_HIDDEN GLubyte *
__glXFlushRenderBuffer(struct glx_context * ctx,GLubyte * pc)1161 __glXFlushRenderBuffer(struct glx_context * ctx, GLubyte * pc)
1162 {
1163 Display *const dpy = ctx->currentDpy;
1164 xcb_connection_t *c = XGetXCBConnection(dpy);
1165 const GLint size = pc - ctx->buf;
1166
1167 if ((dpy != NULL) && (size > 0)) {
1168 xcb_glx_render(c, ctx->currentContextTag, size,
1169 (const uint8_t *) ctx->buf);
1170 }
1171
1172 /* Reset pointer and return it */
1173 ctx->pc = ctx->buf;
1174 return ctx->pc;
1175 }
1176
1177
1178 /**
1179 * Send a portion of a GLXRenderLarge command to the server. The advantage of
1180 * this function over \c __glXSendLargeCommand is that callers can use the
1181 * data buffer in the GLX context and may be able to avoid allocating an
1182 * extra buffer. The disadvantage is the clients will have to do more
1183 * GLX protocol work (i.e., calculating \c totalRequests, etc.).
1184 *
1185 * \sa __glXSendLargeCommand
1186 *
1187 * \param gc GLX context
1188 * \param requestNumber Which part of the whole command is this? The first
1189 * request is 1.
1190 * \param totalRequests How many requests will there be?
1191 * \param data Command data.
1192 * \param dataLen Size, in bytes, of the command data.
1193 */
1194 _X_HIDDEN void
__glXSendLargeChunk(struct glx_context * gc,GLint requestNumber,GLint totalRequests,const GLvoid * data,GLint dataLen)1195 __glXSendLargeChunk(struct glx_context * gc, GLint requestNumber,
1196 GLint totalRequests, const GLvoid * data, GLint dataLen)
1197 {
1198 Display *dpy = gc->currentDpy;
1199 xcb_connection_t *c = XGetXCBConnection(dpy);
1200 xcb_glx_render_large(c, gc->currentContextTag, requestNumber,
1201 totalRequests, dataLen, data);
1202 }
1203
1204
1205 /**
1206 * Send a command that is too large for the GLXRender protocol request.
1207 *
1208 * Send a large command, one that is too large for some reason to
1209 * send using the GLXRender protocol request. One reason to send
1210 * a large command is to avoid copying the data.
1211 *
1212 * \param ctx GLX context
1213 * \param header Header data.
1214 * \param headerLen Size, in bytes, of the header data. It is assumed that
1215 * the header data will always be small enough to fit in
1216 * a single X protocol packet.
1217 * \param data Command data.
1218 * \param dataLen Size, in bytes, of the command data.
1219 */
1220 _X_HIDDEN void
__glXSendLargeCommand(struct glx_context * ctx,const GLvoid * header,GLint headerLen,const GLvoid * data,GLint dataLen)1221 __glXSendLargeCommand(struct glx_context * ctx,
1222 const GLvoid * header, GLint headerLen,
1223 const GLvoid * data, GLint dataLen)
1224 {
1225 GLint maxSize;
1226 GLint totalRequests, requestNumber;
1227
1228 /*
1229 ** Calculate the maximum amount of data can be stuffed into a single
1230 ** packet. sz_xGLXRenderReq is added because bufSize is the maximum
1231 ** packet size minus sz_xGLXRenderReq.
1232 */
1233 maxSize = (ctx->bufSize + sz_xGLXRenderReq) - sz_xGLXRenderLargeReq;
1234 totalRequests = 1 + (dataLen / maxSize);
1235 if (dataLen % maxSize)
1236 totalRequests++;
1237
1238 /*
1239 ** Send all of the command, except the large array, as one request.
1240 */
1241 assert(headerLen <= maxSize);
1242 __glXSendLargeChunk(ctx, 1, totalRequests, header, headerLen);
1243
1244 /*
1245 ** Send enough requests until the whole array is sent.
1246 */
1247 for (requestNumber = 2; requestNumber <= (totalRequests - 1);
1248 requestNumber++) {
1249 __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, maxSize);
1250 data = (const GLvoid *) (((const GLubyte *) data) + maxSize);
1251 dataLen -= maxSize;
1252 assert(dataLen > 0);
1253 }
1254
1255 assert(dataLen <= maxSize);
1256 __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, dataLen);
1257 }
1258