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
= {
101 * Given a display pointer and screen number, determine the name of
102 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
103 * Return True for success, False for failure.
106 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
111 int driverMajor
, driverMinor
, driverPatch
;
115 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
116 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
117 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
120 if (!directCapable
) {
121 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
125 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
126 &driverPatch
, driverName
);
128 ErrorMessageF("Cannot determine driver name for screen %d\n",
133 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
134 driverMajor
, driverMinor
, driverPatch
, *driverName
,
139 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
141 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
153 * Exported function for querying the DRI driver for a given screen.
155 * The returned char pointer points to a static array that will be
156 * overwritten by subsequent calls.
159 glXGetScreenDriver(Display
* dpy
, int scrNum
)
163 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
167 len
= strlen(driverName
);
170 memcpy(ret
, driverName
, len
+ 1);
178 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
180 * The returned char pointer points directly into the driver. Therefore
181 * it should be treated as a constant.
183 * If the driver was not found or does not support configuration NULL is
186 * Note: The driver remains opened after this function returns.
189 glXGetDriverConfig(const char *driverName
)
191 void *handle
= driOpenDriver(driverName
);
193 return dlsym(handle
, "__driConfigOptions");
198 #ifdef XDAMAGE_1_1_INTERFACE
201 has_damage_post(Display
* dpy
)
203 static GLboolean inited
= GL_FALSE
;
204 static GLboolean has_damage
;
209 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
210 major
== 1 && minor
>= 1) {
211 has_damage
= GL_TRUE
;
214 has_damage
= GL_FALSE
;
223 __glXReportDamage(__DRIdrawable
* driDraw
,
225 drm_clip_rect_t
* rects
, int num_rects
,
226 GLboolean front_buffer
, void *loaderPrivate
)
229 XserverRegion region
;
232 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
233 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
234 Display
*dpy
= psc
->dpy
;
237 if (!has_damage_post(dpy
))
243 drawable
= RootWindow(dpy
, psc
->scr
);
248 drawable
= glxDraw
->xDrawable
;
251 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
255 for (i
= 0; i
< num_rects
; i
++) {
256 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
257 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
258 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
259 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
261 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
263 XDamageAdd(dpy
, drawable
, region
);
264 XFixesDestroyRegion(dpy
, region
);
267 static const __DRIdamageExtension damageExtension
= {
268 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
275 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
276 unsigned int *index
, unsigned int *stamp
,
277 int *X
, int *Y
, int *W
, int *H
,
278 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
279 int *backX
, int *backY
,
280 int *numBackClipRects
,
281 drm_clip_rect_t
** pBackClipRects
,
284 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
285 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
286 Display
*dpy
= psc
->dpy
;
288 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
289 index
, stamp
, X
, Y
, W
, H
,
290 numClipRects
, pClipRects
,
292 numBackClipRects
, pBackClipRects
);
295 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
296 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
297 __glXDRIGetDrawableInfo
300 static const __DRIextension
*loader_extensions
[] = {
301 &systemTimeExtension
.base
,
302 &getDrawableInfoExtension
.base
,
303 #ifdef XDAMAGE_1_1_INTERFACE
304 &damageExtension
.base
,
310 * Perform the required libGL-side initialization and call the client-side
311 * driver's \c __driCreateNewScreen function.
313 * \param dpy Display pointer.
314 * \param scrn Screen number on the display.
315 * \param psc DRI screen information.
316 * \param driDpy DRI display information.
317 * \param createNewScreen Pointer to the client-side driver's
318 * \c __driCreateNewScreen function.
319 * \returns A pointer to the \c __DRIscreen structure returned by
320 * the client-side driver on success, or \c NULL on failure.
323 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
324 struct dri_display
* driDpy
)
328 drmAddress pSAREA
= MAP_FAILED
;
330 __DRIversion ddx_version
;
331 __DRIversion dri_version
;
332 __DRIversion drm_version
;
333 __DRIframebuffer framebuffer
;
338 drmVersionPtr version
;
343 const __DRIconfig
**driver_configs
;
344 __GLcontextModes
*visual
;
346 /* DRI protocol version. */
347 dri_version
.major
= driDpy
->driMajor
;
348 dri_version
.minor
= driDpy
->driMinor
;
349 dri_version
.patch
= driDpy
->driPatch
;
351 framebuffer
.base
= MAP_FAILED
;
352 framebuffer
.dev_priv
= NULL
;
353 framebuffer
.size
= 0;
355 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
356 ErrorMessageF("XF86DRIOpenConnection failed\n");
360 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
362 Xfree(BusID
); /* No longer needed */
365 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
369 if (drmGetMagic(fd
, &magic
)) {
370 ErrorMessageF("drmGetMagic failed\n");
374 version
= drmGetVersion(fd
);
376 drm_version
.major
= version
->version_major
;
377 drm_version
.minor
= version
->version_minor
;
378 drm_version
.patch
= version
->version_patchlevel
;
379 drmFreeVersion(version
);
382 drm_version
.major
= -1;
383 drm_version
.minor
= -1;
384 drm_version
.patch
= -1;
387 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
388 ErrorMessageF("XF86DRIAuthConnection failed\n");
392 /* Get device name (like "tdfx") and the ddx version numbers.
393 * We'll check the version in each DRI driver's "createNewScreen"
395 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
398 &ddx_version
.patch
, &driverName
)) {
399 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
403 Xfree(driverName
); /* No longer needed. */
406 * Get device-specific info. pDevPriv will point to a struct
407 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
408 * has information about the screen size, depth, pitch, ancilliary
409 * buffers, DRM mmap handles, etc.
411 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
412 &framebuffer
.size
, &framebuffer
.stride
,
413 &framebuffer
.dev_priv_size
,
414 &framebuffer
.dev_priv
)) {
415 ErrorMessageF("XF86DRIGetDeviceInfo failed");
419 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
420 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
422 /* Map the framebuffer region. */
423 status
= drmMap(fd
, hFB
, framebuffer
.size
,
424 (drmAddressPtr
) & framebuffer
.base
);
426 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
430 /* Map the SAREA region. Further mmap regions may be setup in
431 * each DRI driver's "createNewScreen" function.
433 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
435 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
439 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
447 &driver_configs
, psc
);
450 ErrorMessageF("Calling driver entry point failed");
455 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
457 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
459 psc
->driver_configs
= driver_configs
;
461 /* Visuals with depth != screen depth are subject to automatic compositing
462 * in the X server, so DRI1 can't render to them properly. Mark them as
463 * non-conformant to prevent apps from picking them up accidentally.
465 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
466 XVisualInfo
template;
467 XVisualInfo
*visuals
;
471 template.visualid
= visual
->visualID
;
473 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
476 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
477 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
486 if (pSAREA
!= MAP_FAILED
)
487 drmUnmap(pSAREA
, SAREA_MAX
);
489 if (framebuffer
.base
!= MAP_FAILED
)
490 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
492 if (framebuffer
.dev_priv
!= NULL
)
493 Xfree(framebuffer
.dev_priv
);
498 XF86DRICloseConnection(dpy
, scrn
);
500 ErrorMessageF("reverting to software direct rendering\n");
506 driDestroyContext(__GLXcontext
* context
)
508 struct dri_context
*pcp
= (struct dri_context
*) context
;
509 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
511 (*psc
->core
->destroyContext
) (pcp
->driContext
);
513 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
518 driBindContext(__GLXcontext
*context
,
519 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
521 struct dri_context
*pcp
= (struct dri_context
*) context
;
522 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
523 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
524 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
526 return (*psc
->core
->bindContext
) (pcp
->driContext
,
527 pdr
->driDrawable
, prd
->driDrawable
);
531 driUnbindContext(__GLXcontext
* context
)
533 struct dri_context
*pcp
= (struct dri_context
*) context
;
534 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
536 (*psc
->core
->unbindContext
) (pcp
->driContext
);
539 static __GLXcontext
*
540 driCreateContext(__GLXscreenConfigs
*base
,
541 const __GLcontextModes
* mode
,
542 GLXContext shareList
, int renderType
)
544 struct dri_context
*pcp
, *pcp_shared
;
545 struct dri_screen
*psc
= (struct dri_screen
*) base
;
546 drm_context_t hwContext
;
547 __DRIcontext
*shared
= NULL
;
548 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
550 if (!psc
->base
.driScreen
)
554 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
555 shared
= pcp_shared
->driContext
;
558 pcp
= Xmalloc(sizeof *pcp
);
562 memset(pcp
, 0, sizeof *pcp
);
563 if (!glx_context_init(&pcp
->base
, &psc
->base
, mode
)) {
568 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
570 &pcp
->hwContextID
, &hwContext
)) {
576 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
578 renderType
, shared
, hwContext
, pcp
);
579 if (pcp
->driContext
== NULL
) {
580 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
585 pcp
->base
.vtable
= &dri_context_vtable
;
586 pcp
->base
.driContext
= &pcp
->dri_vtable
;
587 pcp
->dri_vtable
.destroyContext
= driDestroyContext
;
588 pcp
->dri_vtable
.bindContext
= driBindContext
;
589 pcp
->dri_vtable
.unbindContext
= driUnbindContext
;
595 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
597 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
598 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
600 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
601 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
605 static __GLXDRIdrawable
*
606 driCreateDrawable(__GLXscreenConfigs
*base
,
608 GLXDrawable drawable
, const __GLcontextModes
* modes
)
610 drm_drawable_t hwDrawable
;
611 void *empty_attribute_list
= NULL
;
612 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
613 struct dri_screen
*psc
= (struct dri_screen
*) base
;
614 struct dri_drawable
*pdp
;
616 /* Old dri can't handle GLX 1.3+ drawable constructors. */
617 if (xDrawable
!= drawable
)
620 pdp
= Xmalloc(sizeof *pdp
);
624 pdp
->base
.drawable
= drawable
;
625 pdp
->base
.psc
= &psc
->base
;
627 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
628 drawable
, &hwDrawable
)) {
633 /* Create a new drawable */
635 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
639 empty_attribute_list
, pdp
);
641 if (!pdp
->driDrawable
) {
642 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
647 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
653 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
656 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
657 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
659 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
664 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
665 int x
, int y
, int width
, int height
)
667 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
668 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
670 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
671 x
, y
, width
, height
);
675 driDestroyScreen(__GLXscreenConfigs
*base
)
677 struct dri_screen
*psc
= (struct dri_screen
*) base
;
679 /* Free the direct rendering per screen data */
681 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
682 driDestroyConfigs(psc
->driver_configs
);
683 psc
->driScreen
= NULL
;
685 dlclose(psc
->driver
);
688 #ifdef __DRI_SWAP_BUFFER_COUNTER
691 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
692 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
694 struct dri_screen
*psc
= (struct dri_screen
*) base
;
695 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
697 if (pdp
&& psc
->sbc
&& psc
->msc
)
698 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
699 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
700 __glXGetUST(ust
) == 0 );
704 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
705 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
707 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
708 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
710 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
711 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
712 divisor
, remainder
, msc
, sbc
);
714 /* __glXGetUST returns zero on success and non-zero on failure.
715 * This function returns True on success and False on failure.
717 return ret
== 0 && __glXGetUST(ust
) == 0;
722 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
723 int64_t *msc
, int64_t *sbc
)
725 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
727 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
729 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
731 /* __glXGetUST returns zero on success and non-zero on failure.
732 * This function returns True on success and False on failure.
734 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
737 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
738 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
744 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
746 GLXContext gc
= __glXGetCurrentContext();
747 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
748 struct dri_screen
*psc
;
750 if (gc
->driContext
) {
751 psc
= (struct dri_screen
*) pdraw
->psc
;
753 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
754 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
759 return GLX_BAD_CONTEXT
;
763 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
765 GLXContext gc
= __glXGetCurrentContext();
766 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
767 struct dri_screen
*psc
;
769 if (gc
!= NULL
&& gc
->driContext
) {
770 psc
= (struct dri_screen
*) pdraw
->psc
;
772 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
773 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
780 /* Bind DRI1 specific extensions */
782 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
786 for (i
= 0; extensions
[i
]; i
++) {
787 /* No DRI2 support for swap_control at the moment, since SwapBuffers
788 * is done by the X server */
789 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
790 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
791 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
792 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
795 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
796 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
797 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
800 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
801 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
802 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
805 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
806 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
808 /* Ignore unknown extensions */
812 static __GLXscreenConfigs
*
813 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
815 struct dri_display
*pdp
;
817 const __DRIextension
**extensions
;
818 struct dri_screen
*psc
;
822 psc
= Xcalloc(1, sizeof *psc
);
826 memset(psc
, 0, sizeof *psc
);
827 if (!glx_screen_init(&psc
->base
, screen
, priv
))
830 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
835 psc
->driver
= driOpenDriver(driverName
);
837 if (psc
->driver
== NULL
) {
842 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
843 if (extensions
== NULL
) {
844 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
849 for (i
= 0; extensions
[i
]; i
++) {
850 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
851 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
852 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
853 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
856 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
861 pdp
= (struct dri_display
*) priv
->driDisplay
;
863 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
864 if (psc
->driScreen
== NULL
) {
865 dlclose(psc
->driver
);
870 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
871 driBindExtensions(psc
, extensions
);
874 psc
->base
.driScreen
= psp
;
875 if (psc
->driCopySubBuffer
)
876 psp
->copySubBuffer
= driCopySubBuffer
;
878 psp
->destroyScreen
= driDestroyScreen
;
879 psp
->createContext
= driCreateContext
;
880 psp
->createDrawable
= driCreateDrawable
;
881 psp
->swapBuffers
= driSwapBuffers
;
885 #ifdef __DRI_SWAP_BUFFER_COUNTER
886 psp
->getDrawableMSC
= driDrawableGetMSC
;
887 psp
->waitForMSC
= driWaitForMSC
;
888 psp
->waitForSBC
= driWaitForSBC
;
891 psp
->setSwapInterval
= driSetSwapInterval
;
892 psp
->getSwapInterval
= driGetSwapInterval
;
897 /* Called from __glXFreeDisplayPrivate.
900 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
906 * Allocate, initialize and return a __DRIdisplayPrivate object.
907 * This is called from __glXInitialize() when we are given a new
910 _X_HIDDEN __GLXDRIdisplay
*
911 driCreateDisplay(Display
* dpy
)
913 struct dri_display
*pdpyp
;
914 int eventBase
, errorBase
;
915 int major
, minor
, patch
;
917 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
921 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
925 pdpyp
= Xmalloc(sizeof *pdpyp
);
930 pdpyp
->driMajor
= major
;
931 pdpyp
->driMinor
= minor
;
932 pdpyp
->driPatch
= patch
;
934 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
935 pdpyp
->base
.createScreen
= driCreateScreen
;
940 #endif /* GLX_DIRECT_RENDERING */