Remove leftover __DRI{screen,drawable,context}Private references
[mesa.git] / src / glx / x11 / dri_glx.c
1 /**************************************************************************
2
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 All Rights Reserved.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sub license, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial portions
16 of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Kevin E. Martin <kevin@precisioninsight.com>
31 * Brian Paul <brian@precisioninsight.com>
32 *
33 */
34
35 #ifdef GLX_DIRECT_RENDERING
36
37 #include <X11/Xlib.h>
38 #include <X11/extensions/Xfixes.h>
39 #include <X11/extensions/Xdamage.h>
40 #include "glxclient.h"
41 #include "glcontextmodes.h"
42 #include "xf86dri.h"
43 #include "dri2.h"
44 #include "sarea.h"
45 #include <dlfcn.h>
46 #include <sys/types.h>
47 #include <sys/mman.h>
48 #include "xf86drm.h"
49 #include "dri_common.h"
50
51 typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
52 typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
53
54 struct __GLXDRIdisplayPrivateRec
55 {
56 __GLXDRIdisplay base;
57
58 /*
59 ** XFree86-DRI version information
60 */
61 int driMajor;
62 int driMinor;
63 int driPatch;
64 };
65
66 struct __GLXDRIcontextPrivateRec
67 {
68 __GLXDRIcontext base;
69 __DRIcontext *driContext;
70 XID hwContextID;
71 __GLXscreenConfigs *psc;
72 };
73
74 /*
75 * Given a display pointer and screen number, determine the name of
76 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
77 * Return True for success, False for failure.
78 */
79 static Bool
80 driGetDriverName(Display * dpy, int scrNum, char **driverName)
81 {
82 int directCapable;
83 Bool b;
84 int event, error;
85 int driverMajor, driverMinor, driverPatch;
86
87 *driverName = NULL;
88
89 if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */
90 if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
91 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
92 return False;
93 }
94 if (!directCapable) {
95 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
96 return False;
97 }
98
99 b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
100 &driverPatch, driverName);
101 if (!b) {
102 ErrorMessageF("Cannot determine driver name for screen %d\n",
103 scrNum);
104 return False;
105 }
106
107 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
108 driverMajor, driverMinor, driverPatch, *driverName,
109 scrNum);
110
111 return True;
112 }
113 else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */
114 char *dev;
115 Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
116
117 if (ret)
118 Xfree(dev);
119
120 return ret;
121 }
122
123 return False;
124 }
125
126 /*
127 * Exported function for querying the DRI driver for a given screen.
128 *
129 * The returned char pointer points to a static array that will be
130 * overwritten by subsequent calls.
131 */
132 PUBLIC const char *
133 glXGetScreenDriver(Display * dpy, int scrNum)
134 {
135 static char ret[32];
136 char *driverName;
137 if (driGetDriverName(dpy, scrNum, &driverName)) {
138 int len;
139 if (!driverName)
140 return NULL;
141 len = strlen(driverName);
142 if (len >= 31)
143 return NULL;
144 memcpy(ret, driverName, len + 1);
145 Xfree(driverName);
146 return ret;
147 }
148 return NULL;
149 }
150
151 /*
152 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
153 *
154 * The returned char pointer points directly into the driver. Therefore
155 * it should be treated as a constant.
156 *
157 * If the driver was not found or does not support configuration NULL is
158 * returned.
159 *
160 * Note: The driver remains opened after this function returns.
161 */
162 PUBLIC const char *
163 glXGetDriverConfig(const char *driverName)
164 {
165 void *handle = driOpenDriver(driverName);
166 if (handle)
167 return dlsym(handle, "__driConfigOptions");
168 else
169 return NULL;
170 }
171
172 #ifdef XDAMAGE_1_1_INTERFACE
173
174 static GLboolean
175 has_damage_post(Display * dpy)
176 {
177 static GLboolean inited = GL_FALSE;
178 static GLboolean has_damage;
179
180 if (!inited) {
181 int major, minor;
182
183 if (XDamageQueryVersion(dpy, &major, &minor) &&
184 major == 1 && minor >= 1) {
185 has_damage = GL_TRUE;
186 }
187 else {
188 has_damage = GL_FALSE;
189 }
190 inited = GL_TRUE;
191 }
192
193 return has_damage;
194 }
195
196 static void
197 __glXReportDamage(__DRIdrawable * driDraw,
198 int x, int y,
199 drm_clip_rect_t * rects, int num_rects,
200 GLboolean front_buffer, void *loaderPrivate)
201 {
202 XRectangle *xrects;
203 XserverRegion region;
204 int i;
205 int x_off, y_off;
206 __GLXDRIdrawable *glxDraw = loaderPrivate;
207 __GLXscreenConfigs *psc = glxDraw->psc;
208 Display *dpy = psc->dpy;
209 Drawable drawable;
210
211 if (!has_damage_post(dpy))
212 return;
213
214 if (front_buffer) {
215 x_off = x;
216 y_off = y;
217 drawable = RootWindow(dpy, psc->scr);
218 }
219 else {
220 x_off = 0;
221 y_off = 0;
222 drawable = glxDraw->xDrawable;
223 }
224
225 xrects = malloc(sizeof(XRectangle) * num_rects);
226 if (xrects == NULL)
227 return;
228
229 for (i = 0; i < num_rects; i++) {
230 xrects[i].x = rects[i].x1 + x_off;
231 xrects[i].y = rects[i].y1 + y_off;
232 xrects[i].width = rects[i].x2 - rects[i].x1;
233 xrects[i].height = rects[i].y2 - rects[i].y1;
234 }
235 region = XFixesCreateRegion(dpy, xrects, num_rects);
236 free(xrects);
237 XDamageAdd(dpy, drawable, region);
238 XFixesDestroyRegion(dpy, region);
239 }
240
241 static const __DRIdamageExtension damageExtension = {
242 {__DRI_DAMAGE, __DRI_DAMAGE_VERSION},
243 __glXReportDamage,
244 };
245
246 #endif
247
248 static GLboolean
249 __glXDRIGetDrawableInfo(__DRIdrawable * drawable,
250 unsigned int *index, unsigned int *stamp,
251 int *X, int *Y, int *W, int *H,
252 int *numClipRects, drm_clip_rect_t ** pClipRects,
253 int *backX, int *backY,
254 int *numBackClipRects,
255 drm_clip_rect_t ** pBackClipRects,
256 void *loaderPrivate)
257 {
258 __GLXDRIdrawable *glxDraw = loaderPrivate;
259 __GLXscreenConfigs *psc = glxDraw->psc;
260 Display *dpy = psc->dpy;
261
262 return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
263 index, stamp, X, Y, W, H,
264 numClipRects, pClipRects,
265 backX, backY,
266 numBackClipRects, pBackClipRects);
267 }
268
269 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
270 {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION},
271 __glXDRIGetDrawableInfo
272 };
273
274 static const __DRIextension *loader_extensions[] = {
275 &systemTimeExtension.base,
276 &getDrawableInfoExtension.base,
277 #ifdef XDAMAGE_1_1_INTERFACE
278 &damageExtension.base,
279 #endif
280 NULL
281 };
282
283 #ifndef GLX_USE_APPLEGL
284
285 /**
286 * Perform the required libGL-side initialization and call the client-side
287 * driver's \c __driCreateNewScreen function.
288 *
289 * \param dpy Display pointer.
290 * \param scrn Screen number on the display.
291 * \param psc DRI screen information.
292 * \param driDpy DRI display information.
293 * \param createNewScreen Pointer to the client-side driver's
294 * \c __driCreateNewScreen function.
295 * \returns A pointer to the \c __DRIscreen structure returned by
296 * the client-side driver on success, or \c NULL on failure.
297 */
298 static void *
299 CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
300 __GLXDRIdisplayPrivate * driDpy)
301 {
302 void *psp = NULL;
303 drm_handle_t hSAREA;
304 drmAddress pSAREA = MAP_FAILED;
305 char *BusID;
306 __DRIversion ddx_version;
307 __DRIversion dri_version;
308 __DRIversion drm_version;
309 __DRIframebuffer framebuffer;
310 int fd = -1;
311 int status;
312
313 drm_magic_t magic;
314 drmVersionPtr version;
315 int newlyopened;
316 char *driverName;
317 drm_handle_t hFB;
318 int junk;
319 const __DRIconfig **driver_configs;
320 __GLcontextModes *visual;
321
322 /* DRI protocol version. */
323 dri_version.major = driDpy->driMajor;
324 dri_version.minor = driDpy->driMinor;
325 dri_version.patch = driDpy->driPatch;
326
327 framebuffer.base = MAP_FAILED;
328 framebuffer.dev_priv = NULL;
329
330 if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
331 ErrorMessageF("XF86DRIOpenConnection failed\n");
332 goto handle_error;
333 }
334
335 fd = drmOpenOnce(NULL, BusID, &newlyopened);
336
337 Xfree(BusID); /* No longer needed */
338
339 if (fd < 0) {
340 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
341 goto handle_error;
342 }
343
344 if (drmGetMagic(fd, &magic)) {
345 ErrorMessageF("drmGetMagic failed\n");
346 goto handle_error;
347 }
348
349 version = drmGetVersion(fd);
350 if (version) {
351 drm_version.major = version->version_major;
352 drm_version.minor = version->version_minor;
353 drm_version.patch = version->version_patchlevel;
354 drmFreeVersion(version);
355 }
356 else {
357 drm_version.major = -1;
358 drm_version.minor = -1;
359 drm_version.patch = -1;
360 }
361
362 if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
363 ErrorMessageF("XF86DRIAuthConnection failed\n");
364 goto handle_error;
365 }
366
367 /* Get device name (like "tdfx") and the ddx version numbers.
368 * We'll check the version in each DRI driver's "createNewScreen"
369 * function. */
370 if (!XF86DRIGetClientDriverName(dpy, scrn,
371 &ddx_version.major,
372 &ddx_version.minor,
373 &ddx_version.patch, &driverName)) {
374 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
375 goto handle_error;
376 }
377
378 Xfree(driverName); /* No longer needed. */
379
380 /*
381 * Get device-specific info. pDevPriv will point to a struct
382 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
383 * has information about the screen size, depth, pitch, ancilliary
384 * buffers, DRM mmap handles, etc.
385 */
386 if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
387 &framebuffer.size, &framebuffer.stride,
388 &framebuffer.dev_priv_size,
389 &framebuffer.dev_priv)) {
390 ErrorMessageF("XF86DRIGetDeviceInfo failed");
391 goto handle_error;
392 }
393
394 framebuffer.width = DisplayWidth(dpy, scrn);
395 framebuffer.height = DisplayHeight(dpy, scrn);
396
397 /* Map the framebuffer region. */
398 status = drmMap(fd, hFB, framebuffer.size,
399 (drmAddressPtr) & framebuffer.base);
400 if (status != 0) {
401 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
402 goto handle_error;
403 }
404
405 /* Map the SAREA region. Further mmap regions may be setup in
406 * each DRI driver's "createNewScreen" function.
407 */
408 status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
409 if (status != 0) {
410 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
411 goto handle_error;
412 }
413
414 psp = (*psc->legacy->createNewScreen) (scrn,
415 &ddx_version,
416 &dri_version,
417 &drm_version,
418 &framebuffer,
419 pSAREA,
420 fd,
421 loader_extensions,
422 &driver_configs, psc);
423
424 if (psp == NULL) {
425 ErrorMessageF("Calling driver entry point failed");
426 goto handle_error;
427 }
428
429 psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
430 psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
431
432 psc->driver_configs = driver_configs;
433
434 /* Visuals with depth != screen depth are subject to automatic compositing
435 * in the X server, so DRI1 can't render to them properly. Mark them as
436 * non-conformant to prevent apps from picking them up accidentally.
437 */
438 for (visual = psc->visuals; visual; visual = visual->next) {
439 XVisualInfo template;
440 XVisualInfo *visuals;
441 int num_visuals;
442 long mask;
443
444 template.visualid = visual->visualID;
445 mask = VisualIDMask;
446 visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
447
448 if (visuals) {
449 if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
450 visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
451
452 XFree(visuals);
453 }
454 }
455
456 return psp;
457
458 handle_error:
459 if (pSAREA != MAP_FAILED)
460 drmUnmap(pSAREA, SAREA_MAX);
461
462 if (framebuffer.base != MAP_FAILED)
463 drmUnmap((drmAddress) framebuffer.base, framebuffer.size);
464
465 if (framebuffer.dev_priv != NULL)
466 Xfree(framebuffer.dev_priv);
467
468 if (fd >= 0)
469 drmCloseOnce(fd);
470
471 XF86DRICloseConnection(dpy, scrn);
472
473 ErrorMessageF("reverting to software direct rendering\n");
474
475 return NULL;
476 }
477
478 #else /* !GLX_USE_APPLEGL */
479
480 static void *
481 CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
482 __GLXDRIdisplayPrivate * driDpy)
483 {
484 return NULL;
485 }
486
487 #endif /* !GLX_USE_APPLEGL */
488
489 static void
490 driDestroyContext(__GLXDRIcontext * context,
491 __GLXscreenConfigs * psc, Display * dpy)
492 {
493 __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
494
495 (*psc->core->destroyContext) (pcp->driContext);
496
497 XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
498 Xfree(pcp);
499 }
500
501 static Bool
502 driBindContext(__GLXDRIcontext * context,
503 __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
504 {
505 __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
506 const __DRIcoreExtension *core = pcp->psc->core;
507
508 return (*core->bindContext) (pcp->driContext,
509 draw->driDrawable, read->driDrawable);
510 }
511
512 static void
513 driUnbindContext(__GLXDRIcontext * context)
514 {
515 __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
516 const __DRIcoreExtension *core = pcp->psc->core;
517
518 (*core->unbindContext) (pcp->driContext);
519 }
520
521 static __GLXDRIcontext *
522 driCreateContext(__GLXscreenConfigs * psc,
523 const __GLcontextModes * mode,
524 GLXContext gc, GLXContext shareList, int renderType)
525 {
526 __GLXDRIcontextPrivate *pcp, *pcp_shared;
527 drm_context_t hwContext;
528 __DRIcontext *shared = NULL;
529 __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
530
531 if (!psc || !psc->driScreen)
532 return NULL;
533
534 if (shareList) {
535 pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
536 shared = pcp_shared->driContext;
537 }
538
539 pcp = Xmalloc(sizeof *pcp);
540 if (pcp == NULL)
541 return NULL;
542
543 pcp->psc = psc;
544 if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
545 mode->visualID,
546 &pcp->hwContextID, &hwContext)) {
547 Xfree(pcp);
548 return NULL;
549 }
550
551 pcp->driContext =
552 (*psc->legacy->createNewContext) (psc->__driScreen,
553 config->driConfig,
554 renderType, shared, hwContext, pcp);
555 if (pcp->driContext == NULL) {
556 XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
557 Xfree(pcp);
558 return NULL;
559 }
560
561 pcp->base.destroyContext = driDestroyContext;
562 pcp->base.bindContext = driBindContext;
563 pcp->base.unbindContext = driUnbindContext;
564
565 return &pcp->base;
566 }
567
568 static void
569 driDestroyDrawable(__GLXDRIdrawable * pdraw)
570 {
571 __GLXscreenConfigs *psc = pdraw->psc;
572
573 (*psc->core->destroyDrawable) (pdraw->driDrawable);
574 XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
575 Xfree(pdraw);
576 }
577
578 static __GLXDRIdrawable *
579 driCreateDrawable(__GLXscreenConfigs * psc,
580 XID xDrawable,
581 GLXDrawable drawable, const __GLcontextModes * modes)
582 {
583 __GLXDRIdrawable *pdraw;
584 drm_drawable_t hwDrawable;
585 void *empty_attribute_list = NULL;
586 __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
587
588 /* Old dri can't handle GLX 1.3+ drawable constructors. */
589 if (xDrawable != drawable)
590 return NULL;
591
592 pdraw = Xmalloc(sizeof(*pdraw));
593 if (!pdraw)
594 return NULL;
595
596 pdraw->drawable = drawable;
597 pdraw->psc = psc;
598
599 if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable)) {
600 Xfree(pdraw);
601 return NULL;
602 }
603
604 /* Create a new drawable */
605 pdraw->driDrawable =
606 (*psc->legacy->createNewDrawable) (psc->__driScreen,
607 config->driConfig,
608 hwDrawable,
609 GLX_WINDOW_BIT,
610 empty_attribute_list, pdraw);
611
612 if (!pdraw->driDrawable) {
613 XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
614 Xfree(pdraw);
615 return NULL;
616 }
617
618 pdraw->destroyDrawable = driDestroyDrawable;
619
620 return pdraw;
621 }
622
623 static void
624 driSwapBuffers(__GLXDRIdrawable * pdraw)
625 {
626 (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
627 }
628
629 static void
630 driCopySubBuffer(__GLXDRIdrawable * pdraw,
631 int x, int y, int width, int height)
632 {
633 (*pdraw->psc->driCopySubBuffer->copySubBuffer) (pdraw->driDrawable,
634 x, y, width, height);
635 }
636
637 static void
638 driDestroyScreen(__GLXscreenConfigs * psc)
639 {
640 /* Free the direct rendering per screen data */
641 if (psc->__driScreen)
642 (*psc->core->destroyScreen) (psc->__driScreen);
643 psc->__driScreen = NULL;
644 if (psc->driver)
645 dlclose(psc->driver);
646 }
647
648 static __GLXDRIscreen *
649 driCreateScreen(__GLXscreenConfigs * psc, int screen,
650 __GLXdisplayPrivate * priv)
651 {
652 __GLXDRIdisplayPrivate *pdp;
653 __GLXDRIscreen *psp;
654 const __DRIextension **extensions;
655 char *driverName;
656 int i;
657
658 psp = Xcalloc(1, sizeof *psp);
659 if (psp == NULL)
660 return NULL;
661
662 /* Initialize per screen dynamic client GLX extensions */
663 psc->ext_list_first_time = GL_TRUE;
664
665 if (!driGetDriverName(priv->dpy, screen, &driverName)) {
666 Xfree(psp);
667 return NULL;
668 }
669
670 psc->driver = driOpenDriver(driverName);
671 Xfree(driverName);
672 if (psc->driver == NULL) {
673 Xfree(psp);
674 return NULL;
675 }
676
677 extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
678 if (extensions == NULL) {
679 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
680 Xfree(psp);
681 return NULL;
682 }
683
684 for (i = 0; extensions[i]; i++) {
685 if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
686 psc->core = (__DRIcoreExtension *) extensions[i];
687 if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
688 psc->legacy = (__DRIlegacyExtension *) extensions[i];
689 }
690
691 if (psc->core == NULL || psc->legacy == NULL) {
692 Xfree(psp);
693 return NULL;
694 }
695
696 pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
697 psc->__driScreen = CallCreateNewScreen(psc->dpy, screen, psc, pdp);
698 if (psc->__driScreen == NULL) {
699 dlclose(psc->driver);
700 Xfree(psp);
701 return NULL;
702 }
703
704 driBindExtensions(psc, 0);
705 if (psc->driCopySubBuffer)
706 psp->copySubBuffer = driCopySubBuffer;
707
708 psp->destroyScreen = driDestroyScreen;
709 psp->createContext = driCreateContext;
710 psp->createDrawable = driCreateDrawable;
711 psp->swapBuffers = driSwapBuffers;
712 psp->waitX = NULL;
713 psp->waitGL = NULL;
714
715 return psp;
716 }
717
718 /* Called from __glXFreeDisplayPrivate.
719 */
720 static void
721 driDestroyDisplay(__GLXDRIdisplay * dpy)
722 {
723 Xfree(dpy);
724 }
725
726 /*
727 * Allocate, initialize and return a __DRIdisplayPrivate object.
728 * This is called from __glXInitialize() when we are given a new
729 * display pointer.
730 */
731 _X_HIDDEN __GLXDRIdisplay *
732 driCreateDisplay(Display * dpy)
733 {
734 __GLXDRIdisplayPrivate *pdpyp;
735 int eventBase, errorBase;
736 int major, minor, patch;
737
738 if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
739 return NULL;
740 }
741
742 if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
743 return NULL;
744 }
745
746 pdpyp = Xmalloc(sizeof *pdpyp);
747 if (!pdpyp) {
748 return NULL;
749 }
750
751 pdpyp->driMajor = major;
752 pdpyp->driMinor = minor;
753 pdpyp->driPatch = patch;
754
755 pdpyp->base.destroyDisplay = driDestroyDisplay;
756 pdpyp->base.createScreen = driCreateScreen;
757
758 return &pdpyp->base;
759 }
760
761 #endif /* GLX_DIRECT_RENDERING */