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"
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
)
466 glx_config_destroy_list(psc
->base
.configs
);
467 psc
->base
.configs
= configs
;
468 glx_config_destroy_list(psc
->base
.visuals
);
469 psc
->base
.visuals
= visuals
;
471 psc
->driver_configs
= driver_configs
;
473 /* Visuals with depth != screen depth are subject to automatic compositing
474 * in the X server, so DRI1 can't render to them properly. Mark them as
475 * non-conformant to prevent apps from picking them up accidentally.
477 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
478 XVisualInfo
template;
479 XVisualInfo
*visuals
;
483 template.visualid
= visual
->visualID
;
485 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
488 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
489 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
499 glx_config_destroy_list(configs
);
501 glx_config_destroy_list(visuals
);
503 if (pSAREA
!= MAP_FAILED
)
504 drmUnmap(pSAREA
, SAREA_MAX
);
506 if (framebuffer
.base
!= MAP_FAILED
)
507 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
509 free(framebuffer
.dev_priv
);
514 XF86DRICloseConnection(dpy
, scrn
);
516 ErrorMessageF("reverting to software direct rendering\n");
522 dri_destroy_context(struct glx_context
* context
)
524 struct dri_context
*pcp
= (struct dri_context
*) context
;
525 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
527 driReleaseDrawables(&pcp
->base
);
529 free((char *) context
->extensions
);
531 (*psc
->core
->destroyContext
) (pcp
->driContext
);
533 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
538 dri_bind_context(struct glx_context
*context
, struct glx_context
*old
,
539 GLXDrawable draw
, GLXDrawable read
)
541 struct dri_context
*pcp
= (struct dri_context
*) context
;
542 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
543 struct dri_drawable
*pdraw
, *pread
;
545 pdraw
= (struct dri_drawable
*) driFetchDrawable(context
, draw
);
546 pread
= (struct dri_drawable
*) driFetchDrawable(context
, read
);
548 driReleaseDrawables(&pcp
->base
);
550 if (pdraw
== NULL
|| pread
== NULL
)
551 return GLXBadDrawable
;
553 if ((*psc
->core
->bindContext
) (pcp
->driContext
,
554 pdraw
->driDrawable
, pread
->driDrawable
))
557 return GLXBadContext
;
561 dri_unbind_context(struct glx_context
*context
, struct glx_context
*new)
563 struct dri_context
*pcp
= (struct dri_context
*) context
;
564 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
566 (*psc
->core
->unbindContext
) (pcp
->driContext
);
569 static const struct glx_context_vtable dri_context_vtable
= {
570 .destroy
= dri_destroy_context
,
571 .bind
= dri_bind_context
,
572 .unbind
= dri_unbind_context
,
575 .use_x_font
= DRI_glXUseXFont
,
576 .bind_tex_image
= NULL
,
577 .release_tex_image
= NULL
,
578 .get_proc_address
= NULL
,
581 static struct glx_context
*
582 dri_create_context(struct glx_screen
*base
,
583 struct glx_config
*config_base
,
584 struct glx_context
*shareList
, int renderType
)
586 struct dri_context
*pcp
, *pcp_shared
;
587 struct dri_screen
*psc
= (struct dri_screen
*) base
;
588 drm_context_t hwContext
;
589 __DRIcontext
*shared
= NULL
;
590 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) config_base
;
592 if (!psc
->base
.driScreen
)
595 /* Check the renderType value */
596 if (!validate_renderType_against_config(config_base
, renderType
))
600 /* If the shareList context is not a DRI context, we cannot possibly
601 * create a DRI context that shares it.
603 if (shareList
->vtable
->destroy
!= dri_destroy_context
) {
607 pcp_shared
= (struct dri_context
*) shareList
;
608 shared
= pcp_shared
->driContext
;
611 pcp
= calloc(1, sizeof *pcp
);
615 if (!glx_context_init(&pcp
->base
, &psc
->base
, &config
->base
)) {
620 pcp
->base
.renderType
= renderType
;
622 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
623 config
->base
.visualID
,
624 &pcp
->hwContextID
, &hwContext
)) {
630 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
632 renderType
, shared
, hwContext
, pcp
);
633 if (pcp
->driContext
== NULL
) {
634 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
639 pcp
->base
.vtable
= &dri_context_vtable
;
645 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
647 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
648 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
650 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
651 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
655 static __GLXDRIdrawable
*
656 driCreateDrawable(struct glx_screen
*base
,
658 GLXDrawable drawable
, struct glx_config
*config_base
)
660 drm_drawable_t hwDrawable
;
661 void *empty_attribute_list
= NULL
;
662 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) config_base
;
663 struct dri_screen
*psc
= (struct dri_screen
*) base
;
664 struct dri_drawable
*pdp
;
666 /* Old dri can't handle GLX 1.3+ drawable constructors. */
667 if (xDrawable
!= drawable
)
670 pdp
= calloc(1, sizeof *pdp
);
674 pdp
->base
.drawable
= drawable
;
675 pdp
->base
.psc
= &psc
->base
;
677 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
678 drawable
, &hwDrawable
)) {
683 /* Create a new drawable */
685 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
689 empty_attribute_list
, pdp
);
691 if (!pdp
->driDrawable
) {
692 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
697 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
703 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
704 int64_t unused3
, Bool flush
)
706 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
707 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
713 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
718 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
719 int x
, int y
, int width
, int height
, Bool flush
)
721 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
722 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
728 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
729 x
, y
, width
, height
);
733 driDestroyScreen(struct glx_screen
*base
)
735 struct dri_screen
*psc
= (struct dri_screen
*) base
;
737 /* Free the direct rendering per screen data */
739 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
740 driDestroyConfigs(psc
->driver_configs
);
741 psc
->driScreen
= NULL
;
743 dlclose(psc
->driver
);
747 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
749 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
752 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
754 if (psc
->swapControl
!= NULL
) {
755 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
759 return GLX_BAD_CONTEXT
;
763 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
765 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
768 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
770 if (psc
->swapControl
!= NULL
)
771 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
776 /* Bind DRI1 specific extensions */
778 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
782 for (i
= 0; extensions
[i
]; i
++) {
783 /* No DRI2 support for swap_control at the moment, since SwapBuffers
784 * is done by the X server */
785 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
786 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
787 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
788 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
791 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
792 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
793 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
796 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
797 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
798 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
801 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
802 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
804 /* Ignore unknown extensions */
808 static const struct glx_screen_vtable dri_screen_vtable
= {
809 .create_context
= dri_create_context
,
810 .create_context_attribs
= NULL
,
811 .query_renderer_integer
= NULL
,
812 .query_renderer_string
= NULL
,
815 static struct glx_screen
*
816 driCreateScreen(int screen
, struct glx_display
*priv
)
818 struct dri_display
*pdp
;
820 const __DRIextension
**extensions
;
821 struct dri_screen
*psc
;
825 psc
= calloc(1, sizeof *psc
);
829 if (!glx_screen_init(&psc
->base
, screen
, priv
)) {
834 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
838 psc
->driver
= driOpenDriver(driverName
);
839 if (psc
->driver
== NULL
)
842 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
843 if (extensions
== NULL
) {
844 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
848 for (i
= 0; extensions
[i
]; i
++) {
849 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
850 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
851 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
852 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
855 if (psc
->core
== NULL
|| psc
->legacy
== NULL
)
858 pdp
= (struct dri_display
*) priv
->driDisplay
;
860 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
861 if (psc
->driScreen
== NULL
)
864 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
865 driBindExtensions(psc
, extensions
);
867 psc
->base
.vtable
= &dri_screen_vtable
;
869 psc
->base
.driScreen
= psp
;
870 if (psc
->driCopySubBuffer
)
871 psp
->copySubBuffer
= driCopySubBuffer
;
873 psp
->destroyScreen
= driDestroyScreen
;
874 psp
->createDrawable
= driCreateDrawable
;
875 psp
->swapBuffers
= driSwapBuffers
;
877 psp
->setSwapInterval
= driSetSwapInterval
;
878 psp
->getSwapInterval
= driGetSwapInterval
;
885 CriticalErrorMessageF("failed to load driver: %s\n", driverName
);
890 dlclose(psc
->driver
);
891 glx_screen_cleanup(&psc
->base
);
897 /* Called from __glXFreeDisplayPrivate.
900 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
906 * Allocate, initialize and return a __DRIdisplayPrivate object.
907 * This is called from __glXInitialize() when we are given a new
910 _X_HIDDEN __GLXDRIdisplay
*
911 driCreateDisplay(Display
* dpy
)
913 struct dri_display
*pdpyp
;
914 int eventBase
, errorBase
;
915 int major
, minor
, patch
;
917 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
921 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
925 pdpyp
= malloc(sizeof *pdpyp
);
930 pdpyp
->driMajor
= major
;
931 pdpyp
->driMinor
= minor
;
932 pdpyp
->driPatch
= patch
;
934 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
935 pdpyp
->base
.createScreen
= driCreateScreen
;
940 #endif /* GLX_DIRECT_RENDERING */