libGL: Consolidate DRI initialization in dri_glx.c
[mesa.git] / src / glx / x11 / glxext.c
1 /* $XFree86: xc/lib/GL/glx/glxext.c,v 1.22 2003/12/08 17:35:28 dawes Exp $ */
2
3 /*
4 ** License Applicability. Except to the extent portions of this file are
5 ** made subject to an alternative license as permitted in the SGI Free
6 ** Software License B, Version 1.1 (the "License"), the contents of this
7 ** file are subject only to the provisions of the License. You may not use
8 ** this file except in compliance with the License. You may obtain a copy
9 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
10 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
11 **
12 ** http://oss.sgi.com/projects/FreeB
13 **
14 ** Note that, as provided in the License, the Software is distributed on an
15 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
16 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
17 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
18 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
19 **
20 ** Original Code. The Original Code is: OpenGL Sample Implementation,
21 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
22 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
23 ** Copyright in any portions created by third parties is as indicated
24 ** elsewhere herein. All Rights Reserved.
25 **
26 ** Additional Notice Provisions: The application programming interfaces
27 ** established by SGI in conjunction with the Original Code are The
28 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
29 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
30 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
31 ** Window System(R) (Version 1.3), released October 19, 1998. This software
32 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
33 ** published by SGI, but has not been independently verified as being
34 ** compliant with the OpenGL(R) version 1.2.1 Specification.
35 **
36 */
37
38 /**
39 * \file glxext.c
40 * GLX protocol interface boot-strap code.
41 *
42 * Direct rendering support added by Precision Insight, Inc.
43 *
44 * \author Kevin E. Martin <kevin@precisioninsight.com>
45 */
46
47 #include "glxclient.h"
48 #include <stdio.h>
49 #include <X11/extensions/Xext.h>
50 #include <X11/extensions/extutil.h>
51 #include <X11/extensions/Xfixes.h>
52 #include <X11/extensions/Xdamage.h>
53 #include <assert.h>
54 #include "indirect_init.h"
55 #include "glapi.h"
56 #include "glxextensions.h"
57 #include "glcontextmodes.h"
58 #include "glheader.h"
59
60 #ifdef GLX_DIRECT_RENDERING
61 #include <inttypes.h>
62 #include <sys/mman.h>
63 #include "xf86dri.h"
64 #include "xf86drm.h"
65 #include "sarea.h"
66 #include "dri_glx.h"
67 #endif
68
69 #ifdef USE_XCB
70 #include <X11/Xlib-xcb.h>
71 #include <xcb/xcb.h>
72 #include <xcb/glx.h>
73 #endif
74
75 #include <assert.h>
76
77 #ifdef DEBUG
78 void __glXDumpDrawBuffer(__GLXcontext *ctx);
79 #endif
80
81 #ifdef USE_SPARC_ASM
82 /*
83 * This is where our dispatch table's bounds are.
84 * And the static mesa_init is taken directly from
85 * Mesa's 'sparc.c' initializer.
86 *
87 * We need something like this here, because this version
88 * of openGL/glx never initializes a Mesa context, and so
89 * the address of the dispatch table pointer never gets stuffed
90 * into the dispatch jump table otherwise.
91 *
92 * It matters only on SPARC, and only if you are using assembler
93 * code instead of C-code indirect dispatch.
94 *
95 * -- FEM, 04.xii.03
96 */
97 extern unsigned int _mesa_sparc_glapi_begin;
98 extern unsigned int _mesa_sparc_glapi_end;
99 extern void __glapi_sparc_icache_flush(unsigned int *);
100 static void _glx_mesa_init_sparc_glapi_relocs(void);
101 static int _mesa_sparc_needs_init = 1;
102 #define INIT_MESA_SPARC { \
103 if(_mesa_sparc_needs_init) { \
104 _glx_mesa_init_sparc_glapi_relocs(); \
105 _mesa_sparc_needs_init = 0; \
106 } \
107 }
108 #else
109 #define INIT_MESA_SPARC
110 #endif
111
112 static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
113 GLXDrawable read, GLXContext gc);
114
115 /*
116 ** We setup some dummy structures here so that the API can be used
117 ** even if no context is current.
118 */
119
120 static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE];
121
122 /*
123 ** Dummy context used by small commands when there is no current context.
124 ** All the
125 ** gl and glx entry points are designed to operate as nop's when using
126 ** the dummy context structure.
127 */
128 static __GLXcontext dummyContext = {
129 &dummyBuffer[0],
130 &dummyBuffer[0],
131 &dummyBuffer[0],
132 &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE],
133 sizeof(dummyBuffer),
134 };
135
136
137 /*
138 ** All indirect rendering contexts will share the same indirect dispatch table.
139 */
140 static __GLapi *IndirectAPI = NULL;
141
142
143 /*
144 * Current context management and locking
145 */
146
147 #if defined( USE_XTHREADS )
148
149 /* thread safe */
150 static GLboolean TSDinitialized = GL_FALSE;
151 static xthread_key_t ContextTSD;
152
153 __GLXcontext *__glXGetCurrentContext(void)
154 {
155 if (!TSDinitialized) {
156 xthread_key_create(&ContextTSD, NULL);
157 TSDinitialized = GL_TRUE;
158 return &dummyContext;
159 }
160 else {
161 void *p;
162 xthread_get_specific(ContextTSD, &p);
163 if (!p)
164 return &dummyContext;
165 else
166 return (__GLXcontext *) p;
167 }
168 }
169
170 void __glXSetCurrentContext(__GLXcontext *c)
171 {
172 if (!TSDinitialized) {
173 xthread_key_create(&ContextTSD, NULL);
174 TSDinitialized = GL_TRUE;
175 }
176 xthread_set_specific(ContextTSD, c);
177 }
178
179
180 /* Used by the __glXLock() and __glXUnlock() macros */
181 xmutex_rec __glXmutex;
182
183 #elif defined( PTHREADS )
184
185 pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
186
187 # if defined( GLX_USE_TLS )
188
189 /**
190 * Per-thread GLX context pointer.
191 *
192 * \c __glXSetCurrentContext is written is such a way that this pointer can
193 * \b never be \c NULL. This is important! Because of this
194 * \c __glXGetCurrentContext can be implemented as trivial macro.
195 */
196 __thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))
197 = &dummyContext;
198
199 void __glXSetCurrentContext( __GLXcontext * c )
200 {
201 __glX_tls_Context = (c != NULL) ? c : &dummyContext;
202 }
203
204 # else
205
206 static pthread_once_t once_control = PTHREAD_ONCE_INIT;
207
208 /**
209 * Per-thread data key.
210 *
211 * Once \c init_thread_data has been called, the per-thread data key will
212 * take a value of \c NULL. As each new thread is created the default
213 * value, in that thread, will be \c NULL.
214 */
215 static pthread_key_t ContextTSD;
216
217 /**
218 * Initialize the per-thread data key.
219 *
220 * This function is called \b exactly once per-process (not per-thread!) to
221 * initialize the per-thread data key. This is ideally done using the
222 * \c pthread_once mechanism.
223 */
224 static void init_thread_data( void )
225 {
226 if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) {
227 perror( "pthread_key_create" );
228 exit( -1 );
229 }
230 }
231
232 void __glXSetCurrentContext( __GLXcontext * c )
233 {
234 pthread_once( & once_control, init_thread_data );
235 pthread_setspecific( ContextTSD, c );
236 }
237
238 __GLXcontext * __glXGetCurrentContext( void )
239 {
240 void * v;
241
242 pthread_once( & once_control, init_thread_data );
243
244 v = pthread_getspecific( ContextTSD );
245 return (v == NULL) ? & dummyContext : (__GLXcontext *) v;
246 }
247
248 # endif /* defined( GLX_USE_TLS ) */
249
250 #elif defined( THREADS )
251
252 #error Unknown threading method specified.
253
254 #else
255
256 /* not thread safe */
257 __GLXcontext *__glXcurrentContext = &dummyContext;
258
259 #endif
260
261
262 /*
263 ** You can set this cell to 1 to force the gl drawing stuff to be
264 ** one command per packet
265 */
266 int __glXDebug = 0;
267
268 /*
269 ** forward prototype declarations
270 */
271 int __glXCloseDisplay(Display *dpy, XExtCodes *codes);
272
273
274 /************************************************************************/
275
276 /* Extension required boiler plate */
277
278 static char *__glXExtensionName = GLX_EXTENSION_NAME;
279 XExtensionInfo *__glXExtensionInfo = NULL;
280
281 static /* const */ char *error_list[] = {
282 "GLXBadContext",
283 "GLXBadContextState",
284 "GLXBadDrawable",
285 "GLXBadPixmap",
286 "GLXBadContextTag",
287 "GLXBadCurrentWindow",
288 "GLXBadRenderRequest",
289 "GLXBadLargeRequest",
290 "GLXUnsupportedPrivateRequest",
291 "GLXBadFBConfig",
292 "GLXBadPbuffer",
293 "GLXBadCurrentDrawable",
294 "GLXBadWindow",
295 };
296
297 int __glXCloseDisplay(Display *dpy, XExtCodes *codes)
298 {
299 GLXContext gc;
300
301 gc = __glXGetCurrentContext();
302 if (dpy == gc->currentDpy) {
303 __glXSetCurrentContext(&dummyContext);
304 #ifdef GLX_DIRECT_RENDERING
305 _glapi_set_dispatch(NULL); /* no-op functions */
306 #endif
307 __glXFreeContext(gc);
308 }
309
310 return XextRemoveDisplay(__glXExtensionInfo, dpy);
311 }
312
313
314 static XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
315 __GLX_NUMBER_ERRORS, error_list)
316
317 static /* const */ XExtensionHooks __glXExtensionHooks = {
318 NULL, /* create_gc */
319 NULL, /* copy_gc */
320 NULL, /* flush_gc */
321 NULL, /* free_gc */
322 NULL, /* create_font */
323 NULL, /* free_font */
324 __glXCloseDisplay, /* close_display */
325 NULL, /* wire_to_event */
326 NULL, /* event_to_wire */
327 NULL, /* error */
328 __glXErrorString, /* error_string */
329 };
330
331 static
332 XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
333 __glXExtensionName, &__glXExtensionHooks,
334 __GLX_NUMBER_EVENTS, NULL)
335
336 /************************************************************************/
337
338 /*
339 ** Free the per screen configs data as well as the array of
340 ** __glXScreenConfigs.
341 */
342 static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
343 {
344 __GLXscreenConfigs *psc;
345 GLint i, screens;
346
347 /* Free screen configuration information */
348 psc = priv->screenConfigs;
349 screens = ScreenCount(priv->dpy);
350 for (i = 0; i < screens; i++, psc++) {
351 if (psc->configs) {
352 _gl_context_modes_destroy( psc->configs );
353 if(psc->effectiveGLXexts)
354 Xfree(psc->effectiveGLXexts);
355
356 psc->configs = NULL; /* NOTE: just for paranoia */
357 }
358 Xfree((char*) psc->serverGLXexts);
359
360 #ifdef GLX_DIRECT_RENDERING
361 /* Free the direct rendering per screen data */
362 if (psc->driScreen.private)
363 (*psc->driScreen.destroyScreen)(&psc->driScreen);
364 psc->driScreen.private = NULL;
365 if (psc->drawHash)
366 __glxHashDestroy(psc->drawHash);
367 #endif
368 }
369 XFree((char*) priv->screenConfigs);
370 }
371
372 /*
373 ** Release the private memory referred to in a display private
374 ** structure. The caller will free the extension structure.
375 */
376 static int __glXFreeDisplayPrivate(XExtData *extension)
377 {
378 __GLXdisplayPrivate *priv;
379
380 priv = (__GLXdisplayPrivate*) extension->private_data;
381 FreeScreenConfigs(priv);
382 if(priv->serverGLXvendor) {
383 Xfree((char*)priv->serverGLXvendor);
384 priv->serverGLXvendor = 0x0; /* to protect against double free's */
385 }
386 if(priv->serverGLXversion) {
387 Xfree((char*)priv->serverGLXversion);
388 priv->serverGLXversion = 0x0; /* to protect against double free's */
389 }
390
391 #ifdef GLX_DIRECT_RENDERING
392 /* Free the direct rendering per display data */
393 if (priv->driDisplay.private)
394 (*priv->driDisplay.destroyDisplay)(priv->dpy,
395 priv->driDisplay.private);
396 priv->driDisplay.private = NULL;
397 if (priv->driDisplay.createNewScreen) {
398 Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */
399 priv->driDisplay.createNewScreen = NULL;
400 }
401 #endif
402
403 Xfree((char*) priv);
404 return 0;
405 }
406
407 /************************************************************************/
408
409 /*
410 ** Query the version of the GLX extension. This procedure works even if
411 ** the client extension is not completely set up.
412 */
413 static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor)
414 {
415 xGLXQueryVersionReq *req;
416 xGLXQueryVersionReply reply;
417
418 /* Send the glXQueryVersion request */
419 LockDisplay(dpy);
420 GetReq(GLXQueryVersion,req);
421 req->reqType = opcode;
422 req->glxCode = X_GLXQueryVersion;
423 req->majorVersion = GLX_MAJOR_VERSION;
424 req->minorVersion = GLX_MINOR_VERSION;
425 _XReply(dpy, (xReply*) &reply, 0, False);
426 UnlockDisplay(dpy);
427 SyncHandle();
428
429 if (reply.majorVersion != GLX_MAJOR_VERSION) {
430 /*
431 ** The server does not support the same major release as this
432 ** client.
433 */
434 return GL_FALSE;
435 }
436 *major = reply.majorVersion;
437 *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
438 return GL_TRUE;
439 }
440
441
442 void
443 __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
444 const INT32 *bp, Bool tagged_only,
445 Bool fbconfig_style_tags )
446 {
447 int i;
448
449 if (!tagged_only) {
450 /* Copy in the first set of properties */
451 config->visualID = *bp++;
452
453 config->visualType = _gl_convert_from_x_visual_type( *bp++ );
454
455 config->rgbMode = *bp++;
456
457 config->redBits = *bp++;
458 config->greenBits = *bp++;
459 config->blueBits = *bp++;
460 config->alphaBits = *bp++;
461 config->accumRedBits = *bp++;
462 config->accumGreenBits = *bp++;
463 config->accumBlueBits = *bp++;
464 config->accumAlphaBits = *bp++;
465
466 config->doubleBufferMode = *bp++;
467 config->stereoMode = *bp++;
468
469 config->rgbBits = *bp++;
470 config->depthBits = *bp++;
471 config->stencilBits = *bp++;
472 config->numAuxBuffers = *bp++;
473 config->level = *bp++;
474
475 count -= __GLX_MIN_CONFIG_PROPS;
476 }
477
478 /*
479 ** Additional properties may be in a list at the end
480 ** of the reply. They are in pairs of property type
481 ** and property value.
482 */
483
484 #define FETCH_OR_SET(tag) \
485 config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
486
487 for (i = 0; i < count; i += 2 ) {
488 switch(*bp++) {
489 case GLX_RGBA:
490 FETCH_OR_SET( rgbMode );
491 break;
492 case GLX_BUFFER_SIZE:
493 config->rgbBits = *bp++;
494 break;
495 case GLX_LEVEL:
496 config->level = *bp++;
497 break;
498 case GLX_DOUBLEBUFFER:
499 FETCH_OR_SET( doubleBufferMode );
500 break;
501 case GLX_STEREO:
502 FETCH_OR_SET( stereoMode );
503 break;
504 case GLX_AUX_BUFFERS:
505 config->numAuxBuffers = *bp++;
506 break;
507 case GLX_RED_SIZE:
508 config->redBits = *bp++;
509 break;
510 case GLX_GREEN_SIZE:
511 config->greenBits = *bp++;
512 break;
513 case GLX_BLUE_SIZE:
514 config->blueBits = *bp++;
515 break;
516 case GLX_ALPHA_SIZE:
517 config->alphaBits = *bp++;
518 break;
519 case GLX_DEPTH_SIZE:
520 config->depthBits = *bp++;
521 break;
522 case GLX_STENCIL_SIZE:
523 config->stencilBits = *bp++;
524 break;
525 case GLX_ACCUM_RED_SIZE:
526 config->accumRedBits = *bp++;
527 break;
528 case GLX_ACCUM_GREEN_SIZE:
529 config->accumGreenBits = *bp++;
530 break;
531 case GLX_ACCUM_BLUE_SIZE:
532 config->accumBlueBits = *bp++;
533 break;
534 case GLX_ACCUM_ALPHA_SIZE:
535 config->accumAlphaBits = *bp++;
536 break;
537 case GLX_VISUAL_CAVEAT_EXT:
538 config->visualRating = *bp++;
539 break;
540 case GLX_X_VISUAL_TYPE:
541 config->visualType = *bp++;
542 break;
543 case GLX_TRANSPARENT_TYPE:
544 config->transparentPixel = *bp++;
545 break;
546 case GLX_TRANSPARENT_INDEX_VALUE:
547 config->transparentIndex = *bp++;
548 break;
549 case GLX_TRANSPARENT_RED_VALUE:
550 config->transparentRed = *bp++;
551 break;
552 case GLX_TRANSPARENT_GREEN_VALUE:
553 config->transparentGreen = *bp++;
554 break;
555 case GLX_TRANSPARENT_BLUE_VALUE:
556 config->transparentBlue = *bp++;
557 break;
558 case GLX_TRANSPARENT_ALPHA_VALUE:
559 config->transparentAlpha = *bp++;
560 break;
561 case GLX_VISUAL_ID:
562 config->visualID = *bp++;
563 break;
564 case GLX_DRAWABLE_TYPE:
565 config->drawableType = *bp++;
566 break;
567 case GLX_RENDER_TYPE:
568 config->renderType = *bp++;
569 break;
570 case GLX_X_RENDERABLE:
571 config->xRenderable = *bp++;
572 break;
573 case GLX_FBCONFIG_ID:
574 config->fbconfigID = *bp++;
575 break;
576 case GLX_MAX_PBUFFER_WIDTH:
577 config->maxPbufferWidth = *bp++;
578 break;
579 case GLX_MAX_PBUFFER_HEIGHT:
580 config->maxPbufferHeight = *bp++;
581 break;
582 case GLX_MAX_PBUFFER_PIXELS:
583 config->maxPbufferPixels = *bp++;
584 break;
585 case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
586 config->optimalPbufferWidth = *bp++;
587 break;
588 case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
589 config->optimalPbufferHeight = *bp++;
590 break;
591 case GLX_VISUAL_SELECT_GROUP_SGIX:
592 config->visualSelectGroup = *bp++;
593 break;
594 case GLX_SWAP_METHOD_OML:
595 config->swapMethod = *bp++;
596 break;
597 case GLX_SAMPLE_BUFFERS_SGIS:
598 config->sampleBuffers = *bp++;
599 break;
600 case GLX_SAMPLES_SGIS:
601 config->samples = *bp++;
602 break;
603 case GLX_BIND_TO_TEXTURE_RGB_EXT:
604 config->bindToTextureRgb = *bp++;
605 break;
606 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
607 config->bindToTextureRgba = *bp++;
608 break;
609 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
610 config->bindToMipmapTexture = *bp++;
611 break;
612 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
613 config->bindToTextureTargets = *bp++;
614 break;
615 case GLX_Y_INVERTED_EXT:
616 config->yInverted = *bp++;
617 break;
618 case None:
619 i = count;
620 break;
621 default:
622 break;
623 }
624 }
625
626 config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
627
628 config->haveAccumBuffer = ((config->accumRedBits +
629 config->accumGreenBits +
630 config->accumBlueBits +
631 config->accumAlphaBits) > 0);
632 config->haveDepthBuffer = (config->depthBits > 0);
633 config->haveStencilBuffer = (config->stencilBits > 0);
634 }
635
636 static __GLcontextModes *
637 createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
638 int screen, GLboolean tagged_only)
639 {
640 INT32 buf[__GLX_TOTAL_CONFIG], *props;
641 unsigned prop_size;
642 __GLcontextModes *modes, *m;
643 int i;
644
645 if (nprops == 0)
646 return NULL;
647
648 /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
649
650 /* Check number of properties */
651 if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
652 return NULL;
653
654 /* Allocate memory for our config structure */
655 modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
656 if (!modes)
657 return NULL;
658
659 prop_size = nprops * __GLX_SIZE_INT32;
660 if (prop_size <= sizeof(buf))
661 props = buf;
662 else
663 props = Xmalloc(prop_size);
664
665 /* Read each config structure and convert it into our format */
666 m = modes;
667 for (i = 0; i < nvisuals; i++) {
668 _XRead(dpy, (char *)props, prop_size);
669 /* Older X servers don't send this so we default it here. */
670 m->drawableType = GLX_WINDOW_BIT;
671 __glXInitializeVisualConfigFromTags(m, nprops, props,
672 tagged_only, GL_TRUE);
673 m->screen = screen;
674 m = m->next;
675 }
676
677 if (props != buf)
678 Xfree(props);
679
680 return modes;
681 }
682
683 static GLboolean
684 getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
685 {
686 xGLXGetVisualConfigsReq *req;
687 __GLXscreenConfigs *psc;
688 xGLXGetVisualConfigsReply reply;
689
690 LockDisplay(dpy);
691
692 psc = priv->screenConfigs + screen;
693 psc->visuals = NULL;
694 GetReq(GLXGetVisualConfigs, req);
695 req->reqType = priv->majorOpcode;
696 req->glxCode = X_GLXGetVisualConfigs;
697 req->screen = screen;
698
699 if (!_XReply(dpy, (xReply*) &reply, 0, False))
700 goto out;
701
702 psc->visuals = createConfigsFromProperties(dpy,
703 reply.numVisuals,
704 reply.numProps,
705 screen, GL_FALSE);
706
707 out:
708 UnlockDisplay(dpy);
709 return psc->visuals != NULL;
710 }
711
712 static GLboolean
713 getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
714 {
715 xGLXGetFBConfigsReq *fb_req;
716 xGLXGetFBConfigsSGIXReq *sgi_req;
717 xGLXVendorPrivateWithReplyReq *vpreq;
718 xGLXGetFBConfigsReply reply;
719 __GLXscreenConfigs *psc;
720
721 psc = priv->screenConfigs + screen;
722 psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
723 X_GLXQueryServerString,
724 screen, GLX_EXTENSIONS);
725
726 LockDisplay(dpy);
727
728 psc->configs = NULL;
729 if (atof(priv->serverGLXversion) >= 1.3) {
730 GetReq(GLXGetFBConfigs, fb_req);
731 fb_req->reqType = priv->majorOpcode;
732 fb_req->glxCode = X_GLXGetFBConfigs;
733 fb_req->screen = screen;
734 } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
735 GetReqExtra(GLXVendorPrivateWithReply,
736 sz_xGLXGetFBConfigsSGIXReq +
737 sz_xGLXVendorPrivateWithReplyReq, vpreq);
738 sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
739 sgi_req->reqType = priv->majorOpcode;
740 sgi_req->glxCode = X_GLXVendorPrivateWithReply;
741 sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
742 sgi_req->screen = screen;
743 } else
744 goto out;
745
746 if (!_XReply(dpy, (xReply*) &reply, 0, False))
747 goto out;
748
749 psc->configs = createConfigsFromProperties(dpy,
750 reply.numFBConfigs,
751 reply.numAttribs * 2,
752 screen, GL_TRUE);
753
754 out:
755 UnlockDisplay(dpy);
756 return psc->configs != NULL;
757 }
758
759 /*
760 ** Allocate the memory for the per screen configs for each screen.
761 ** If that works then fetch the per screen configs data.
762 */
763 static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
764 {
765 __GLXscreenConfigs *psc;
766 GLint i, screens;
767
768 /*
769 ** First allocate memory for the array of per screen configs.
770 */
771 screens = ScreenCount(dpy);
772 psc = (__GLXscreenConfigs*) Xmalloc(screens * sizeof(__GLXscreenConfigs));
773 if (!psc) {
774 return GL_FALSE;
775 }
776 memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
777 priv->screenConfigs = psc;
778
779 priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,
780 X_GLXQueryServerString,
781 0, GLX_VERSION);
782 if ( priv->serverGLXversion == NULL ) {
783 FreeScreenConfigs(priv);
784 return GL_FALSE;
785 }
786
787 for (i = 0; i < screens; i++, psc++) {
788 getVisualConfigs(dpy, priv, i);
789 getFBConfigs(dpy, priv, i);
790
791 psc->scr = i;
792 psc->dpy = dpy;
793 #ifdef GLX_DIRECT_RENDERING
794 driCreateScreen(psc, i, priv);
795 #endif
796 }
797 SyncHandle();
798 return GL_TRUE;
799 }
800
801 /*
802 ** Initialize the client side extension code.
803 */
804 __GLXdisplayPrivate *__glXInitialize(Display* dpy)
805 {
806 XExtDisplayInfo *info = __glXFindDisplay(dpy);
807 XExtData **privList, *private, *found;
808 __GLXdisplayPrivate *dpyPriv;
809 XEDataObject dataObj;
810 int major, minor;
811
812 #if defined(USE_XTHREADS)
813 {
814 static int firstCall = 1;
815 if (firstCall) {
816 /* initialize the GLX mutexes */
817 xmutex_init(&__glXmutex);
818 firstCall = 0;
819 }
820 }
821 #endif
822
823 INIT_MESA_SPARC
824 /* The one and only long long lock */
825 __glXLock();
826
827 if (!XextHasExtension(info)) {
828 /* No GLX extension supported by this server. Oh well. */
829 __glXUnlock();
830 XMissingExtension(dpy, __glXExtensionName);
831 return 0;
832 }
833
834 /* See if a display private already exists. If so, return it */
835 dataObj.display = dpy;
836 privList = XEHeadOfExtensionList(dataObj);
837 found = XFindOnExtensionList(privList, info->codes->extension);
838 if (found) {
839 __glXUnlock();
840 return (__GLXdisplayPrivate *) found->private_data;
841 }
842
843 /* See if the versions are compatible */
844 if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) {
845 /* The client and server do not agree on versions. Punt. */
846 __glXUnlock();
847 return 0;
848 }
849
850 /*
851 ** Allocate memory for all the pieces needed for this buffer.
852 */
853 private = (XExtData *) Xmalloc(sizeof(XExtData));
854 if (!private) {
855 __glXUnlock();
856 return 0;
857 }
858 dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
859 if (!dpyPriv) {
860 __glXUnlock();
861 Xfree((char*) private);
862 return 0;
863 }
864
865 /*
866 ** Init the display private and then read in the screen config
867 ** structures from the server.
868 */
869 dpyPriv->majorOpcode = info->codes->major_opcode;
870 dpyPriv->majorVersion = major;
871 dpyPriv->minorVersion = minor;
872 dpyPriv->dpy = dpy;
873
874 dpyPriv->serverGLXvendor = 0x0;
875 dpyPriv->serverGLXversion = 0x0;
876
877 #ifdef GLX_DIRECT_RENDERING
878 /*
879 ** Initialize the direct rendering per display data and functions.
880 ** Note: This _must_ be done before calling any other DRI routines
881 ** (e.g., those called in AllocAndFetchScreenConfigs).
882 */
883 if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) {
884 dpyPriv->driDisplay.private =
885 driCreateDisplay(dpy, &dpyPriv->driDisplay);
886 }
887 #endif
888
889 if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
890 __glXUnlock();
891 Xfree((char*) dpyPriv);
892 Xfree((char*) private);
893 return 0;
894 }
895
896 /*
897 ** Fill in the private structure. This is the actual structure that
898 ** hangs off of the Display structure. Our private structure is
899 ** referred to by this structure. Got that?
900 */
901 private->number = info->codes->extension;
902 private->next = 0;
903 private->free_private = __glXFreeDisplayPrivate;
904 private->private_data = (char *) dpyPriv;
905 XAddToExtensionList(privList, private);
906
907 if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) {
908 __glXClientInfo(dpy, dpyPriv->majorOpcode);
909 }
910 __glXUnlock();
911
912 return dpyPriv;
913 }
914
915 /*
916 ** Setup for sending a GLX command on dpy. Make sure the extension is
917 ** initialized. Try to avoid calling __glXInitialize as its kinda slow.
918 */
919 CARD8 __glXSetupForCommand(Display *dpy)
920 {
921 GLXContext gc;
922 __GLXdisplayPrivate *priv;
923
924 /* If this thread has a current context, flush its rendering commands */
925 gc = __glXGetCurrentContext();
926 if (gc->currentDpy) {
927 /* Flush rendering buffer of the current context, if any */
928 (void) __glXFlushRenderBuffer(gc, gc->pc);
929
930 if (gc->currentDpy == dpy) {
931 /* Use opcode from gc because its right */
932 INIT_MESA_SPARC
933 return gc->majorOpcode;
934 } else {
935 /*
936 ** Have to get info about argument dpy because it might be to
937 ** a different server
938 */
939 }
940 }
941
942 /* Forced to lookup extension via the slow initialize route */
943 priv = __glXInitialize(dpy);
944 if (!priv) {
945 return 0;
946 }
947 return priv->majorOpcode;
948 }
949
950 /**
951 * Flush the drawing command transport buffer.
952 *
953 * \param ctx Context whose transport buffer is to be flushed.
954 * \param pc Pointer to first unused buffer location.
955 *
956 * \todo
957 * Modify this function to use \c ctx->pc instead of the explicit
958 * \c pc parameter.
959 */
960 GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
961 {
962 Display * const dpy = ctx->currentDpy;
963 #ifdef USE_XCB
964 xcb_connection_t *c = XGetXCBConnection(dpy);
965 #else
966 xGLXRenderReq *req;
967 #endif /* USE_XCB */
968 const GLint size = pc - ctx->buf;
969
970 if ( (dpy != NULL) && (size > 0) ) {
971 #ifdef USE_XCB
972 xcb_glx_render(c, ctx->currentContextTag, size,
973 (const uint8_t *)ctx->buf);
974 #else
975 /* Send the entire buffer as an X request */
976 LockDisplay(dpy);
977 GetReq(GLXRender,req);
978 req->reqType = ctx->majorOpcode;
979 req->glxCode = X_GLXRender;
980 req->contextTag = ctx->currentContextTag;
981 req->length += (size + 3) >> 2;
982 _XSend(dpy, (char *)ctx->buf, size);
983 UnlockDisplay(dpy);
984 SyncHandle();
985 #endif
986 }
987
988 /* Reset pointer and return it */
989 ctx->pc = ctx->buf;
990 return ctx->pc;
991 }
992
993
994 /**
995 * Send a portion of a GLXRenderLarge command to the server. The advantage of
996 * this function over \c __glXSendLargeCommand is that callers can use the
997 * data buffer in the GLX context and may be able to avoid allocating an
998 * extra buffer. The disadvantage is the clients will have to do more
999 * GLX protocol work (i.e., calculating \c totalRequests, etc.).
1000 *
1001 * \sa __glXSendLargeCommand
1002 *
1003 * \param gc GLX context
1004 * \param requestNumber Which part of the whole command is this? The first
1005 * request is 1.
1006 * \param totalRequests How many requests will there be?
1007 * \param data Command data.
1008 * \param dataLen Size, in bytes, of the command data.
1009 */
1010 void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,
1011 GLint totalRequests,
1012 const GLvoid * data, GLint dataLen)
1013 {
1014 Display *dpy = gc->currentDpy;
1015 #ifdef USE_XCB
1016 xcb_connection_t *c = XGetXCBConnection(dpy);
1017 xcb_glx_render_large(c, gc->currentContextTag, requestNumber, totalRequests, dataLen, data);
1018 #else
1019 xGLXRenderLargeReq *req;
1020
1021 if ( requestNumber == 1 ) {
1022 LockDisplay(dpy);
1023 }
1024
1025 GetReq(GLXRenderLarge,req);
1026 req->reqType = gc->majorOpcode;
1027 req->glxCode = X_GLXRenderLarge;
1028 req->contextTag = gc->currentContextTag;
1029 req->length += (dataLen + 3) >> 2;
1030 req->requestNumber = requestNumber;
1031 req->requestTotal = totalRequests;
1032 req->dataBytes = dataLen;
1033 Data(dpy, data, dataLen);
1034
1035 if ( requestNumber == totalRequests ) {
1036 UnlockDisplay(dpy);
1037 SyncHandle();
1038 }
1039 #endif /* USE_XCB */
1040 }
1041
1042
1043 /**
1044 * Send a command that is too large for the GLXRender protocol request.
1045 *
1046 * Send a large command, one that is too large for some reason to
1047 * send using the GLXRender protocol request. One reason to send
1048 * a large command is to avoid copying the data.
1049 *
1050 * \param ctx GLX context
1051 * \param header Header data.
1052 * \param headerLen Size, in bytes, of the header data. It is assumed that
1053 * the header data will always be small enough to fit in
1054 * a single X protocol packet.
1055 * \param data Command data.
1056 * \param dataLen Size, in bytes, of the command data.
1057 */
1058 void __glXSendLargeCommand(__GLXcontext *ctx,
1059 const GLvoid *header, GLint headerLen,
1060 const GLvoid *data, GLint dataLen)
1061 {
1062 GLint maxSize;
1063 GLint totalRequests, requestNumber;
1064
1065 /*
1066 ** Calculate the maximum amount of data can be stuffed into a single
1067 ** packet. sz_xGLXRenderReq is added because bufSize is the maximum
1068 ** packet size minus sz_xGLXRenderReq.
1069 */
1070 maxSize = (ctx->bufSize + sz_xGLXRenderReq) - sz_xGLXRenderLargeReq;
1071 totalRequests = 1 + (dataLen / maxSize);
1072 if (dataLen % maxSize) totalRequests++;
1073
1074 /*
1075 ** Send all of the command, except the large array, as one request.
1076 */
1077 assert( headerLen <= maxSize );
1078 __glXSendLargeChunk(ctx, 1, totalRequests, header, headerLen);
1079
1080 /*
1081 ** Send enough requests until the whole array is sent.
1082 */
1083 for ( requestNumber = 2 ; requestNumber <= (totalRequests - 1) ; requestNumber++ ) {
1084 __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, maxSize);
1085 data = (const GLvoid *) (((const GLubyte *) data) + maxSize);
1086 dataLen -= maxSize;
1087 assert( dataLen > 0 );
1088 }
1089
1090 assert( dataLen <= maxSize );
1091 __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, dataLen);
1092 }
1093
1094 /************************************************************************/
1095
1096 PUBLIC GLXContext glXGetCurrentContext(void)
1097 {
1098 GLXContext cx = __glXGetCurrentContext();
1099
1100 if (cx == &dummyContext) {
1101 return NULL;
1102 } else {
1103 return cx;
1104 }
1105 }
1106
1107 PUBLIC GLXDrawable glXGetCurrentDrawable(void)
1108 {
1109 GLXContext gc = __glXGetCurrentContext();
1110 return gc->currentDrawable;
1111 }
1112
1113
1114 /************************************************************************/
1115
1116 static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode,
1117 GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read,
1118 xGLXMakeCurrentReply * reply );
1119
1120 /**
1121 * Sends a GLX protocol message to the specified display to make the context
1122 * and the drawables current.
1123 *
1124 * \param dpy Display to send the message to.
1125 * \param opcode Major opcode value for the display.
1126 * \param gc_id Context tag for the context to be made current.
1127 * \param draw Drawable ID for the "draw" drawable.
1128 * \param read Drawable ID for the "read" drawable.
1129 * \param reply Space to store the X-server's reply.
1130 *
1131 * \warning
1132 * This function assumes that \c dpy is locked with \c LockDisplay on entry.
1133 */
1134 static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
1135 GLXContextID gc_id, GLXContextTag gc_tag,
1136 GLXDrawable draw, GLXDrawable read,
1137 xGLXMakeCurrentReply *reply)
1138 {
1139 Bool ret;
1140
1141
1142 LockDisplay(dpy);
1143
1144 if (draw == read) {
1145 xGLXMakeCurrentReq *req;
1146
1147 GetReq(GLXMakeCurrent,req);
1148 req->reqType = opcode;
1149 req->glxCode = X_GLXMakeCurrent;
1150 req->drawable = draw;
1151 req->context = gc_id;
1152 req->oldContextTag = gc_tag;
1153 }
1154 else {
1155 __GLXdisplayPrivate *priv = __glXInitialize(dpy);
1156
1157 /* If the server can support the GLX 1.3 version, we should
1158 * perfer that. Not only that, some servers support GLX 1.3 but
1159 * not the SGI extension.
1160 */
1161
1162 if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
1163 xGLXMakeContextCurrentReq *req;
1164
1165 GetReq(GLXMakeContextCurrent,req);
1166 req->reqType = opcode;
1167 req->glxCode = X_GLXMakeContextCurrent;
1168 req->drawable = draw;
1169 req->readdrawable = read;
1170 req->context = gc_id;
1171 req->oldContextTag = gc_tag;
1172 }
1173 else {
1174 xGLXVendorPrivateWithReplyReq *vpreq;
1175 xGLXMakeCurrentReadSGIReq *req;
1176
1177 GetReqExtra(GLXVendorPrivateWithReply,
1178 sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
1179 req = (xGLXMakeCurrentReadSGIReq *)vpreq;
1180 req->reqType = opcode;
1181 req->glxCode = X_GLXVendorPrivateWithReply;
1182 req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
1183 req->drawable = draw;
1184 req->readable = read;
1185 req->context = gc_id;
1186 req->oldContextTag = gc_tag;
1187 }
1188 }
1189
1190 ret = _XReply(dpy, (xReply*) reply, 0, False);
1191
1192 UnlockDisplay(dpy);
1193 SyncHandle();
1194
1195 return ret;
1196 }
1197
1198
1199 #ifdef GLX_DIRECT_RENDERING
1200 static __DRIdrawable *
1201 FetchDRIDrawable( Display *dpy, GLXDrawable drawable, GLXContext gc)
1202 {
1203 __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
1204 __GLXdrawable *pdraw;
1205 __GLXscreenConfigs *sc;
1206 drm_drawable_t hwDrawable;
1207 void *empty_attribute_list = NULL;
1208
1209 if (priv == NULL || priv->driDisplay.private == NULL)
1210 return NULL;
1211
1212 sc = &priv->screenConfigs[gc->screen];
1213 if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0)
1214 return &pdraw->driDrawable;
1215
1216 /* Allocate a new drawable */
1217 pdraw = Xmalloc(sizeof(*pdraw));
1218 if (!pdraw)
1219 return NULL;
1220
1221 pdraw->drawable = drawable;
1222 pdraw->psc = sc;
1223
1224 if (!XF86DRICreateDrawable(dpy, sc->scr, drawable, &hwDrawable))
1225 return NULL;
1226
1227 /* Create a new drawable */
1228 pdraw->driDrawable.private =
1229 (*sc->driScreen.createNewDrawable)(&sc->driScreen,
1230 gc->mode,
1231 &pdraw->driDrawable,
1232 hwDrawable,
1233 GLX_WINDOW_BIT,
1234 empty_attribute_list);
1235
1236 if (!pdraw->driDrawable.private) {
1237 XF86DRIDestroyDrawable(dpy, sc->scr, drawable);
1238 Xfree(pdraw);
1239 return NULL;
1240 }
1241
1242 if (__glxHashInsert(sc->drawHash, drawable, pdraw)) {
1243 (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
1244 XF86DRIDestroyDrawable(dpy, sc->scr, drawable);
1245 Xfree(pdraw);
1246 return NULL;
1247 }
1248
1249 return &pdraw->driDrawable;
1250 }
1251
1252 static Bool BindContextWrapper( Display *dpy, GLXContext gc,
1253 GLXDrawable draw, GLXDrawable read )
1254 {
1255 __DRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc);
1256 __DRIdrawable *pread = FetchDRIDrawable(dpy, read, gc);
1257
1258 return (*gc->driContext.bindContext)(&gc->driContext, pdraw, pread);
1259 }
1260
1261
1262 static Bool UnbindContextWrapper( GLXContext gc )
1263 {
1264 return (*gc->driContext.unbindContext)(&gc->driContext);
1265 }
1266 #endif /* GLX_DIRECT_RENDERING */
1267
1268
1269 /**
1270 * Make a particular context current.
1271 *
1272 * \note This is in this file so that it can access dummyContext.
1273 */
1274 USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
1275 GLXDrawable read, GLXContext gc)
1276 {
1277 xGLXMakeCurrentReply reply;
1278 const GLXContext oldGC = __glXGetCurrentContext();
1279 const CARD8 opcode = __glXSetupForCommand(dpy);
1280 const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
1281 ? opcode : __glXSetupForCommand(oldGC->currentDpy);
1282 Bool bindReturnValue;
1283
1284
1285 if (!opcode || !oldOpcode) {
1286 return GL_FALSE;
1287 }
1288
1289 /* Make sure that the new context has a nonzero ID. In the request,
1290 * a zero context ID is used only to mean that we bind to no current
1291 * context.
1292 */
1293 if ((gc != NULL) && (gc->xid == None)) {
1294 return GL_FALSE;
1295 }
1296
1297 #ifndef GLX_DIRECT_RENDERING
1298 if (gc && gc->isDirect) {
1299 return GL_FALSE;
1300 }
1301 #endif
1302
1303 _glapi_check_multithread();
1304
1305 #ifdef GLX_DIRECT_RENDERING
1306 /* Bind the direct rendering context to the drawable */
1307 if (gc && gc->isDirect) {
1308 bindReturnValue = (gc->driContext.private)
1309 ? BindContextWrapper(dpy, gc, draw, read)
1310 : False;
1311 } else
1312 #endif
1313 {
1314 /* Send a glXMakeCurrent request to bind the new context. */
1315 bindReturnValue =
1316 SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
1317 ((dpy != oldGC->currentDpy) || oldGC->isDirect)
1318 ? None : oldGC->currentContextTag,
1319 draw, read, &reply);
1320 }
1321
1322
1323 if (!bindReturnValue) {
1324 return False;
1325 }
1326
1327 if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) &&
1328 !oldGC->isDirect && oldGC != &dummyContext) {
1329 xGLXMakeCurrentReply dummy_reply;
1330
1331 /* We are either switching from one dpy to another and have to
1332 * send a request to the previous dpy to unbind the previous
1333 * context, or we are switching away from a indirect context to
1334 * a direct context and have to send a request to the dpy to
1335 * unbind the previous context.
1336 */
1337 (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
1338 oldGC->currentContextTag, None, None,
1339 & dummy_reply);
1340 }
1341 #ifdef GLX_DIRECT_RENDERING
1342 else if (oldGC->isDirect && oldGC->driContext.private) {
1343 (void) UnbindContextWrapper(oldGC);
1344 }
1345 #endif
1346
1347
1348 /* Update our notion of what is current */
1349 __glXLock();
1350 if (gc == oldGC) {
1351 /* Even though the contexts are the same the drawable might have
1352 * changed. Note that gc cannot be the dummy, and that oldGC
1353 * cannot be NULL, therefore if they are the same, gc is not
1354 * NULL and not the dummy.
1355 */
1356 gc->currentDrawable = draw;
1357 gc->currentReadable = read;
1358 } else {
1359 if (oldGC != &dummyContext) {
1360 /* Old current context is no longer current to anybody */
1361 oldGC->currentDpy = 0;
1362 oldGC->currentDrawable = None;
1363 oldGC->currentReadable = None;
1364 oldGC->currentContextTag = 0;
1365
1366 if (oldGC->xid == None) {
1367 /* We are switching away from a context that was
1368 * previously destroyed, so we need to free the memory
1369 * for the old handle.
1370 */
1371 #ifdef GLX_DIRECT_RENDERING
1372 /* Destroy the old direct rendering context */
1373 if (oldGC->isDirect) {
1374 if (oldGC->driContext.private) {
1375 (*oldGC->driContext.destroyContext)
1376 (&oldGC->driContext);
1377 XF86DRIDestroyContext(oldGC->createDpy,
1378 oldGC->psc->scr,
1379 gc->hwContextID);
1380 oldGC->driContext.private = NULL;
1381 }
1382 }
1383 #endif
1384 __glXFreeContext(oldGC);
1385 }
1386 }
1387 if (gc) {
1388 __glXSetCurrentContext(gc);
1389
1390 gc->currentDpy = dpy;
1391 gc->currentDrawable = draw;
1392 gc->currentReadable = read;
1393
1394 if (!gc->isDirect) {
1395 if (!IndirectAPI)
1396 IndirectAPI = __glXNewIndirectAPI();
1397 _glapi_set_dispatch(IndirectAPI);
1398
1399 #ifdef GLX_USE_APPLEGL
1400 do {
1401 extern void XAppleDRIUseIndirectDispatch(void);
1402 XAppleDRIUseIndirectDispatch();
1403 } while (0);
1404 #endif
1405
1406 __GLXattribute *state =
1407 (__GLXattribute *)(gc->client_state_private);
1408
1409 gc->currentContextTag = reply.contextTag;
1410 if (state->array_state == NULL) {
1411 (void) glGetString(GL_EXTENSIONS);
1412 (void) glGetString(GL_VERSION);
1413 __glXInitVertexArrayState(gc);
1414 }
1415 }
1416 else {
1417 gc->currentContextTag = -1;
1418 }
1419 } else {
1420 __glXSetCurrentContext(&dummyContext);
1421 #ifdef GLX_DIRECT_RENDERING
1422 _glapi_set_dispatch(NULL); /* no-op functions */
1423 #endif
1424 }
1425 }
1426 __glXUnlock();
1427 return GL_TRUE;
1428 }
1429
1430
1431 PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc)
1432 {
1433 return MakeContextCurrent( dpy, draw, draw, gc );
1434 }
1435
1436 PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
1437 (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
1438 (dpy, d, r, ctx), MakeContextCurrent)
1439
1440 PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,
1441 (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
1442 (dpy, d, r, ctx), MakeContextCurrent)
1443
1444
1445 #ifdef DEBUG
1446 void __glXDumpDrawBuffer(__GLXcontext *ctx)
1447 {
1448 GLubyte *p = ctx->buf;
1449 GLubyte *end = ctx->pc;
1450 GLushort opcode, length;
1451
1452 while (p < end) {
1453 /* Fetch opcode */
1454 opcode = *((GLushort*) p);
1455 length = *((GLushort*) (p + 2));
1456 printf("%2x: %5d: ", opcode, length);
1457 length -= 4;
1458 p += 4;
1459 while (length > 0) {
1460 printf("%08x ", *((unsigned *) p));
1461 p += 4;
1462 length -= 4;
1463 }
1464 printf("\n");
1465 }
1466 }
1467 #endif
1468
1469 #ifdef USE_SPARC_ASM
1470 /*
1471 * Used only when we are sparc, using sparc assembler.
1472 *
1473 */
1474
1475 static void
1476 _glx_mesa_init_sparc_glapi_relocs(void)
1477 {
1478 unsigned int *insn_ptr, *end_ptr;
1479 unsigned long disp_addr;
1480
1481 insn_ptr = &_mesa_sparc_glapi_begin;
1482 end_ptr = &_mesa_sparc_glapi_end;
1483 disp_addr = (unsigned long) &_glapi_Dispatch;
1484
1485 /*
1486 * Verbatim from Mesa sparc.c. It's needed because there doesn't
1487 * seem to be a better way to do this:
1488 *
1489 * UNCONDITIONAL_JUMP ( (*_glapi_Dispatch) + entry_offset )
1490 *
1491 * This code is patching in the ADDRESS of the pointer to the
1492 * dispatch table. Hence, it must be called exactly once, because
1493 * that address is not going to change.
1494 *
1495 * What it points to can change, but Mesa (and hence, we) assume
1496 * that there is only one pointer.
1497 *
1498 */
1499 while (insn_ptr < end_ptr) {
1500 #if ( defined(__sparc_v9__) && ( !defined(__linux__) || defined(__linux_64__) ) )
1501 /*
1502 This code patches for 64-bit addresses. This had better
1503 not happen for Sparc/Linux, no matter what architecture we
1504 are building for. So, don't do this.
1505
1506 The 'defined(__linux_64__)' is used here as a placeholder for
1507 when we do do 64-bit usermode on sparc linux.
1508 */
1509 insn_ptr[0] |= (disp_addr >> (32 + 10));
1510 insn_ptr[1] |= ((disp_addr & 0xffffffff) >> 10);
1511 __glapi_sparc_icache_flush(&insn_ptr[0]);
1512 insn_ptr[2] |= ((disp_addr >> 32) & ((1 << 10) - 1));
1513 insn_ptr[3] |= (disp_addr & ((1 << 10) - 1));
1514 __glapi_sparc_icache_flush(&insn_ptr[2]);
1515 insn_ptr += 11;
1516 #else
1517 insn_ptr[0] |= (disp_addr >> 10);
1518 insn_ptr[1] |= (disp_addr & ((1 << 10) - 1));
1519 __glapi_sparc_icache_flush(&insn_ptr[0]);
1520 insn_ptr += 5;
1521 #endif
1522 }
1523 }
1524 #endif /* sparc ASM in use */
1525