1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
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:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
30 * Kevin E. Martin <kevin@precisioninsight.com>
31 * Brian Paul <brian@precisioninsight.com>
35 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
38 #include <X11/extensions/Xfixes.h>
39 #include <X11/extensions/Xdamage.h>
40 #include "glxclient.h"
43 #include "dri_sarea.h"
45 #include <sys/types.h>
48 #include "dri_common.h"
55 ** XFree86-DRI version information
64 struct glx_screen base
;
66 __DRIscreen
*driScreen
;
67 __GLXDRIscreen vtable
;
68 const __DRIlegacyExtension
*legacy
;
69 const __DRIcoreExtension
*core
;
70 const __DRIswapControlExtension
*swapControl
;
71 const __DRImediaStreamCounterExtension
*msc
;
72 const __DRIconfig
**driver_configs
;
73 const __DRIcopySubBufferExtension
*driCopySubBuffer
;
81 struct glx_context base
;
82 __DRIcontext
*driContext
;
88 __GLXDRIdrawable base
;
90 __DRIdrawable
*driDrawable
;
94 * Given a display pointer and screen number, determine the name of
95 * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc).
96 * Return True for success, False for failure.
99 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
104 int driverMajor
, driverMinor
, driverPatch
;
108 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
109 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
110 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
113 if (!directCapable
) {
114 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
118 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
119 &driverPatch
, driverName
);
121 ErrorMessageF("Cannot determine driver name for screen %d\n",
126 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
127 driverMajor
, driverMinor
, driverPatch
, *driverName
,
132 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
134 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
146 * Exported function for querying the DRI driver for a given screen.
148 * The returned char pointer points to a static array that will be
149 * overwritten by subsequent calls.
151 _X_EXPORT
const char *
152 glXGetScreenDriver(Display
* dpy
, int scrNum
)
156 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
160 len
= strlen(driverName
);
163 memcpy(ret
, driverName
, len
+ 1);
171 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
173 * The returned char pointer points directly into the driver. Therefore
174 * it should be treated as a constant.
176 * If the driver was not found or does not support configuration NULL is
179 * Note: The driver remains opened after this function returns.
181 _X_EXPORT
const char *
182 glXGetDriverConfig(const char *driverName
)
184 void *handle
= driOpenDriver(driverName
);
185 const __DRIextension
**extensions
;
190 extensions
= driGetDriverExtensions(handle
, driverName
);
192 for (int i
= 0; extensions
[i
]; i
++) {
193 if (strcmp(extensions
[i
]->name
, __DRI_CONFIG_OPTIONS
) == 0)
194 return ((__DRIconfigOptionsExtension
*)extensions
[i
])->xml
;
198 /* Fall back to the old method */
199 return dlsym(handle
, "__driConfigOptions");
202 #ifdef XDAMAGE_1_1_INTERFACE
205 has_damage_post(Display
* dpy
)
207 static GLboolean inited
= GL_FALSE
;
208 static GLboolean has_damage
;
213 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
214 major
== 1 && minor
>= 1) {
215 has_damage
= GL_TRUE
;
218 has_damage
= GL_FALSE
;
227 __glXReportDamage(__DRIdrawable
* driDraw
,
229 drm_clip_rect_t
* rects
, int num_rects
,
230 GLboolean front_buffer
, void *loaderPrivate
)
233 XserverRegion region
;
236 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
237 struct glx_screen
*psc
= glxDraw
->psc
;
238 Display
*dpy
= psc
->dpy
;
241 if (!has_damage_post(dpy
))
247 drawable
= RootWindow(dpy
, psc
->scr
);
252 drawable
= glxDraw
->xDrawable
;
255 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
259 for (i
= 0; i
< num_rects
; i
++) {
260 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
261 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
262 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
263 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
265 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
267 XDamageAdd(dpy
, drawable
, region
);
268 XFixesDestroyRegion(dpy
, region
);
271 static const __DRIdamageExtension damageExtension
= {
272 .base
= {__DRI_DAMAGE
, 1 },
274 .reportDamage
= __glXReportDamage
,
280 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
281 unsigned int *index
, unsigned int *stamp
,
282 int *X
, int *Y
, int *W
, int *H
,
283 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
284 int *backX
, int *backY
,
285 int *numBackClipRects
,
286 drm_clip_rect_t
** pBackClipRects
,
289 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
290 struct glx_screen
*psc
= glxDraw
->psc
;
291 Display
*dpy
= psc
->dpy
;
293 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
294 index
, stamp
, X
, Y
, W
, H
,
295 numClipRects
, pClipRects
,
297 numBackClipRects
, pBackClipRects
);
300 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
301 .base
= {__DRI_GET_DRAWABLE_INFO
, 1 },
303 .getDrawableInfo
= __glXDRIGetDrawableInfo
306 static const __DRIextension
*loader_extensions
[] = {
307 &systemTimeExtension
.base
,
308 &getDrawableInfoExtension
.base
,
309 #ifdef XDAMAGE_1_1_INTERFACE
310 &damageExtension
.base
,
316 * Perform the required libGL-side initialization and call the client-side
317 * driver's \c __driCreateNewScreen function.
319 * \param dpy Display pointer.
320 * \param scrn Screen number on the display.
321 * \param psc DRI screen information.
322 * \param driDpy DRI display information.
323 * \param createNewScreen Pointer to the client-side driver's
324 * \c __driCreateNewScreen function.
325 * \returns A pointer to the \c __DRIscreen structure returned by
326 * the client-side driver on success, or \c NULL on failure.
329 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
330 struct dri_display
* driDpy
)
334 drmAddress pSAREA
= MAP_FAILED
;
336 __DRIversion ddx_version
;
337 __DRIversion dri_version
;
338 __DRIversion drm_version
;
339 __DRIframebuffer framebuffer
;
344 drmVersionPtr version
;
349 const __DRIconfig
**driver_configs
;
350 struct glx_config
*visual
, *configs
= NULL
, *visuals
= NULL
;
352 /* DRI protocol version. */
353 dri_version
.major
= driDpy
->driMajor
;
354 dri_version
.minor
= driDpy
->driMinor
;
355 dri_version
.patch
= driDpy
->driPatch
;
357 framebuffer
.base
= MAP_FAILED
;
358 framebuffer
.dev_priv
= NULL
;
359 framebuffer
.size
= 0;
361 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
362 ErrorMessageF("XF86DRIOpenConnection failed\n");
366 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
368 free(BusID
); /* No longer needed */
371 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
375 if (drmGetMagic(fd
, &magic
)) {
376 ErrorMessageF("drmGetMagic failed\n");
380 version
= drmGetVersion(fd
);
382 drm_version
.major
= version
->version_major
;
383 drm_version
.minor
= version
->version_minor
;
384 drm_version
.patch
= version
->version_patchlevel
;
385 drmFreeVersion(version
);
388 drm_version
.major
= -1;
389 drm_version
.minor
= -1;
390 drm_version
.patch
= -1;
393 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
394 ErrorMessageF("XF86DRIAuthConnection failed\n");
398 /* Get device name (like "radeon") and the ddx version numbers.
399 * We'll check the version in each DRI driver's "createNewScreen"
401 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
404 &ddx_version
.patch
, &driverName
)) {
405 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
409 free(driverName
); /* No longer needed. */
412 * Get device-specific info. pDevPriv will point to a struct
413 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
414 * has information about the screen size, depth, pitch, ancilliary
415 * buffers, DRM mmap handles, etc.
417 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
418 &framebuffer
.size
, &framebuffer
.stride
,
419 &framebuffer
.dev_priv_size
,
420 &framebuffer
.dev_priv
)) {
421 ErrorMessageF("XF86DRIGetDeviceInfo failed\n");
425 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
426 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
428 /* Map the framebuffer region. */
429 status
= drmMap(fd
, hFB
, framebuffer
.size
,
430 (drmAddressPtr
) & framebuffer
.base
);
432 ErrorMessageF("drmMap of framebuffer failed (%s)\n", strerror(-status
));
436 /* Map the SAREA region. Further mmap regions may be setup in
437 * each DRI driver's "createNewScreen" function.
439 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
441 ErrorMessageF("drmMap of SAREA failed (%s)\n", strerror(-status
));
445 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
453 &driver_configs
, psc
);
456 ErrorMessageF("Calling driver entry point failed\n");
460 configs
= driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
461 visuals
= driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
463 if (!configs
|| !visuals
) {
464 ErrorMessageF("No matching fbConfigs or visuals found\n");
468 glx_config_destroy_list(psc
->base
.configs
);
469 psc
->base
.configs
= configs
;
470 glx_config_destroy_list(psc
->base
.visuals
);
471 psc
->base
.visuals
= visuals
;
473 psc
->driver_configs
= driver_configs
;
475 /* Visuals with depth != screen depth are subject to automatic compositing
476 * in the X server, so DRI1 can't render to them properly. Mark them as
477 * non-conformant to prevent apps from picking them up accidentally.
479 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
480 XVisualInfo
template;
481 XVisualInfo
*visuals
;
485 template.visualid
= visual
->visualID
;
487 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
490 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
491 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
501 glx_config_destroy_list(configs
);
503 glx_config_destroy_list(visuals
);
505 if (pSAREA
!= MAP_FAILED
)
506 drmUnmap(pSAREA
, SAREA_MAX
);
508 if (framebuffer
.base
!= MAP_FAILED
)
509 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
511 free(framebuffer
.dev_priv
);
516 XF86DRICloseConnection(dpy
, scrn
);
518 ErrorMessageF("reverting to software direct rendering\n");
524 dri_destroy_context(struct glx_context
* context
)
526 struct dri_context
*pcp
= (struct dri_context
*) context
;
527 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
529 driReleaseDrawables(&pcp
->base
);
531 free((char *) context
->extensions
);
533 (*psc
->core
->destroyContext
) (pcp
->driContext
);
535 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
540 dri_bind_context(struct glx_context
*context
, struct glx_context
*old
,
541 GLXDrawable draw
, GLXDrawable read
)
543 struct dri_context
*pcp
= (struct dri_context
*) context
;
544 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
545 struct dri_drawable
*pdraw
, *pread
;
547 pdraw
= (struct dri_drawable
*) driFetchDrawable(context
, draw
);
548 pread
= (struct dri_drawable
*) driFetchDrawable(context
, read
);
550 driReleaseDrawables(&pcp
->base
);
552 if (pdraw
== NULL
|| pread
== NULL
)
553 return GLXBadDrawable
;
555 if ((*psc
->core
->bindContext
) (pcp
->driContext
,
556 pdraw
->driDrawable
, pread
->driDrawable
))
559 return GLXBadContext
;
563 dri_unbind_context(struct glx_context
*context
, struct glx_context
*new)
565 struct dri_context
*pcp
= (struct dri_context
*) context
;
566 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
568 (*psc
->core
->unbindContext
) (pcp
->driContext
);
571 static const struct glx_context_vtable dri_context_vtable
= {
572 .destroy
= dri_destroy_context
,
573 .bind
= dri_bind_context
,
574 .unbind
= dri_unbind_context
,
577 .use_x_font
= DRI_glXUseXFont
,
578 .bind_tex_image
= NULL
,
579 .release_tex_image
= NULL
,
580 .get_proc_address
= NULL
,
583 static struct glx_context
*
584 dri_create_context(struct glx_screen
*base
,
585 struct glx_config
*config_base
,
586 struct glx_context
*shareList
, int renderType
)
588 struct dri_context
*pcp
, *pcp_shared
;
589 struct dri_screen
*psc
= (struct dri_screen
*) base
;
590 drm_context_t hwContext
;
591 __DRIcontext
*shared
= NULL
;
592 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) config_base
;
594 if (!psc
->base
.driScreen
)
597 /* Check the renderType value */
598 if (!validate_renderType_against_config(config_base
, renderType
))
602 /* If the shareList context is not a DRI context, we cannot possibly
603 * create a DRI context that shares it.
605 if (shareList
->vtable
->destroy
!= dri_destroy_context
) {
609 pcp_shared
= (struct dri_context
*) shareList
;
610 shared
= pcp_shared
->driContext
;
613 pcp
= calloc(1, sizeof *pcp
);
617 if (!glx_context_init(&pcp
->base
, &psc
->base
, &config
->base
)) {
622 pcp
->base
.renderType
= renderType
;
624 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
625 config
->base
.visualID
,
626 &pcp
->hwContextID
, &hwContext
)) {
632 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
634 renderType
, shared
, hwContext
, pcp
);
635 if (pcp
->driContext
== NULL
) {
636 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
641 pcp
->base
.vtable
= &dri_context_vtable
;
647 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
649 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
650 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
652 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
653 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
657 static __GLXDRIdrawable
*
658 driCreateDrawable(struct glx_screen
*base
,
660 GLXDrawable drawable
, struct glx_config
*config_base
)
662 drm_drawable_t hwDrawable
;
663 void *empty_attribute_list
= NULL
;
664 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) config_base
;
665 struct dri_screen
*psc
= (struct dri_screen
*) base
;
666 struct dri_drawable
*pdp
;
668 /* Old dri can't handle GLX 1.3+ drawable constructors. */
669 if (xDrawable
!= drawable
)
672 pdp
= calloc(1, sizeof *pdp
);
676 pdp
->base
.drawable
= drawable
;
677 pdp
->base
.psc
= &psc
->base
;
679 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
680 drawable
, &hwDrawable
)) {
685 /* Create a new drawable */
687 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
691 empty_attribute_list
, pdp
);
693 if (!pdp
->driDrawable
) {
694 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
699 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
705 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
706 int64_t unused3
, Bool flush
)
708 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
709 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
715 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
720 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
721 int x
, int y
, int width
, int height
, Bool flush
)
723 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
724 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
730 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
731 x
, y
, width
, height
);
735 driDestroyScreen(struct glx_screen
*base
)
737 struct dri_screen
*psc
= (struct dri_screen
*) base
;
739 /* Free the direct rendering per screen data */
741 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
742 driDestroyConfigs(psc
->driver_configs
);
743 psc
->driScreen
= NULL
;
745 dlclose(psc
->driver
);
749 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
751 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
754 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
756 if (psc
->swapControl
!= NULL
) {
757 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
761 return GLX_BAD_CONTEXT
;
765 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
767 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
770 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
772 if (psc
->swapControl
!= NULL
)
773 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
778 /* Bind DRI1 specific extensions */
780 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
784 for (i
= 0; extensions
[i
]; i
++) {
785 /* No DRI2 support for swap_control at the moment, since SwapBuffers
786 * is done by the X server */
787 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
788 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
789 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
790 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
793 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
794 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
795 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
798 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
799 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
800 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
803 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
804 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
806 /* Ignore unknown extensions */
810 static const struct glx_screen_vtable dri_screen_vtable
= {
811 .create_context
= dri_create_context
,
812 .create_context_attribs
= NULL
,
813 .query_renderer_integer
= NULL
,
814 .query_renderer_string
= NULL
,
817 static struct glx_screen
*
818 driCreateScreen(int screen
, struct glx_display
*priv
)
820 struct dri_display
*pdp
;
822 const __DRIextension
**extensions
;
823 struct dri_screen
*psc
;
827 psc
= calloc(1, sizeof *psc
);
831 if (!glx_screen_init(&psc
->base
, screen
, priv
)) {
836 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
840 psc
->driver
= driOpenDriver(driverName
);
841 if (psc
->driver
== NULL
)
844 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
845 if (extensions
== NULL
) {
846 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
850 for (i
= 0; extensions
[i
]; i
++) {
851 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
852 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
853 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
854 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
857 if (psc
->core
== NULL
|| psc
->legacy
== NULL
)
860 pdp
= (struct dri_display
*) priv
->driDisplay
;
862 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
863 if (psc
->driScreen
== NULL
)
866 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
867 driBindExtensions(psc
, extensions
);
869 psc
->base
.vtable
= &dri_screen_vtable
;
871 psc
->base
.driScreen
= psp
;
872 if (psc
->driCopySubBuffer
)
873 psp
->copySubBuffer
= driCopySubBuffer
;
875 psp
->destroyScreen
= driDestroyScreen
;
876 psp
->createDrawable
= driCreateDrawable
;
877 psp
->swapBuffers
= driSwapBuffers
;
879 psp
->setSwapInterval
= driSetSwapInterval
;
880 psp
->getSwapInterval
= driGetSwapInterval
;
887 CriticalErrorMessageF("failed to load driver: %s\n", driverName
);
892 dlclose(psc
->driver
);
893 glx_screen_cleanup(&psc
->base
);
899 /* Called from __glXFreeDisplayPrivate.
902 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
908 * Allocate, initialize and return a __DRIdisplayPrivate object.
909 * This is called from __glXInitialize() when we are given a new
912 _X_HIDDEN __GLXDRIdisplay
*
913 driCreateDisplay(Display
* dpy
)
915 struct dri_display
*pdpyp
;
916 int eventBase
, errorBase
;
917 int major
, minor
, patch
;
919 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
923 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
927 pdpyp
= malloc(sizeof *pdpyp
);
932 pdpyp
->driMajor
= major
;
933 pdpyp
->driMinor
= minor
;
934 pdpyp
->driPatch
= patch
;
936 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
937 pdpyp
->base
.createScreen
= driCreateScreen
;
942 #endif /* GLX_DIRECT_RENDERING */