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 __GLXDRIcontext dri_vtable
;
83 __DRIcontext
*driContext
;
85 __GLXscreenConfigs
*psc
;
90 __GLXDRIdrawable base
;
92 __DRIdrawable
*driDrawable
;
95 static const struct glx_context_vtable dri_context_vtable
;
98 * Given a display pointer and screen number, determine the name of
99 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
100 * Return True for success, False for failure.
103 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
108 int driverMajor
, driverMinor
, driverPatch
;
112 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
113 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
114 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
117 if (!directCapable
) {
118 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
122 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
123 &driverPatch
, driverName
);
125 ErrorMessageF("Cannot determine driver name for screen %d\n",
130 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
131 driverMajor
, driverMinor
, driverPatch
, *driverName
,
136 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
138 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
150 * Exported function for querying the DRI driver for a given screen.
152 * The returned char pointer points to a static array that will be
153 * overwritten by subsequent calls.
156 glXGetScreenDriver(Display
* dpy
, int scrNum
)
160 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
164 len
= strlen(driverName
);
167 memcpy(ret
, driverName
, len
+ 1);
175 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
177 * The returned char pointer points directly into the driver. Therefore
178 * it should be treated as a constant.
180 * If the driver was not found or does not support configuration NULL is
183 * Note: The driver remains opened after this function returns.
186 glXGetDriverConfig(const char *driverName
)
188 void *handle
= driOpenDriver(driverName
);
190 return dlsym(handle
, "__driConfigOptions");
195 #ifdef XDAMAGE_1_1_INTERFACE
198 has_damage_post(Display
* dpy
)
200 static GLboolean inited
= GL_FALSE
;
201 static GLboolean has_damage
;
206 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
207 major
== 1 && minor
>= 1) {
208 has_damage
= GL_TRUE
;
211 has_damage
= GL_FALSE
;
220 __glXReportDamage(__DRIdrawable
* driDraw
,
222 drm_clip_rect_t
* rects
, int num_rects
,
223 GLboolean front_buffer
, void *loaderPrivate
)
226 XserverRegion region
;
229 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
230 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
231 Display
*dpy
= psc
->dpy
;
234 if (!has_damage_post(dpy
))
240 drawable
= RootWindow(dpy
, psc
->scr
);
245 drawable
= glxDraw
->xDrawable
;
248 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
252 for (i
= 0; i
< num_rects
; i
++) {
253 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
254 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
255 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
256 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
258 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
260 XDamageAdd(dpy
, drawable
, region
);
261 XFixesDestroyRegion(dpy
, region
);
264 static const __DRIdamageExtension damageExtension
= {
265 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
272 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
273 unsigned int *index
, unsigned int *stamp
,
274 int *X
, int *Y
, int *W
, int *H
,
275 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
276 int *backX
, int *backY
,
277 int *numBackClipRects
,
278 drm_clip_rect_t
** pBackClipRects
,
281 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
282 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
283 Display
*dpy
= psc
->dpy
;
285 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
286 index
, stamp
, X
, Y
, W
, H
,
287 numClipRects
, pClipRects
,
289 numBackClipRects
, pBackClipRects
);
292 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
293 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
294 __glXDRIGetDrawableInfo
297 static const __DRIextension
*loader_extensions
[] = {
298 &systemTimeExtension
.base
,
299 &getDrawableInfoExtension
.base
,
300 #ifdef XDAMAGE_1_1_INTERFACE
301 &damageExtension
.base
,
307 * Perform the required libGL-side initialization and call the client-side
308 * driver's \c __driCreateNewScreen function.
310 * \param dpy Display pointer.
311 * \param scrn Screen number on the display.
312 * \param psc DRI screen information.
313 * \param driDpy DRI display information.
314 * \param createNewScreen Pointer to the client-side driver's
315 * \c __driCreateNewScreen function.
316 * \returns A pointer to the \c __DRIscreen structure returned by
317 * the client-side driver on success, or \c NULL on failure.
320 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
321 struct dri_display
* driDpy
)
325 drmAddress pSAREA
= MAP_FAILED
;
327 __DRIversion ddx_version
;
328 __DRIversion dri_version
;
329 __DRIversion drm_version
;
330 __DRIframebuffer framebuffer
;
335 drmVersionPtr version
;
340 const __DRIconfig
**driver_configs
;
341 __GLcontextModes
*visual
;
343 /* DRI protocol version. */
344 dri_version
.major
= driDpy
->driMajor
;
345 dri_version
.minor
= driDpy
->driMinor
;
346 dri_version
.patch
= driDpy
->driPatch
;
348 framebuffer
.base
= MAP_FAILED
;
349 framebuffer
.dev_priv
= NULL
;
350 framebuffer
.size
= 0;
352 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
353 ErrorMessageF("XF86DRIOpenConnection failed\n");
357 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
359 Xfree(BusID
); /* No longer needed */
362 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
366 if (drmGetMagic(fd
, &magic
)) {
367 ErrorMessageF("drmGetMagic failed\n");
371 version
= drmGetVersion(fd
);
373 drm_version
.major
= version
->version_major
;
374 drm_version
.minor
= version
->version_minor
;
375 drm_version
.patch
= version
->version_patchlevel
;
376 drmFreeVersion(version
);
379 drm_version
.major
= -1;
380 drm_version
.minor
= -1;
381 drm_version
.patch
= -1;
384 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
385 ErrorMessageF("XF86DRIAuthConnection failed\n");
389 /* Get device name (like "tdfx") and the ddx version numbers.
390 * We'll check the version in each DRI driver's "createNewScreen"
392 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
395 &ddx_version
.patch
, &driverName
)) {
396 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
400 Xfree(driverName
); /* No longer needed. */
403 * Get device-specific info. pDevPriv will point to a struct
404 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
405 * has information about the screen size, depth, pitch, ancilliary
406 * buffers, DRM mmap handles, etc.
408 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
409 &framebuffer
.size
, &framebuffer
.stride
,
410 &framebuffer
.dev_priv_size
,
411 &framebuffer
.dev_priv
)) {
412 ErrorMessageF("XF86DRIGetDeviceInfo failed");
416 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
417 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
419 /* Map the framebuffer region. */
420 status
= drmMap(fd
, hFB
, framebuffer
.size
,
421 (drmAddressPtr
) & framebuffer
.base
);
423 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
427 /* Map the SAREA region. Further mmap regions may be setup in
428 * each DRI driver's "createNewScreen" function.
430 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
432 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
436 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
444 &driver_configs
, psc
);
447 ErrorMessageF("Calling driver entry point failed");
452 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
454 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
456 psc
->driver_configs
= driver_configs
;
458 /* Visuals with depth != screen depth are subject to automatic compositing
459 * in the X server, so DRI1 can't render to them properly. Mark them as
460 * non-conformant to prevent apps from picking them up accidentally.
462 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
463 XVisualInfo
template;
464 XVisualInfo
*visuals
;
468 template.visualid
= visual
->visualID
;
470 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
473 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
474 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
483 if (pSAREA
!= MAP_FAILED
)
484 drmUnmap(pSAREA
, SAREA_MAX
);
486 if (framebuffer
.base
!= MAP_FAILED
)
487 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
489 if (framebuffer
.dev_priv
!= NULL
)
490 Xfree(framebuffer
.dev_priv
);
495 XF86DRICloseConnection(dpy
, scrn
);
497 ErrorMessageF("reverting to software direct rendering\n");
503 dri_destroy_context(__GLXcontext
* context
)
505 struct dri_context
*pcp
= (struct dri_context
*) context
;
506 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
509 glx_send_destroy_context(psc
->base
.dpy
, context
->xid
);
511 if (context
->extensions
)
512 XFree((char *) context
->extensions
);
514 GarbageCollectDRIDrawables(context
->psc
);
516 (*psc
->core
->destroyContext
) (pcp
->driContext
);
518 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
523 driBindContext(__GLXcontext
*context
,
524 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
526 struct dri_context
*pcp
= (struct dri_context
*) context
;
527 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
528 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
529 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
531 return (*psc
->core
->bindContext
) (pcp
->driContext
,
532 pdr
->driDrawable
, prd
->driDrawable
);
536 driUnbindContext(__GLXcontext
* context
)
538 struct dri_context
*pcp
= (struct dri_context
*) context
;
539 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
541 (*psc
->core
->unbindContext
) (pcp
->driContext
);
544 static const struct glx_context_vtable dri_context_vtable
= {
553 static __GLXcontext
*
554 dri_create_context(__GLXscreenConfigs
*base
,
555 const __GLcontextModes
*mode
,
556 GLXContext shareList
, int renderType
)
558 struct dri_context
*pcp
, *pcp_shared
;
559 struct dri_screen
*psc
= (struct dri_screen
*) base
;
560 drm_context_t hwContext
;
561 __DRIcontext
*shared
= NULL
;
562 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
564 if (!psc
->base
.driScreen
)
568 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
569 shared
= pcp_shared
->driContext
;
572 pcp
= Xmalloc(sizeof *pcp
);
576 memset(pcp
, 0, sizeof *pcp
);
577 if (!glx_context_init(&pcp
->base
, &psc
->base
, mode
)) {
582 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
584 &pcp
->hwContextID
, &hwContext
)) {
590 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
592 renderType
, shared
, hwContext
, pcp
);
593 if (pcp
->driContext
== NULL
) {
594 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
599 pcp
->base
.vtable
= &dri_context_vtable
;
600 pcp
->base
.driContext
= &pcp
->dri_vtable
;
601 pcp
->dri_vtable
.bindContext
= driBindContext
;
602 pcp
->dri_vtable
.unbindContext
= driUnbindContext
;
608 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
610 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
611 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
613 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
614 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
618 static __GLXDRIdrawable
*
619 driCreateDrawable(__GLXscreenConfigs
*base
,
621 GLXDrawable drawable
, const __GLcontextModes
* modes
)
623 drm_drawable_t hwDrawable
;
624 void *empty_attribute_list
= NULL
;
625 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
626 struct dri_screen
*psc
= (struct dri_screen
*) base
;
627 struct dri_drawable
*pdp
;
629 /* Old dri can't handle GLX 1.3+ drawable constructors. */
630 if (xDrawable
!= drawable
)
633 pdp
= Xmalloc(sizeof *pdp
);
637 memset(pdp
, 0, sizeof *pdp
);
638 pdp
->base
.drawable
= drawable
;
639 pdp
->base
.psc
= &psc
->base
;
641 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
642 drawable
, &hwDrawable
)) {
647 /* Create a new drawable */
649 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
653 empty_attribute_list
, pdp
);
655 if (!pdp
->driDrawable
) {
656 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
661 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
667 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
670 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
671 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
673 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
678 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
679 int x
, int y
, int width
, int height
)
681 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
682 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
684 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
685 x
, y
, width
, height
);
689 driDestroyScreen(__GLXscreenConfigs
*base
)
691 struct dri_screen
*psc
= (struct dri_screen
*) base
;
693 /* Free the direct rendering per screen data */
695 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
696 driDestroyConfigs(psc
->driver_configs
);
697 psc
->driScreen
= NULL
;
699 dlclose(psc
->driver
);
702 #ifdef __DRI_SWAP_BUFFER_COUNTER
705 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
706 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
708 struct dri_screen
*psc
= (struct dri_screen
*) base
;
709 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
711 if (pdp
&& psc
->sbc
&& psc
->msc
)
712 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
713 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
714 __glXGetUST(ust
) == 0 );
718 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
719 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
721 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
722 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
724 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
725 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
726 divisor
, remainder
, msc
, sbc
);
728 /* __glXGetUST returns zero on success and non-zero on failure.
729 * This function returns True on success and False on failure.
731 return ret
== 0 && __glXGetUST(ust
) == 0;
736 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
737 int64_t *msc
, int64_t *sbc
)
739 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
741 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
743 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
745 /* __glXGetUST returns zero on success and non-zero on failure.
746 * This function returns True on success and False on failure.
748 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
751 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
752 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
758 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
760 GLXContext gc
= __glXGetCurrentContext();
761 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
762 struct dri_screen
*psc
;
764 if (gc
->driContext
) {
765 psc
= (struct dri_screen
*) pdraw
->psc
;
767 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
768 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
773 return GLX_BAD_CONTEXT
;
777 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
779 GLXContext gc
= __glXGetCurrentContext();
780 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
781 struct dri_screen
*psc
;
783 if (gc
!= NULL
&& gc
->driContext
) {
784 psc
= (struct dri_screen
*) pdraw
->psc
;
786 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
787 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
794 /* Bind DRI1 specific extensions */
796 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
800 for (i
= 0; extensions
[i
]; i
++) {
801 /* No DRI2 support for swap_control at the moment, since SwapBuffers
802 * is done by the X server */
803 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
804 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
805 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
806 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
809 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
810 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
811 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
814 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
815 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
816 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
819 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
820 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
822 /* Ignore unknown extensions */
826 static const struct glx_screen_vtable dri_screen_vtable
= {
830 static __GLXscreenConfigs
*
831 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
833 struct dri_display
*pdp
;
835 const __DRIextension
**extensions
;
836 struct dri_screen
*psc
;
840 psc
= Xcalloc(1, sizeof *psc
);
844 memset(psc
, 0, sizeof *psc
);
845 if (!glx_screen_init(&psc
->base
, screen
, priv
))
848 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
853 psc
->driver
= driOpenDriver(driverName
);
855 if (psc
->driver
== NULL
) {
860 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
861 if (extensions
== NULL
) {
862 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
867 for (i
= 0; extensions
[i
]; i
++) {
868 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
869 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
870 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
871 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
874 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
879 pdp
= (struct dri_display
*) priv
->driDisplay
;
881 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
882 if (psc
->driScreen
== NULL
) {
883 dlclose(psc
->driver
);
888 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
889 driBindExtensions(psc
, extensions
);
891 psc
->base
.vtable
= &dri_screen_vtable
;
893 psc
->base
.driScreen
= psp
;
894 if (psc
->driCopySubBuffer
)
895 psp
->copySubBuffer
= driCopySubBuffer
;
897 psp
->destroyScreen
= driDestroyScreen
;
898 psp
->createDrawable
= driCreateDrawable
;
899 psp
->swapBuffers
= driSwapBuffers
;
901 #ifdef __DRI_SWAP_BUFFER_COUNTER
902 psp
->getDrawableMSC
= driDrawableGetMSC
;
903 psp
->waitForMSC
= driWaitForMSC
;
904 psp
->waitForSBC
= driWaitForSBC
;
907 psp
->setSwapInterval
= driSetSwapInterval
;
908 psp
->getSwapInterval
= driGetSwapInterval
;
913 /* Called from __glXFreeDisplayPrivate.
916 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
922 * Allocate, initialize and return a __DRIdisplayPrivate object.
923 * This is called from __glXInitialize() when we are given a new
926 _X_HIDDEN __GLXDRIdisplay
*
927 driCreateDisplay(Display
* dpy
)
929 struct dri_display
*pdpyp
;
930 int eventBase
, errorBase
;
931 int major
, minor
, patch
;
933 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
937 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
941 pdpyp
= Xmalloc(sizeof *pdpyp
);
946 pdpyp
->driMajor
= major
;
947 pdpyp
->driMinor
= minor
;
948 pdpyp
->driPatch
= patch
;
950 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
951 pdpyp
->base
.createScreen
= driCreateScreen
;
956 #endif /* GLX_DIRECT_RENDERING */