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
;
89 __GLXDRIdrawable base
;
91 __DRIdrawable
*driDrawable
;
94 static const struct glx_context_vtable dri_context_vtable
;
97 * Given a display pointer and screen number, determine the name of
98 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
99 * Return True for success, False for failure.
102 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
107 int driverMajor
, driverMinor
, driverPatch
;
111 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
112 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
113 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
116 if (!directCapable
) {
117 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
121 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
122 &driverPatch
, driverName
);
124 ErrorMessageF("Cannot determine driver name for screen %d\n",
129 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
130 driverMajor
, driverMinor
, driverPatch
, *driverName
,
135 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
137 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
149 * Exported function for querying the DRI driver for a given screen.
151 * The returned char pointer points to a static array that will be
152 * overwritten by subsequent calls.
155 glXGetScreenDriver(Display
* dpy
, int scrNum
)
159 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
163 len
= strlen(driverName
);
166 memcpy(ret
, driverName
, len
+ 1);
174 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
176 * The returned char pointer points directly into the driver. Therefore
177 * it should be treated as a constant.
179 * If the driver was not found or does not support configuration NULL is
182 * Note: The driver remains opened after this function returns.
185 glXGetDriverConfig(const char *driverName
)
187 void *handle
= driOpenDriver(driverName
);
189 return dlsym(handle
, "__driConfigOptions");
194 #ifdef XDAMAGE_1_1_INTERFACE
197 has_damage_post(Display
* dpy
)
199 static GLboolean inited
= GL_FALSE
;
200 static GLboolean has_damage
;
205 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
206 major
== 1 && minor
>= 1) {
207 has_damage
= GL_TRUE
;
210 has_damage
= GL_FALSE
;
219 __glXReportDamage(__DRIdrawable
* driDraw
,
221 drm_clip_rect_t
* rects
, int num_rects
,
222 GLboolean front_buffer
, void *loaderPrivate
)
225 XserverRegion region
;
228 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
229 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
230 Display
*dpy
= psc
->dpy
;
233 if (!has_damage_post(dpy
))
239 drawable
= RootWindow(dpy
, psc
->scr
);
244 drawable
= glxDraw
->xDrawable
;
247 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
251 for (i
= 0; i
< num_rects
; i
++) {
252 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
253 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
254 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
255 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
257 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
259 XDamageAdd(dpy
, drawable
, region
);
260 XFixesDestroyRegion(dpy
, region
);
263 static const __DRIdamageExtension damageExtension
= {
264 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
271 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
272 unsigned int *index
, unsigned int *stamp
,
273 int *X
, int *Y
, int *W
, int *H
,
274 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
275 int *backX
, int *backY
,
276 int *numBackClipRects
,
277 drm_clip_rect_t
** pBackClipRects
,
280 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
281 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
282 Display
*dpy
= psc
->dpy
;
284 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
285 index
, stamp
, X
, Y
, W
, H
,
286 numClipRects
, pClipRects
,
288 numBackClipRects
, pBackClipRects
);
291 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
292 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
293 __glXDRIGetDrawableInfo
296 static const __DRIextension
*loader_extensions
[] = {
297 &systemTimeExtension
.base
,
298 &getDrawableInfoExtension
.base
,
299 #ifdef XDAMAGE_1_1_INTERFACE
300 &damageExtension
.base
,
306 * Perform the required libGL-side initialization and call the client-side
307 * driver's \c __driCreateNewScreen function.
309 * \param dpy Display pointer.
310 * \param scrn Screen number on the display.
311 * \param psc DRI screen information.
312 * \param driDpy DRI display information.
313 * \param createNewScreen Pointer to the client-side driver's
314 * \c __driCreateNewScreen function.
315 * \returns A pointer to the \c __DRIscreen structure returned by
316 * the client-side driver on success, or \c NULL on failure.
319 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
320 struct dri_display
* driDpy
)
324 drmAddress pSAREA
= MAP_FAILED
;
326 __DRIversion ddx_version
;
327 __DRIversion dri_version
;
328 __DRIversion drm_version
;
329 __DRIframebuffer framebuffer
;
334 drmVersionPtr version
;
339 const __DRIconfig
**driver_configs
;
340 __GLcontextModes
*visual
;
342 /* DRI protocol version. */
343 dri_version
.major
= driDpy
->driMajor
;
344 dri_version
.minor
= driDpy
->driMinor
;
345 dri_version
.patch
= driDpy
->driPatch
;
347 framebuffer
.base
= MAP_FAILED
;
348 framebuffer
.dev_priv
= NULL
;
349 framebuffer
.size
= 0;
351 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
352 ErrorMessageF("XF86DRIOpenConnection failed\n");
356 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
358 Xfree(BusID
); /* No longer needed */
361 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
365 if (drmGetMagic(fd
, &magic
)) {
366 ErrorMessageF("drmGetMagic failed\n");
370 version
= drmGetVersion(fd
);
372 drm_version
.major
= version
->version_major
;
373 drm_version
.minor
= version
->version_minor
;
374 drm_version
.patch
= version
->version_patchlevel
;
375 drmFreeVersion(version
);
378 drm_version
.major
= -1;
379 drm_version
.minor
= -1;
380 drm_version
.patch
= -1;
383 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
384 ErrorMessageF("XF86DRIAuthConnection failed\n");
388 /* Get device name (like "tdfx") and the ddx version numbers.
389 * We'll check the version in each DRI driver's "createNewScreen"
391 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
394 &ddx_version
.patch
, &driverName
)) {
395 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
399 Xfree(driverName
); /* No longer needed. */
402 * Get device-specific info. pDevPriv will point to a struct
403 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
404 * has information about the screen size, depth, pitch, ancilliary
405 * buffers, DRM mmap handles, etc.
407 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
408 &framebuffer
.size
, &framebuffer
.stride
,
409 &framebuffer
.dev_priv_size
,
410 &framebuffer
.dev_priv
)) {
411 ErrorMessageF("XF86DRIGetDeviceInfo failed");
415 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
416 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
418 /* Map the framebuffer region. */
419 status
= drmMap(fd
, hFB
, framebuffer
.size
,
420 (drmAddressPtr
) & framebuffer
.base
);
422 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
426 /* Map the SAREA region. Further mmap regions may be setup in
427 * each DRI driver's "createNewScreen" function.
429 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
431 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
435 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
443 &driver_configs
, psc
);
446 ErrorMessageF("Calling driver entry point failed");
451 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
453 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
455 psc
->driver_configs
= driver_configs
;
457 /* Visuals with depth != screen depth are subject to automatic compositing
458 * in the X server, so DRI1 can't render to them properly. Mark them as
459 * non-conformant to prevent apps from picking them up accidentally.
461 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
462 XVisualInfo
template;
463 XVisualInfo
*visuals
;
467 template.visualid
= visual
->visualID
;
469 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
472 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
473 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
482 if (pSAREA
!= MAP_FAILED
)
483 drmUnmap(pSAREA
, SAREA_MAX
);
485 if (framebuffer
.base
!= MAP_FAILED
)
486 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
488 if (framebuffer
.dev_priv
!= NULL
)
489 Xfree(framebuffer
.dev_priv
);
494 XF86DRICloseConnection(dpy
, scrn
);
496 ErrorMessageF("reverting to software direct rendering\n");
502 dri_destroy_context(__GLXcontext
* context
)
504 struct dri_context
*pcp
= (struct dri_context
*) context
;
505 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
508 glx_send_destroy_context(psc
->base
.dpy
, context
->xid
);
510 if (context
->extensions
)
511 XFree((char *) context
->extensions
);
513 GarbageCollectDRIDrawables(context
->psc
);
515 (*psc
->core
->destroyContext
) (pcp
->driContext
);
517 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
522 driBindContext(__GLXcontext
*context
,
523 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
525 struct dri_context
*pcp
= (struct dri_context
*) context
;
526 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
527 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
528 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
530 return (*psc
->core
->bindContext
) (pcp
->driContext
,
531 pdr
->driDrawable
, prd
->driDrawable
);
535 driUnbindContext(__GLXcontext
* context
)
537 struct dri_context
*pcp
= (struct dri_context
*) context
;
538 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->base
.psc
;
540 (*psc
->core
->unbindContext
) (pcp
->driContext
);
543 static const struct glx_context_vtable dri_context_vtable
= {
552 static __GLXcontext
*
553 dri_create_context(__GLXscreenConfigs
*base
,
554 const __GLcontextModes
*mode
,
555 GLXContext shareList
, int renderType
)
557 struct dri_context
*pcp
, *pcp_shared
;
558 struct dri_screen
*psc
= (struct dri_screen
*) base
;
559 drm_context_t hwContext
;
560 __DRIcontext
*shared
= NULL
;
561 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
563 if (!psc
->base
.driScreen
)
567 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
568 shared
= pcp_shared
->driContext
;
571 pcp
= Xmalloc(sizeof *pcp
);
575 memset(pcp
, 0, sizeof *pcp
);
576 if (!glx_context_init(&pcp
->base
, &psc
->base
, mode
)) {
581 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
583 &pcp
->hwContextID
, &hwContext
)) {
589 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
591 renderType
, shared
, hwContext
, pcp
);
592 if (pcp
->driContext
== NULL
) {
593 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
598 pcp
->base
.vtable
= &dri_context_vtable
;
599 pcp
->base
.driContext
= &pcp
->dri_vtable
;
600 pcp
->dri_vtable
.bindContext
= driBindContext
;
601 pcp
->dri_vtable
.unbindContext
= driUnbindContext
;
607 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
609 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
610 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
612 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
613 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
617 static __GLXDRIdrawable
*
618 driCreateDrawable(__GLXscreenConfigs
*base
,
620 GLXDrawable drawable
, const __GLcontextModes
* modes
)
622 drm_drawable_t hwDrawable
;
623 void *empty_attribute_list
= NULL
;
624 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
625 struct dri_screen
*psc
= (struct dri_screen
*) base
;
626 struct dri_drawable
*pdp
;
628 /* Old dri can't handle GLX 1.3+ drawable constructors. */
629 if (xDrawable
!= drawable
)
632 pdp
= Xmalloc(sizeof *pdp
);
636 memset(pdp
, 0, sizeof *pdp
);
637 pdp
->base
.drawable
= drawable
;
638 pdp
->base
.psc
= &psc
->base
;
640 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
641 drawable
, &hwDrawable
)) {
646 /* Create a new drawable */
648 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
652 empty_attribute_list
, pdp
);
654 if (!pdp
->driDrawable
) {
655 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
660 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
666 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
669 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
670 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
672 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
677 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
678 int x
, int y
, int width
, int height
)
680 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
681 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
683 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
684 x
, y
, width
, height
);
688 driDestroyScreen(__GLXscreenConfigs
*base
)
690 struct dri_screen
*psc
= (struct dri_screen
*) base
;
692 /* Free the direct rendering per screen data */
694 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
695 driDestroyConfigs(psc
->driver_configs
);
696 psc
->driScreen
= NULL
;
698 dlclose(psc
->driver
);
701 #ifdef __DRI_SWAP_BUFFER_COUNTER
704 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
705 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
707 struct dri_screen
*psc
= (struct dri_screen
*) base
;
708 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
710 if (pdp
&& psc
->sbc
&& psc
->msc
)
711 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
712 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
713 __glXGetUST(ust
) == 0 );
717 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
718 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
720 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
721 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
723 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
724 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
725 divisor
, remainder
, msc
, sbc
);
727 /* __glXGetUST returns zero on success and non-zero on failure.
728 * This function returns True on success and False on failure.
730 return ret
== 0 && __glXGetUST(ust
) == 0;
735 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
736 int64_t *msc
, int64_t *sbc
)
738 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
740 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
742 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
744 /* __glXGetUST returns zero on success and non-zero on failure.
745 * This function returns True on success and False on failure.
747 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
750 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
751 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
757 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
759 GLXContext gc
= __glXGetCurrentContext();
760 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
761 struct dri_screen
*psc
;
763 if (gc
->driContext
) {
764 psc
= (struct dri_screen
*) pdraw
->psc
;
766 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
767 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
772 return GLX_BAD_CONTEXT
;
776 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
778 GLXContext gc
= __glXGetCurrentContext();
779 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
780 struct dri_screen
*psc
;
782 if (gc
!= NULL
&& gc
->driContext
) {
783 psc
= (struct dri_screen
*) pdraw
->psc
;
785 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
786 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
793 /* Bind DRI1 specific extensions */
795 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
799 for (i
= 0; extensions
[i
]; i
++) {
800 /* No DRI2 support for swap_control at the moment, since SwapBuffers
801 * is done by the X server */
802 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
803 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
804 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
805 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
808 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
809 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
810 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
813 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
814 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
815 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
818 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
819 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
821 /* Ignore unknown extensions */
825 static const struct glx_screen_vtable dri_screen_vtable
= {
829 static __GLXscreenConfigs
*
830 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
832 struct dri_display
*pdp
;
834 const __DRIextension
**extensions
;
835 struct dri_screen
*psc
;
839 psc
= Xcalloc(1, sizeof *psc
);
843 memset(psc
, 0, sizeof *psc
);
844 if (!glx_screen_init(&psc
->base
, screen
, priv
))
847 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
852 psc
->driver
= driOpenDriver(driverName
);
854 if (psc
->driver
== NULL
) {
859 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
860 if (extensions
== NULL
) {
861 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
866 for (i
= 0; extensions
[i
]; i
++) {
867 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
868 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
869 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
870 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
873 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
878 pdp
= (struct dri_display
*) priv
->driDisplay
;
880 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
881 if (psc
->driScreen
== NULL
) {
882 dlclose(psc
->driver
);
887 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
888 driBindExtensions(psc
, extensions
);
890 psc
->base
.vtable
= &dri_screen_vtable
;
892 psc
->base
.driScreen
= psp
;
893 if (psc
->driCopySubBuffer
)
894 psp
->copySubBuffer
= driCopySubBuffer
;
896 psp
->destroyScreen
= driDestroyScreen
;
897 psp
->createDrawable
= driCreateDrawable
;
898 psp
->swapBuffers
= driSwapBuffers
;
900 #ifdef __DRI_SWAP_BUFFER_COUNTER
901 psp
->getDrawableMSC
= driDrawableGetMSC
;
902 psp
->waitForMSC
= driWaitForMSC
;
903 psp
->waitForSBC
= driWaitForSBC
;
906 psp
->setSwapInterval
= driSetSwapInterval
;
907 psp
->getSwapInterval
= driGetSwapInterval
;
912 /* Called from __glXFreeDisplayPrivate.
915 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
921 * Allocate, initialize and return a __DRIdisplayPrivate object.
922 * This is called from __glXInitialize() when we are given a new
925 _X_HIDDEN __GLXDRIdisplay
*
926 driCreateDisplay(Display
* dpy
)
928 struct dri_display
*pdpyp
;
929 int eventBase
, errorBase
;
930 int major
, minor
, patch
;
932 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
936 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
940 pdpyp
= Xmalloc(sizeof *pdpyp
);
945 pdpyp
->driMajor
= major
;
946 pdpyp
->driMinor
= minor
;
947 pdpyp
->driPatch
= patch
;
949 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
950 pdpyp
->base
.createScreen
= driCreateScreen
;
955 #endif /* GLX_DIRECT_RENDERING */