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 __GLXscreenConfigs 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
;
81 __DRIcontext
*driContext
;
83 __GLXscreenConfigs
*psc
;
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. "r128", "tdfx", 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.
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.
182 glXGetDriverConfig(const char *driverName
)
184 void *handle
= driOpenDriver(driverName
);
186 return dlsym(handle
, "__driConfigOptions");
191 #ifdef XDAMAGE_1_1_INTERFACE
194 has_damage_post(Display
* dpy
)
196 static GLboolean inited
= GL_FALSE
;
197 static GLboolean has_damage
;
202 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
203 major
== 1 && minor
>= 1) {
204 has_damage
= GL_TRUE
;
207 has_damage
= GL_FALSE
;
216 __glXReportDamage(__DRIdrawable
* driDraw
,
218 drm_clip_rect_t
* rects
, int num_rects
,
219 GLboolean front_buffer
, void *loaderPrivate
)
222 XserverRegion region
;
225 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
226 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
227 Display
*dpy
= psc
->dpy
;
230 if (!has_damage_post(dpy
))
236 drawable
= RootWindow(dpy
, psc
->scr
);
241 drawable
= glxDraw
->xDrawable
;
244 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
248 for (i
= 0; i
< num_rects
; i
++) {
249 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
250 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
251 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
252 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
254 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
256 XDamageAdd(dpy
, drawable
, region
);
257 XFixesDestroyRegion(dpy
, region
);
260 static const __DRIdamageExtension damageExtension
= {
261 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
268 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
269 unsigned int *index
, unsigned int *stamp
,
270 int *X
, int *Y
, int *W
, int *H
,
271 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
272 int *backX
, int *backY
,
273 int *numBackClipRects
,
274 drm_clip_rect_t
** pBackClipRects
,
277 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
278 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
279 Display
*dpy
= psc
->dpy
;
281 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
282 index
, stamp
, X
, Y
, W
, H
,
283 numClipRects
, pClipRects
,
285 numBackClipRects
, pBackClipRects
);
288 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
289 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
290 __glXDRIGetDrawableInfo
293 static const __DRIextension
*loader_extensions
[] = {
294 &systemTimeExtension
.base
,
295 &getDrawableInfoExtension
.base
,
296 #ifdef XDAMAGE_1_1_INTERFACE
297 &damageExtension
.base
,
303 * Perform the required libGL-side initialization and call the client-side
304 * driver's \c __driCreateNewScreen function.
306 * \param dpy Display pointer.
307 * \param scrn Screen number on the display.
308 * \param psc DRI screen information.
309 * \param driDpy DRI display information.
310 * \param createNewScreen Pointer to the client-side driver's
311 * \c __driCreateNewScreen function.
312 * \returns A pointer to the \c __DRIscreen structure returned by
313 * the client-side driver on success, or \c NULL on failure.
316 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
317 struct dri_display
* driDpy
)
321 drmAddress pSAREA
= MAP_FAILED
;
323 __DRIversion ddx_version
;
324 __DRIversion dri_version
;
325 __DRIversion drm_version
;
326 __DRIframebuffer framebuffer
;
331 drmVersionPtr version
;
336 const __DRIconfig
**driver_configs
;
337 __GLcontextModes
*visual
;
339 /* DRI protocol version. */
340 dri_version
.major
= driDpy
->driMajor
;
341 dri_version
.minor
= driDpy
->driMinor
;
342 dri_version
.patch
= driDpy
->driPatch
;
344 framebuffer
.base
= MAP_FAILED
;
345 framebuffer
.dev_priv
= NULL
;
346 framebuffer
.size
= 0;
348 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
349 ErrorMessageF("XF86DRIOpenConnection failed\n");
353 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
355 Xfree(BusID
); /* No longer needed */
358 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
362 if (drmGetMagic(fd
, &magic
)) {
363 ErrorMessageF("drmGetMagic failed\n");
367 version
= drmGetVersion(fd
);
369 drm_version
.major
= version
->version_major
;
370 drm_version
.minor
= version
->version_minor
;
371 drm_version
.patch
= version
->version_patchlevel
;
372 drmFreeVersion(version
);
375 drm_version
.major
= -1;
376 drm_version
.minor
= -1;
377 drm_version
.patch
= -1;
380 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
381 ErrorMessageF("XF86DRIAuthConnection failed\n");
385 /* Get device name (like "tdfx") and the ddx version numbers.
386 * We'll check the version in each DRI driver's "createNewScreen"
388 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
391 &ddx_version
.patch
, &driverName
)) {
392 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
396 Xfree(driverName
); /* No longer needed. */
399 * Get device-specific info. pDevPriv will point to a struct
400 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
401 * has information about the screen size, depth, pitch, ancilliary
402 * buffers, DRM mmap handles, etc.
404 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
405 &framebuffer
.size
, &framebuffer
.stride
,
406 &framebuffer
.dev_priv_size
,
407 &framebuffer
.dev_priv
)) {
408 ErrorMessageF("XF86DRIGetDeviceInfo failed");
412 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
413 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
415 /* Map the framebuffer region. */
416 status
= drmMap(fd
, hFB
, framebuffer
.size
,
417 (drmAddressPtr
) & framebuffer
.base
);
419 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
423 /* Map the SAREA region. Further mmap regions may be setup in
424 * each DRI driver's "createNewScreen" function.
426 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
428 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
432 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
440 &driver_configs
, psc
);
443 ErrorMessageF("Calling driver entry point failed");
448 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
450 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
452 psc
->driver_configs
= driver_configs
;
454 /* Visuals with depth != screen depth are subject to automatic compositing
455 * in the X server, so DRI1 can't render to them properly. Mark them as
456 * non-conformant to prevent apps from picking them up accidentally.
458 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
459 XVisualInfo
template;
460 XVisualInfo
*visuals
;
464 template.visualid
= visual
->visualID
;
466 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
469 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
470 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
479 if (pSAREA
!= MAP_FAILED
)
480 drmUnmap(pSAREA
, SAREA_MAX
);
482 if (framebuffer
.base
!= MAP_FAILED
)
483 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
485 if (framebuffer
.dev_priv
!= NULL
)
486 Xfree(framebuffer
.dev_priv
);
491 XF86DRICloseConnection(dpy
, scrn
);
493 ErrorMessageF("reverting to software direct rendering\n");
499 driDestroyContext(__GLXDRIcontext
* context
,
500 __GLXscreenConfigs
*base
, Display
* dpy
)
502 struct dri_context
*pcp
= (struct dri_context
*) context
;
503 struct dri_screen
*psc
= (struct dri_screen
*) base
;
505 (*psc
->core
->destroyContext
) (pcp
->driContext
);
507 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
512 driBindContext(__GLXDRIcontext
*context
,
513 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
515 struct dri_context
*pcp
= (struct dri_context
*) context
;
516 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
517 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
518 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
520 return (*psc
->core
->bindContext
) (pcp
->driContext
,
521 pdr
->driDrawable
, prd
->driDrawable
);
525 driUnbindContext(__GLXDRIcontext
* context
)
527 struct dri_context
*pcp
= (struct dri_context
*) context
;
528 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
530 (*psc
->core
->unbindContext
) (pcp
->driContext
);
533 static __GLXDRIcontext
*
534 driCreateContext(__GLXscreenConfigs
*base
,
535 const __GLcontextModes
* mode
,
536 GLXContext gc
, GLXContext shareList
, int renderType
)
538 struct dri_context
*pcp
, *pcp_shared
;
539 struct dri_screen
*psc
= (struct dri_screen
*) base
;
540 drm_context_t hwContext
;
541 __DRIcontext
*shared
= NULL
;
542 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
544 if (!psc
->base
.driScreen
)
548 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
549 shared
= pcp_shared
->driContext
;
552 pcp
= Xmalloc(sizeof *pcp
);
556 pcp
->psc
= &psc
->base
;
557 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
559 &pcp
->hwContextID
, &hwContext
)) {
565 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
567 renderType
, shared
, hwContext
, pcp
);
568 if (pcp
->driContext
== NULL
) {
569 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
574 pcp
->base
.destroyContext
= driDestroyContext
;
575 pcp
->base
.bindContext
= driBindContext
;
576 pcp
->base
.unbindContext
= driUnbindContext
;
582 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
584 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
585 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
587 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
588 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
592 static __GLXDRIdrawable
*
593 driCreateDrawable(__GLXscreenConfigs
*base
,
595 GLXDrawable drawable
, const __GLcontextModes
* modes
)
597 drm_drawable_t hwDrawable
;
598 void *empty_attribute_list
= NULL
;
599 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
600 struct dri_screen
*psc
= (struct dri_screen
*) base
;
601 struct dri_drawable
*pdp
;
603 /* Old dri can't handle GLX 1.3+ drawable constructors. */
604 if (xDrawable
!= drawable
)
607 pdp
= Xmalloc(sizeof *pdp
);
611 pdp
->base
.drawable
= drawable
;
612 pdp
->base
.psc
= &psc
->base
;
614 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
615 drawable
, &hwDrawable
)) {
620 /* Create a new drawable */
622 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
626 empty_attribute_list
, pdp
);
628 if (!pdp
->driDrawable
) {
629 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
634 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
640 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
643 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
644 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
646 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
651 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
652 int x
, int y
, int width
, int height
)
654 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
656 (*pdp
->base
.psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
657 x
, y
, width
, height
);
661 driDestroyScreen(__GLXscreenConfigs
*base
)
663 struct dri_screen
*psc
= (struct dri_screen
*) base
;
665 /* Free the direct rendering per screen data */
667 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
668 driDestroyConfigs(psc
->driver_configs
);
669 psc
->driScreen
= NULL
;
671 dlclose(psc
->driver
);
674 static const struct glx_context_vtable dri_context_vtable
= {
679 #ifdef __DRI_SWAP_BUFFER_COUNTER
682 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
683 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
685 struct dri_screen
*psc
= (struct dri_screen
*) base
;
686 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
688 if (pdp
&& psc
->sbc
&& psc
->msc
)
689 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
690 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
691 __glXGetUST(ust
) == 0 );
695 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
696 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
698 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
699 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
701 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
702 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
703 divisor
, remainder
, msc
, sbc
);
705 /* __glXGetUST returns zero on success and non-zero on failure.
706 * This function returns True on success and False on failure.
708 return ret
== 0 && __glXGetUST(ust
) == 0;
713 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
714 int64_t *msc
, int64_t *sbc
)
716 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
718 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
720 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
722 /* __glXGetUST returns zero on success and non-zero on failure.
723 * This function returns True on success and False on failure.
725 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
728 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
729 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
735 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
737 GLXContext gc
= __glXGetCurrentContext();
738 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
739 struct dri_screen
*psc
;
741 if (gc
->driContext
) {
742 psc
= (struct dri_screen
*) pdraw
->psc
;
744 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
745 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
750 return GLX_BAD_CONTEXT
;
754 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
756 GLXContext gc
= __glXGetCurrentContext();
757 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
758 struct dri_screen
*psc
;
760 if (gc
!= NULL
&& gc
->driContext
) {
761 psc
= (struct dri_screen
*) pdraw
->psc
;
763 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
764 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
771 /* Bind DRI1 specific extensions */
773 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
777 for (i
= 0; extensions
[i
]; i
++) {
778 /* No DRI2 support for swap_control at the moment, since SwapBuffers
779 * is done by the X server */
780 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
781 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
782 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
783 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
786 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
787 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
788 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
791 /* Ignore unknown extensions */
795 static __GLXscreenConfigs
*
796 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
798 struct dri_display
*pdp
;
800 const __DRIextension
**extensions
;
801 struct dri_screen
*psc
;
805 psc
= Xcalloc(1, sizeof *psc
);
809 memset(psc
, 0, sizeof *psc
);
810 if (!glx_screen_init(&psc
->base
, screen
, priv
))
813 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
818 psc
->driver
= driOpenDriver(driverName
);
820 if (psc
->driver
== NULL
) {
825 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
826 if (extensions
== NULL
) {
827 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
832 for (i
= 0; extensions
[i
]; i
++) {
833 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
834 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
835 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
836 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
839 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
844 pdp
= (struct dri_display
*) priv
->driDisplay
;
846 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
847 if (psc
->driScreen
== NULL
) {
848 dlclose(psc
->driver
);
853 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
854 driBindExtensions(psc
, extensions
);
855 driBindCommonExtensions(&psc
->base
, extensions
);
858 psc
->base
.driScreen
= psp
;
859 if (psc
->base
.driCopySubBuffer
)
860 psp
->copySubBuffer
= driCopySubBuffer
;
862 psp
->destroyScreen
= driDestroyScreen
;
863 psp
->createContext
= driCreateContext
;
864 psp
->createDrawable
= driCreateDrawable
;
865 psp
->swapBuffers
= driSwapBuffers
;
869 #ifdef __DRI_SWAP_BUFFER_COUNTER
870 psp
->getDrawableMSC
= driDrawableGetMSC
;
871 psp
->waitForMSC
= driWaitForMSC
;
872 psp
->waitForSBC
= driWaitForSBC
;
875 psp
->setSwapInterval
= driSetSwapInterval
;
876 psp
->getSwapInterval
= driGetSwapInterval
;
878 psc
->base
.direct_context_vtable
= &dri_context_vtable
;
883 /* Called from __glXFreeDisplayPrivate.
886 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
892 * Allocate, initialize and return a __DRIdisplayPrivate object.
893 * This is called from __glXInitialize() when we are given a new
896 _X_HIDDEN __GLXDRIdisplay
*
897 driCreateDisplay(Display
* dpy
)
899 struct dri_display
*pdpyp
;
900 int eventBase
, errorBase
;
901 int major
, minor
, patch
;
903 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
907 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
911 pdpyp
= Xmalloc(sizeof *pdpyp
);
916 pdpyp
->driMajor
= major
;
917 pdpyp
->driMinor
= minor
;
918 pdpyp
->driPatch
= patch
;
920 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
921 pdpyp
->base
.createScreen
= driCreateScreen
;
926 #endif /* GLX_DIRECT_RENDERING */