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 _GLX_PUBLIC
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 _GLX_PUBLIC
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");
203 has_damage_post(Display
* dpy
)
205 static GLboolean inited
= GL_FALSE
;
206 static GLboolean has_damage
;
211 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
212 major
== 1 && minor
>= 1) {
213 has_damage
= GL_TRUE
;
216 has_damage
= GL_FALSE
;
225 __glXReportDamage(__DRIdrawable
* driDraw
,
227 drm_clip_rect_t
* rects
, int num_rects
,
228 GLboolean front_buffer
, void *loaderPrivate
)
231 XserverRegion region
;
234 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
235 struct glx_screen
*psc
= glxDraw
->psc
;
236 Display
*dpy
= psc
->dpy
;
239 if (!has_damage_post(dpy
))
245 drawable
= RootWindow(dpy
, psc
->scr
);
250 drawable
= glxDraw
->xDrawable
;
253 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
257 for (i
= 0; i
< num_rects
; i
++) {
258 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
259 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
260 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
261 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
263 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
265 XDamageAdd(dpy
, drawable
, region
);
266 XFixesDestroyRegion(dpy
, region
);
269 static const __DRIdamageExtension damageExtension
= {
270 .base
= {__DRI_DAMAGE
, 1 },
272 .reportDamage
= __glXReportDamage
,
276 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
277 unsigned int *index
, unsigned int *stamp
,
278 int *X
, int *Y
, int *W
, int *H
,
279 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
280 int *backX
, int *backY
,
281 int *numBackClipRects
,
282 drm_clip_rect_t
** pBackClipRects
,
285 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
286 struct glx_screen
*psc
= glxDraw
->psc
;
287 Display
*dpy
= psc
->dpy
;
289 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
290 index
, stamp
, X
, Y
, W
, H
,
291 numClipRects
, pClipRects
,
293 numBackClipRects
, pBackClipRects
);
296 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
297 .base
= {__DRI_GET_DRAWABLE_INFO
, 1 },
299 .getDrawableInfo
= __glXDRIGetDrawableInfo
302 static const __DRIextension
*loader_extensions
[] = {
303 &systemTimeExtension
.base
,
304 &getDrawableInfoExtension
.base
,
305 #ifdef XDAMAGE_1_1_INTERFACE
306 &damageExtension
.base
,
312 * Perform the required libGL-side initialization and call the client-side
313 * driver's \c __driCreateNewScreen function.
315 * \param dpy Display pointer.
316 * \param scrn Screen number on the display.
317 * \param psc DRI screen information.
318 * \param driDpy DRI display information.
319 * \param createNewScreen Pointer to the client-side driver's
320 * \c __driCreateNewScreen function.
321 * \returns A pointer to the \c __DRIscreen structure returned by
322 * the client-side driver on success, or \c NULL on failure.
325 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
326 struct dri_display
* driDpy
)
330 drmAddress pSAREA
= MAP_FAILED
;
332 __DRIversion ddx_version
;
333 __DRIversion dri_version
;
334 __DRIversion drm_version
;
335 __DRIframebuffer framebuffer
;
340 drmVersionPtr version
;
345 const __DRIconfig
**driver_configs
;
346 struct glx_config
*visual
, *configs
= NULL
, *visuals
= NULL
;
348 /* DRI protocol version. */
349 dri_version
.major
= driDpy
->driMajor
;
350 dri_version
.minor
= driDpy
->driMinor
;
351 dri_version
.patch
= driDpy
->driPatch
;
353 framebuffer
.base
= MAP_FAILED
;
354 framebuffer
.dev_priv
= NULL
;
355 framebuffer
.size
= 0;
357 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
358 ErrorMessageF("XF86DRIOpenConnection failed\n");
362 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
364 free(BusID
); /* No longer needed */
367 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
371 if (drmGetMagic(fd
, &magic
)) {
372 ErrorMessageF("drmGetMagic failed\n");
376 version
= drmGetVersion(fd
);
378 drm_version
.major
= version
->version_major
;
379 drm_version
.minor
= version
->version_minor
;
380 drm_version
.patch
= version
->version_patchlevel
;
381 drmFreeVersion(version
);
384 drm_version
.major
= -1;
385 drm_version
.minor
= -1;
386 drm_version
.patch
= -1;
389 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
390 ErrorMessageF("XF86DRIAuthConnection failed\n");
394 /* Get device name (like "radeon") and the ddx version numbers.
395 * We'll check the version in each DRI driver's "createNewScreen"
397 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
400 &ddx_version
.patch
, &driverName
)) {
401 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
405 free(driverName
); /* No longer needed. */
408 * Get device-specific info. pDevPriv will point to a struct
409 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
410 * has information about the screen size, depth, pitch, ancilliary
411 * buffers, DRM mmap handles, etc.
413 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
414 &framebuffer
.size
, &framebuffer
.stride
,
415 &framebuffer
.dev_priv_size
,
416 &framebuffer
.dev_priv
)) {
417 ErrorMessageF("XF86DRIGetDeviceInfo failed\n");
421 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
422 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
424 /* Map the framebuffer region. */
425 status
= drmMap(fd
, hFB
, framebuffer
.size
,
426 (drmAddressPtr
) & framebuffer
.base
);
428 ErrorMessageF("drmMap of framebuffer failed (%s)\n", strerror(-status
));
432 /* Map the SAREA region. Further mmap regions may be setup in
433 * each DRI driver's "createNewScreen" function.
435 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
437 ErrorMessageF("drmMap of SAREA failed (%s)\n", strerror(-status
));
441 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
449 &driver_configs
, psc
);
452 ErrorMessageF("Calling driver entry point failed\n");
456 configs
= driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
457 visuals
= driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
459 if (!configs
|| !visuals
) {
460 ErrorMessageF("No matching fbConfigs or visuals found\n");
464 glx_config_destroy_list(psc
->base
.configs
);
465 psc
->base
.configs
= configs
;
466 glx_config_destroy_list(psc
->base
.visuals
);
467 psc
->base
.visuals
= visuals
;
469 psc
->driver_configs
= driver_configs
;
471 /* Visuals with depth != screen depth are subject to automatic compositing
472 * in the X server, so DRI1 can't render to them properly. Mark them as
473 * non-conformant to prevent apps from picking them up accidentally.
475 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
476 XVisualInfo
template;
477 XVisualInfo
*visuals
;
481 template.visualid
= visual
->visualID
;
483 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
486 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
487 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
497 glx_config_destroy_list(configs
);
499 glx_config_destroy_list(visuals
);
501 if (pSAREA
!= MAP_FAILED
)
502 drmUnmap(pSAREA
, SAREA_MAX
);
504 if (framebuffer
.base
!= MAP_FAILED
)
505 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
507 free(framebuffer
.dev_priv
);
512 XF86DRICloseConnection(dpy
, scrn
);
514 ErrorMessageF("reverting to software direct rendering\n");
520 dri_destroy_context(struct glx_context
* context
)
522 struct dri_context
*pcp
= (struct dri_context
*) context
;
523 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
525 driReleaseDrawables(&pcp
->base
);
527 free((char *) context
->extensions
);
529 (*psc
->core
->destroyContext
) (pcp
->driContext
);
531 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
536 dri_bind_context(struct glx_context
*context
, struct glx_context
*old
,
537 GLXDrawable draw
, GLXDrawable read
)
539 struct dri_context
*pcp
= (struct dri_context
*) context
;
540 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
541 struct dri_drawable
*pdraw
, *pread
;
543 pdraw
= (struct dri_drawable
*) driFetchDrawable(context
, draw
);
544 pread
= (struct dri_drawable
*) driFetchDrawable(context
, read
);
546 driReleaseDrawables(&pcp
->base
);
548 if (pdraw
== NULL
|| pread
== NULL
)
549 return GLXBadDrawable
;
551 if ((*psc
->core
->bindContext
) (pcp
->driContext
,
552 pdraw
->driDrawable
, pread
->driDrawable
))
555 return GLXBadContext
;
559 dri_unbind_context(struct glx_context
*context
, struct glx_context
*new)
561 struct dri_context
*pcp
= (struct dri_context
*) context
;
562 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
564 (*psc
->core
->unbindContext
) (pcp
->driContext
);
567 static const struct glx_context_vtable dri_context_vtable
= {
568 .destroy
= dri_destroy_context
,
569 .bind
= dri_bind_context
,
570 .unbind
= dri_unbind_context
,
573 .use_x_font
= DRI_glXUseXFont
,
574 .bind_tex_image
= NULL
,
575 .release_tex_image
= NULL
,
576 .get_proc_address
= NULL
,
579 static struct glx_context
*
580 dri_create_context(struct glx_screen
*base
,
581 struct glx_config
*config_base
,
582 struct glx_context
*shareList
, int renderType
)
584 struct dri_context
*pcp
, *pcp_shared
;
585 struct dri_screen
*psc
= (struct dri_screen
*) base
;
586 drm_context_t hwContext
;
587 __DRIcontext
*shared
= NULL
;
588 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) config_base
;
590 if (!psc
->base
.driScreen
)
593 /* Check the renderType value */
594 if (!validate_renderType_against_config(config_base
, renderType
))
598 /* If the shareList context is not a DRI context, we cannot possibly
599 * create a DRI context that shares it.
601 if (shareList
->vtable
->destroy
!= dri_destroy_context
) {
605 pcp_shared
= (struct dri_context
*) shareList
;
606 shared
= pcp_shared
->driContext
;
609 pcp
= calloc(1, sizeof *pcp
);
613 if (!glx_context_init(&pcp
->base
, &psc
->base
, &config
->base
)) {
618 pcp
->base
.renderType
= renderType
;
620 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
621 config
->base
.visualID
,
622 &pcp
->hwContextID
, &hwContext
)) {
628 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
630 renderType
, shared
, hwContext
, pcp
);
631 if (pcp
->driContext
== NULL
) {
632 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
637 pcp
->base
.vtable
= &dri_context_vtable
;
643 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
645 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
646 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
648 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
649 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
653 static __GLXDRIdrawable
*
654 driCreateDrawable(struct glx_screen
*base
,
656 GLXDrawable drawable
, struct glx_config
*config_base
)
658 drm_drawable_t hwDrawable
;
659 void *empty_attribute_list
= NULL
;
660 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) config_base
;
661 struct dri_screen
*psc
= (struct dri_screen
*) base
;
662 struct dri_drawable
*pdp
;
664 /* Old dri can't handle GLX 1.3+ drawable constructors. */
665 if (xDrawable
!= drawable
)
668 pdp
= calloc(1, sizeof *pdp
);
672 pdp
->base
.drawable
= drawable
;
673 pdp
->base
.psc
= &psc
->base
;
675 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
676 drawable
, &hwDrawable
)) {
681 /* Create a new drawable */
683 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
687 empty_attribute_list
, pdp
);
689 if (!pdp
->driDrawable
) {
690 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
695 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
701 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
702 int64_t unused3
, Bool flush
)
704 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
705 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
711 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
716 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
717 int x
, int y
, int width
, int height
, Bool flush
)
719 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
720 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
726 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
727 x
, y
, width
, height
);
731 driDestroyScreen(struct glx_screen
*base
)
733 struct dri_screen
*psc
= (struct dri_screen
*) base
;
735 /* Free the direct rendering per screen data */
737 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
738 driDestroyConfigs(psc
->driver_configs
);
739 psc
->driScreen
= NULL
;
741 dlclose(psc
->driver
);
745 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
747 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
750 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
752 if (psc
->swapControl
!= NULL
) {
753 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
757 return GLX_BAD_CONTEXT
;
761 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
763 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
766 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
768 if (psc
->swapControl
!= NULL
)
769 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
774 /* Bind DRI1 specific extensions */
776 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
780 for (i
= 0; extensions
[i
]; i
++) {
781 /* No DRI2 support for swap_control at the moment, since SwapBuffers
782 * is done by the X server */
783 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
784 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
785 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
786 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
789 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
790 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
791 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
794 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
795 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
796 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
799 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
800 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
802 /* Ignore unknown extensions */
806 static const struct glx_screen_vtable dri_screen_vtable
= {
807 .create_context
= dri_create_context
,
808 .create_context_attribs
= NULL
,
809 .query_renderer_integer
= NULL
,
810 .query_renderer_string
= NULL
,
813 static struct glx_screen
*
814 driCreateScreen(int screen
, struct glx_display
*priv
)
816 struct dri_display
*pdp
;
818 const __DRIextension
**extensions
;
819 struct dri_screen
*psc
;
823 psc
= calloc(1, sizeof *psc
);
827 if (!glx_screen_init(&psc
->base
, screen
, priv
)) {
832 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
836 psc
->driver
= driOpenDriver(driverName
);
837 if (psc
->driver
== NULL
)
840 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
841 if (extensions
== NULL
) {
842 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
846 for (i
= 0; extensions
[i
]; i
++) {
847 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
848 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
849 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
850 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
853 if (psc
->core
== NULL
|| psc
->legacy
== NULL
)
856 pdp
= (struct dri_display
*) priv
->driDisplay
;
858 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
859 if (psc
->driScreen
== NULL
)
862 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
863 driBindExtensions(psc
, extensions
);
865 psc
->base
.vtable
= &dri_screen_vtable
;
867 psc
->base
.driScreen
= psp
;
868 if (psc
->driCopySubBuffer
)
869 psp
->copySubBuffer
= driCopySubBuffer
;
871 psp
->destroyScreen
= driDestroyScreen
;
872 psp
->createDrawable
= driCreateDrawable
;
873 psp
->swapBuffers
= driSwapBuffers
;
875 psp
->setSwapInterval
= driSetSwapInterval
;
876 psp
->getSwapInterval
= driGetSwapInterval
;
883 CriticalErrorMessageF("failed to load driver: %s\n", driverName
);
888 dlclose(psc
->driver
);
889 glx_screen_cleanup(&psc
->base
);
895 /* Called from __glXFreeDisplayPrivate.
898 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
904 * Allocate, initialize and return a __DRIdisplayPrivate object.
905 * This is called from __glXInitialize() when we are given a new
908 _X_HIDDEN __GLXDRIdisplay
*
909 driCreateDisplay(Display
* dpy
)
911 struct dri_display
*pdpyp
;
912 int eventBase
, errorBase
;
913 int major
, minor
, patch
;
915 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
919 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
923 pdpyp
= malloc(sizeof *pdpyp
);
928 pdpyp
->driMajor
= major
;
929 pdpyp
->driMinor
= minor
;
930 pdpyp
->driPatch
= patch
;
932 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
933 pdpyp
->base
.createScreen
= driCreateScreen
;
938 #endif /* GLX_DIRECT_RENDERING */