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
;
73 const __DRIcopySubBufferExtension
*driCopySubBuffer
;
82 __DRIcontext
*driContext
;
84 __GLXscreenConfigs
*psc
;
89 __GLXDRIdrawable base
;
91 __DRIdrawable
*driDrawable
;
95 * Given a display pointer and screen number, determine the name of
96 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
97 * Return True for success, False for failure.
100 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
105 int driverMajor
, driverMinor
, driverPatch
;
109 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
110 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
111 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
114 if (!directCapable
) {
115 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
119 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
120 &driverPatch
, driverName
);
122 ErrorMessageF("Cannot determine driver name for screen %d\n",
127 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
128 driverMajor
, driverMinor
, driverPatch
, *driverName
,
133 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
135 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
147 * Exported function for querying the DRI driver for a given screen.
149 * The returned char pointer points to a static array that will be
150 * overwritten by subsequent calls.
153 glXGetScreenDriver(Display
* dpy
, int scrNum
)
157 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
161 len
= strlen(driverName
);
164 memcpy(ret
, driverName
, len
+ 1);
172 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
174 * The returned char pointer points directly into the driver. Therefore
175 * it should be treated as a constant.
177 * If the driver was not found or does not support configuration NULL is
180 * Note: The driver remains opened after this function returns.
183 glXGetDriverConfig(const char *driverName
)
185 void *handle
= driOpenDriver(driverName
);
187 return dlsym(handle
, "__driConfigOptions");
192 #ifdef XDAMAGE_1_1_INTERFACE
195 has_damage_post(Display
* dpy
)
197 static GLboolean inited
= GL_FALSE
;
198 static GLboolean has_damage
;
203 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
204 major
== 1 && minor
>= 1) {
205 has_damage
= GL_TRUE
;
208 has_damage
= GL_FALSE
;
217 __glXReportDamage(__DRIdrawable
* driDraw
,
219 drm_clip_rect_t
* rects
, int num_rects
,
220 GLboolean front_buffer
, void *loaderPrivate
)
223 XserverRegion region
;
226 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
227 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
228 Display
*dpy
= psc
->dpy
;
231 if (!has_damage_post(dpy
))
237 drawable
= RootWindow(dpy
, psc
->scr
);
242 drawable
= glxDraw
->xDrawable
;
245 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
249 for (i
= 0; i
< num_rects
; i
++) {
250 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
251 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
252 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
253 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
255 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
257 XDamageAdd(dpy
, drawable
, region
);
258 XFixesDestroyRegion(dpy
, region
);
261 static const __DRIdamageExtension damageExtension
= {
262 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
269 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
270 unsigned int *index
, unsigned int *stamp
,
271 int *X
, int *Y
, int *W
, int *H
,
272 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
273 int *backX
, int *backY
,
274 int *numBackClipRects
,
275 drm_clip_rect_t
** pBackClipRects
,
278 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
279 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
280 Display
*dpy
= psc
->dpy
;
282 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
283 index
, stamp
, X
, Y
, W
, H
,
284 numClipRects
, pClipRects
,
286 numBackClipRects
, pBackClipRects
);
289 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
290 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
291 __glXDRIGetDrawableInfo
294 static const __DRIextension
*loader_extensions
[] = {
295 &systemTimeExtension
.base
,
296 &getDrawableInfoExtension
.base
,
297 #ifdef XDAMAGE_1_1_INTERFACE
298 &damageExtension
.base
,
304 * Perform the required libGL-side initialization and call the client-side
305 * driver's \c __driCreateNewScreen function.
307 * \param dpy Display pointer.
308 * \param scrn Screen number on the display.
309 * \param psc DRI screen information.
310 * \param driDpy DRI display information.
311 * \param createNewScreen Pointer to the client-side driver's
312 * \c __driCreateNewScreen function.
313 * \returns A pointer to the \c __DRIscreen structure returned by
314 * the client-side driver on success, or \c NULL on failure.
317 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
318 struct dri_display
* driDpy
)
322 drmAddress pSAREA
= MAP_FAILED
;
324 __DRIversion ddx_version
;
325 __DRIversion dri_version
;
326 __DRIversion drm_version
;
327 __DRIframebuffer framebuffer
;
332 drmVersionPtr version
;
337 const __DRIconfig
**driver_configs
;
338 __GLcontextModes
*visual
;
340 /* DRI protocol version. */
341 dri_version
.major
= driDpy
->driMajor
;
342 dri_version
.minor
= driDpy
->driMinor
;
343 dri_version
.patch
= driDpy
->driPatch
;
345 framebuffer
.base
= MAP_FAILED
;
346 framebuffer
.dev_priv
= NULL
;
347 framebuffer
.size
= 0;
349 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
350 ErrorMessageF("XF86DRIOpenConnection failed\n");
354 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
356 Xfree(BusID
); /* No longer needed */
359 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
363 if (drmGetMagic(fd
, &magic
)) {
364 ErrorMessageF("drmGetMagic failed\n");
368 version
= drmGetVersion(fd
);
370 drm_version
.major
= version
->version_major
;
371 drm_version
.minor
= version
->version_minor
;
372 drm_version
.patch
= version
->version_patchlevel
;
373 drmFreeVersion(version
);
376 drm_version
.major
= -1;
377 drm_version
.minor
= -1;
378 drm_version
.patch
= -1;
381 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
382 ErrorMessageF("XF86DRIAuthConnection failed\n");
386 /* Get device name (like "tdfx") and the ddx version numbers.
387 * We'll check the version in each DRI driver's "createNewScreen"
389 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
392 &ddx_version
.patch
, &driverName
)) {
393 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
397 Xfree(driverName
); /* No longer needed. */
400 * Get device-specific info. pDevPriv will point to a struct
401 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
402 * has information about the screen size, depth, pitch, ancilliary
403 * buffers, DRM mmap handles, etc.
405 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
406 &framebuffer
.size
, &framebuffer
.stride
,
407 &framebuffer
.dev_priv_size
,
408 &framebuffer
.dev_priv
)) {
409 ErrorMessageF("XF86DRIGetDeviceInfo failed");
413 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
414 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
416 /* Map the framebuffer region. */
417 status
= drmMap(fd
, hFB
, framebuffer
.size
,
418 (drmAddressPtr
) & framebuffer
.base
);
420 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
424 /* Map the SAREA region. Further mmap regions may be setup in
425 * each DRI driver's "createNewScreen" function.
427 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
429 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
433 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
441 &driver_configs
, psc
);
444 ErrorMessageF("Calling driver entry point failed");
449 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
451 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
453 psc
->driver_configs
= driver_configs
;
455 /* Visuals with depth != screen depth are subject to automatic compositing
456 * in the X server, so DRI1 can't render to them properly. Mark them as
457 * non-conformant to prevent apps from picking them up accidentally.
459 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
460 XVisualInfo
template;
461 XVisualInfo
*visuals
;
465 template.visualid
= visual
->visualID
;
467 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
470 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
471 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
480 if (pSAREA
!= MAP_FAILED
)
481 drmUnmap(pSAREA
, SAREA_MAX
);
483 if (framebuffer
.base
!= MAP_FAILED
)
484 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
486 if (framebuffer
.dev_priv
!= NULL
)
487 Xfree(framebuffer
.dev_priv
);
492 XF86DRICloseConnection(dpy
, scrn
);
494 ErrorMessageF("reverting to software direct rendering\n");
500 driDestroyContext(__GLXDRIcontext
* context
,
501 __GLXscreenConfigs
*base
, Display
* dpy
)
503 struct dri_context
*pcp
= (struct dri_context
*) context
;
504 struct dri_screen
*psc
= (struct dri_screen
*) base
;
506 (*psc
->core
->destroyContext
) (pcp
->driContext
);
508 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
513 driBindContext(__GLXDRIcontext
*context
,
514 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
516 struct dri_context
*pcp
= (struct dri_context
*) context
;
517 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
518 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
519 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
521 return (*psc
->core
->bindContext
) (pcp
->driContext
,
522 pdr
->driDrawable
, prd
->driDrawable
);
526 driUnbindContext(__GLXDRIcontext
* context
)
528 struct dri_context
*pcp
= (struct dri_context
*) context
;
529 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
531 (*psc
->core
->unbindContext
) (pcp
->driContext
);
534 static __GLXDRIcontext
*
535 driCreateContext(__GLXscreenConfigs
*base
,
536 const __GLcontextModes
* mode
,
537 GLXContext gc
, GLXContext shareList
, int renderType
)
539 struct dri_context
*pcp
, *pcp_shared
;
540 struct dri_screen
*psc
= (struct dri_screen
*) base
;
541 drm_context_t hwContext
;
542 __DRIcontext
*shared
= NULL
;
543 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
545 if (!psc
->base
.driScreen
)
549 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
550 shared
= pcp_shared
->driContext
;
553 pcp
= Xmalloc(sizeof *pcp
);
557 pcp
->psc
= &psc
->base
;
558 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
560 &pcp
->hwContextID
, &hwContext
)) {
566 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
568 renderType
, shared
, hwContext
, pcp
);
569 if (pcp
->driContext
== NULL
) {
570 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
575 pcp
->base
.destroyContext
= driDestroyContext
;
576 pcp
->base
.bindContext
= driBindContext
;
577 pcp
->base
.unbindContext
= driUnbindContext
;
583 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
585 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
586 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
588 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
589 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
593 static __GLXDRIdrawable
*
594 driCreateDrawable(__GLXscreenConfigs
*base
,
596 GLXDrawable drawable
, const __GLcontextModes
* modes
)
598 drm_drawable_t hwDrawable
;
599 void *empty_attribute_list
= NULL
;
600 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
601 struct dri_screen
*psc
= (struct dri_screen
*) base
;
602 struct dri_drawable
*pdp
;
604 /* Old dri can't handle GLX 1.3+ drawable constructors. */
605 if (xDrawable
!= drawable
)
608 pdp
= Xmalloc(sizeof *pdp
);
612 pdp
->base
.drawable
= drawable
;
613 pdp
->base
.psc
= &psc
->base
;
615 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
616 drawable
, &hwDrawable
)) {
621 /* Create a new drawable */
623 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
627 empty_attribute_list
, pdp
);
629 if (!pdp
->driDrawable
) {
630 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
635 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
641 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
644 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
645 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
647 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
652 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
653 int x
, int y
, int width
, int height
)
655 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
656 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
658 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
659 x
, y
, width
, height
);
663 driDestroyScreen(__GLXscreenConfigs
*base
)
665 struct dri_screen
*psc
= (struct dri_screen
*) base
;
667 /* Free the direct rendering per screen data */
669 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
670 driDestroyConfigs(psc
->driver_configs
);
671 psc
->driScreen
= NULL
;
673 dlclose(psc
->driver
);
676 static const struct glx_context_vtable dri_context_vtable
= {
681 #ifdef __DRI_SWAP_BUFFER_COUNTER
684 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
685 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
687 struct dri_screen
*psc
= (struct dri_screen
*) base
;
688 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
690 if (pdp
&& psc
->sbc
&& psc
->msc
)
691 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
692 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
693 __glXGetUST(ust
) == 0 );
697 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
698 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
700 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
701 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
703 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
704 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
705 divisor
, remainder
, msc
, sbc
);
707 /* __glXGetUST returns zero on success and non-zero on failure.
708 * This function returns True on success and False on failure.
710 return ret
== 0 && __glXGetUST(ust
) == 0;
715 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
716 int64_t *msc
, int64_t *sbc
)
718 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
720 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
722 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
724 /* __glXGetUST returns zero on success and non-zero on failure.
725 * This function returns True on success and False on failure.
727 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
730 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
731 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
737 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
739 GLXContext gc
= __glXGetCurrentContext();
740 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
741 struct dri_screen
*psc
;
743 if (gc
->driContext
) {
744 psc
= (struct dri_screen
*) pdraw
->psc
;
746 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
747 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
752 return GLX_BAD_CONTEXT
;
756 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
758 GLXContext gc
= __glXGetCurrentContext();
759 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
760 struct dri_screen
*psc
;
762 if (gc
!= NULL
&& gc
->driContext
) {
763 psc
= (struct dri_screen
*) pdraw
->psc
;
765 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
766 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
773 /* Bind DRI1 specific extensions */
775 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
779 for (i
= 0; extensions
[i
]; i
++) {
780 /* No DRI2 support for swap_control at the moment, since SwapBuffers
781 * is done by the X server */
782 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
783 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
784 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
785 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
788 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
789 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
790 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
793 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
794 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
795 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
798 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
799 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
801 /* Ignore unknown extensions */
805 static __GLXscreenConfigs
*
806 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
808 struct dri_display
*pdp
;
810 const __DRIextension
**extensions
;
811 struct dri_screen
*psc
;
815 psc
= Xcalloc(1, sizeof *psc
);
819 memset(psc
, 0, sizeof *psc
);
820 if (!glx_screen_init(&psc
->base
, screen
, priv
))
823 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
828 psc
->driver
= driOpenDriver(driverName
);
830 if (psc
->driver
== NULL
) {
835 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
836 if (extensions
== NULL
) {
837 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
842 for (i
= 0; extensions
[i
]; i
++) {
843 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
844 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
845 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
846 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
849 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
854 pdp
= (struct dri_display
*) priv
->driDisplay
;
856 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
857 if (psc
->driScreen
== NULL
) {
858 dlclose(psc
->driver
);
863 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
864 driBindExtensions(psc
, extensions
);
867 psc
->base
.driScreen
= psp
;
868 if (psc
->driCopySubBuffer
)
869 psp
->copySubBuffer
= driCopySubBuffer
;
871 psp
->destroyScreen
= driDestroyScreen
;
872 psp
->createContext
= driCreateContext
;
873 psp
->createDrawable
= driCreateDrawable
;
874 psp
->swapBuffers
= driSwapBuffers
;
878 #ifdef __DRI_SWAP_BUFFER_COUNTER
879 psp
->getDrawableMSC
= driDrawableGetMSC
;
880 psp
->waitForMSC
= driWaitForMSC
;
881 psp
->waitForSBC
= driWaitForSBC
;
884 psp
->setSwapInterval
= driSetSwapInterval
;
885 psp
->getSwapInterval
= driGetSwapInterval
;
887 psc
->base
.direct_context_vtable
= &dri_context_vtable
;
892 /* Called from __glXFreeDisplayPrivate.
895 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
901 * Allocate, initialize and return a __DRIdisplayPrivate object.
902 * This is called from __glXInitialize() when we are given a new
905 _X_HIDDEN __GLXDRIdisplay
*
906 driCreateDisplay(Display
* dpy
)
908 struct dri_display
*pdpyp
;
909 int eventBase
, errorBase
;
910 int major
, minor
, patch
;
912 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
916 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
920 pdpyp
= Xmalloc(sizeof *pdpyp
);
925 pdpyp
->driMajor
= major
;
926 pdpyp
->driMinor
= minor
;
927 pdpyp
->driPatch
= patch
;
929 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
930 pdpyp
->base
.createScreen
= driCreateScreen
;
935 #endif /* GLX_DIRECT_RENDERING */