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
;
80 __DRIcontext
*driContext
;
82 __GLXscreenConfigs
*psc
;
86 * Given a display pointer and screen number, determine the name of
87 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
88 * Return True for success, False for failure.
91 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
96 int driverMajor
, driverMinor
, driverPatch
;
100 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
101 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
102 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
105 if (!directCapable
) {
106 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
110 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
111 &driverPatch
, driverName
);
113 ErrorMessageF("Cannot determine driver name for screen %d\n",
118 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
119 driverMajor
, driverMinor
, driverPatch
, *driverName
,
124 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
126 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
138 * Exported function for querying the DRI driver for a given screen.
140 * The returned char pointer points to a static array that will be
141 * overwritten by subsequent calls.
144 glXGetScreenDriver(Display
* dpy
, int scrNum
)
148 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
152 len
= strlen(driverName
);
155 memcpy(ret
, driverName
, len
+ 1);
163 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
165 * The returned char pointer points directly into the driver. Therefore
166 * it should be treated as a constant.
168 * If the driver was not found or does not support configuration NULL is
171 * Note: The driver remains opened after this function returns.
174 glXGetDriverConfig(const char *driverName
)
176 void *handle
= driOpenDriver(driverName
);
178 return dlsym(handle
, "__driConfigOptions");
183 #ifdef XDAMAGE_1_1_INTERFACE
186 has_damage_post(Display
* dpy
)
188 static GLboolean inited
= GL_FALSE
;
189 static GLboolean has_damage
;
194 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
195 major
== 1 && minor
>= 1) {
196 has_damage
= GL_TRUE
;
199 has_damage
= GL_FALSE
;
208 __glXReportDamage(__DRIdrawable
* driDraw
,
210 drm_clip_rect_t
* rects
, int num_rects
,
211 GLboolean front_buffer
, void *loaderPrivate
)
214 XserverRegion region
;
217 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
218 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
219 Display
*dpy
= psc
->dpy
;
222 if (!has_damage_post(dpy
))
228 drawable
= RootWindow(dpy
, psc
->scr
);
233 drawable
= glxDraw
->xDrawable
;
236 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
240 for (i
= 0; i
< num_rects
; i
++) {
241 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
242 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
243 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
244 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
246 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
248 XDamageAdd(dpy
, drawable
, region
);
249 XFixesDestroyRegion(dpy
, region
);
252 static const __DRIdamageExtension damageExtension
= {
253 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
260 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
261 unsigned int *index
, unsigned int *stamp
,
262 int *X
, int *Y
, int *W
, int *H
,
263 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
264 int *backX
, int *backY
,
265 int *numBackClipRects
,
266 drm_clip_rect_t
** pBackClipRects
,
269 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
270 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
271 Display
*dpy
= psc
->dpy
;
273 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
274 index
, stamp
, X
, Y
, W
, H
,
275 numClipRects
, pClipRects
,
277 numBackClipRects
, pBackClipRects
);
280 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
281 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
282 __glXDRIGetDrawableInfo
285 static const __DRIextension
*loader_extensions
[] = {
286 &systemTimeExtension
.base
,
287 &getDrawableInfoExtension
.base
,
288 #ifdef XDAMAGE_1_1_INTERFACE
289 &damageExtension
.base
,
295 * Perform the required libGL-side initialization and call the client-side
296 * driver's \c __driCreateNewScreen function.
298 * \param dpy Display pointer.
299 * \param scrn Screen number on the display.
300 * \param psc DRI screen information.
301 * \param driDpy DRI display information.
302 * \param createNewScreen Pointer to the client-side driver's
303 * \c __driCreateNewScreen function.
304 * \returns A pointer to the \c __DRIscreen structure returned by
305 * the client-side driver on success, or \c NULL on failure.
308 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
309 struct dri_display
* driDpy
)
313 drmAddress pSAREA
= MAP_FAILED
;
315 __DRIversion ddx_version
;
316 __DRIversion dri_version
;
317 __DRIversion drm_version
;
318 __DRIframebuffer framebuffer
;
323 drmVersionPtr version
;
328 const __DRIconfig
**driver_configs
;
329 __GLcontextModes
*visual
;
331 /* DRI protocol version. */
332 dri_version
.major
= driDpy
->driMajor
;
333 dri_version
.minor
= driDpy
->driMinor
;
334 dri_version
.patch
= driDpy
->driPatch
;
336 framebuffer
.base
= MAP_FAILED
;
337 framebuffer
.dev_priv
= NULL
;
338 framebuffer
.size
= 0;
340 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
341 ErrorMessageF("XF86DRIOpenConnection failed\n");
345 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
347 Xfree(BusID
); /* No longer needed */
350 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
354 if (drmGetMagic(fd
, &magic
)) {
355 ErrorMessageF("drmGetMagic failed\n");
359 version
= drmGetVersion(fd
);
361 drm_version
.major
= version
->version_major
;
362 drm_version
.minor
= version
->version_minor
;
363 drm_version
.patch
= version
->version_patchlevel
;
364 drmFreeVersion(version
);
367 drm_version
.major
= -1;
368 drm_version
.minor
= -1;
369 drm_version
.patch
= -1;
372 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
373 ErrorMessageF("XF86DRIAuthConnection failed\n");
377 /* Get device name (like "tdfx") and the ddx version numbers.
378 * We'll check the version in each DRI driver's "createNewScreen"
380 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
383 &ddx_version
.patch
, &driverName
)) {
384 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
388 Xfree(driverName
); /* No longer needed. */
391 * Get device-specific info. pDevPriv will point to a struct
392 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
393 * has information about the screen size, depth, pitch, ancilliary
394 * buffers, DRM mmap handles, etc.
396 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
397 &framebuffer
.size
, &framebuffer
.stride
,
398 &framebuffer
.dev_priv_size
,
399 &framebuffer
.dev_priv
)) {
400 ErrorMessageF("XF86DRIGetDeviceInfo failed");
404 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
405 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
407 /* Map the framebuffer region. */
408 status
= drmMap(fd
, hFB
, framebuffer
.size
,
409 (drmAddressPtr
) & framebuffer
.base
);
411 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
415 /* Map the SAREA region. Further mmap regions may be setup in
416 * each DRI driver's "createNewScreen" function.
418 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
420 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
424 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
432 &driver_configs
, psc
);
435 ErrorMessageF("Calling driver entry point failed");
440 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
442 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
444 psc
->base
.driver_configs
= driver_configs
;
446 /* Visuals with depth != screen depth are subject to automatic compositing
447 * in the X server, so DRI1 can't render to them properly. Mark them as
448 * non-conformant to prevent apps from picking them up accidentally.
450 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
451 XVisualInfo
template;
452 XVisualInfo
*visuals
;
456 template.visualid
= visual
->visualID
;
458 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
461 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
462 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
471 if (pSAREA
!= MAP_FAILED
)
472 drmUnmap(pSAREA
, SAREA_MAX
);
474 if (framebuffer
.base
!= MAP_FAILED
)
475 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
477 if (framebuffer
.dev_priv
!= NULL
)
478 Xfree(framebuffer
.dev_priv
);
483 XF86DRICloseConnection(dpy
, scrn
);
485 ErrorMessageF("reverting to software direct rendering\n");
491 driDestroyContext(__GLXDRIcontext
* context
,
492 __GLXscreenConfigs
*base
, Display
* dpy
)
494 struct dri_context
*pcp
= (struct dri_context
*) context
;
495 struct dri_screen
*psc
= (struct dri_screen
*) base
;
497 (*psc
->core
->destroyContext
) (pcp
->driContext
);
499 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
504 driBindContext(__GLXDRIcontext
*context
,
505 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
507 struct dri_context
*pcp
= (struct dri_context
*) context
;
508 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
510 return (*psc
->core
->bindContext
) (pcp
->driContext
,
511 draw
->driDrawable
, read
->driDrawable
);
515 driUnbindContext(__GLXDRIcontext
* context
)
517 struct dri_context
*pcp
= (struct dri_context
*) context
;
518 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
520 (*psc
->core
->unbindContext
) (pcp
->driContext
);
523 static __GLXDRIcontext
*
524 driCreateContext(__GLXscreenConfigs
*base
,
525 const __GLcontextModes
* mode
,
526 GLXContext gc
, GLXContext shareList
, int renderType
)
528 struct dri_context
*pcp
, *pcp_shared
;
529 struct dri_screen
*psc
= (struct dri_screen
*) base
;
530 drm_context_t hwContext
;
531 __DRIcontext
*shared
= NULL
;
532 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
534 if (!psc
->base
.driScreen
)
538 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
539 shared
= pcp_shared
->driContext
;
542 pcp
= Xmalloc(sizeof *pcp
);
546 pcp
->psc
= &psc
->base
;
547 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
549 &pcp
->hwContextID
, &hwContext
)) {
555 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
557 renderType
, shared
, hwContext
, pcp
);
558 if (pcp
->driContext
== NULL
) {
559 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
564 pcp
->base
.destroyContext
= driDestroyContext
;
565 pcp
->base
.bindContext
= driBindContext
;
566 pcp
->base
.unbindContext
= driUnbindContext
;
572 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
574 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
576 (*psc
->core
->destroyDrawable
) (pdraw
->driDrawable
);
577 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
581 static __GLXDRIdrawable
*
582 driCreateDrawable(__GLXscreenConfigs
*base
,
584 GLXDrawable drawable
, const __GLcontextModes
* modes
)
586 __GLXDRIdrawable
*pdraw
;
587 drm_drawable_t hwDrawable
;
588 void *empty_attribute_list
= NULL
;
589 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
590 struct dri_screen
*psc
= (struct dri_screen
*) base
;
592 /* Old dri can't handle GLX 1.3+ drawable constructors. */
593 if (xDrawable
!= drawable
)
596 pdraw
= Xmalloc(sizeof(*pdraw
));
600 pdraw
->drawable
= drawable
;
601 pdraw
->psc
= &psc
->base
;
603 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
604 drawable
, &hwDrawable
)) {
609 /* Create a new drawable */
611 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
615 empty_attribute_list
, pdraw
);
617 if (!pdraw
->driDrawable
) {
618 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
623 pdraw
->destroyDrawable
= driDestroyDrawable
;
629 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
632 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
634 (*psc
->core
->swapBuffers
) (pdraw
->driDrawable
);
639 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
640 int x
, int y
, int width
, int height
)
642 (*pdraw
->psc
->driCopySubBuffer
->copySubBuffer
) (pdraw
->driDrawable
,
643 x
, y
, width
, height
);
647 driDestroyScreen(__GLXscreenConfigs
*base
)
649 struct dri_screen
*psc
= (struct dri_screen
*) base
;
651 /* Free the direct rendering per screen data */
653 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
654 psc
->driScreen
= NULL
;
656 dlclose(psc
->driver
);
659 static const struct glx_context_vtable dri_context_vtable
= {
664 #ifdef __DRI_SWAP_BUFFER_COUNTER
667 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
668 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
670 struct dri_screen
*psc
= (struct dri_screen
*) base
;
672 if (pdraw
&& psc
->sbc
&& psc
->msc
)
673 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
674 (*psc
->sbc
->getSBC
)(pdraw
->driDrawable
, sbc
) == 0 &&
675 __glXGetUST(ust
) == 0 );
679 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
680 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
682 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
684 if (pdraw
!= NULL
&& psc
->msc
!= NULL
) {
685 ret
= (*psc
->msc
->waitForMSC
) (pdraw
->driDrawable
, target_msc
,
686 divisor
, remainder
, msc
, sbc
);
688 /* __glXGetUST returns zero on success and non-zero on failure.
689 * This function returns True on success and False on failure.
691 return ret
== 0 && __glXGetUST(ust
) == 0;
696 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
697 int64_t *msc
, int64_t *sbc
)
699 if (pdraw
!= NULL
&& psc
->sbc
!= NULL
) {
701 (*psc
->sbc
->waitForSBC
) (pdraw
->driDrawable
, target_sbc
, msc
, sbc
);
703 /* __glXGetUST returns zero on success and non-zero on failure.
704 * This function returns True on success and False on failure.
706 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
709 return DRI2WaitSBC(pdraw
->psc
->dpy
, pdraw
->xDrawable
, target_sbc
, ust
, msc
,
716 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
718 GLXContext gc
= __glXGetCurrentContext();
719 struct dri_screen
*psc
;
721 if (gc
->driContext
) {
722 psc
= (struct dri_screen
*) pdraw
->psc
;
724 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
725 psc
->swapControl
->setSwapInterval(pdraw
->driDrawable
, interval
);
730 return GLX_BAD_CONTEXT
;
734 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
736 GLXContext gc
= __glXGetCurrentContext();
737 struct dri_screen
*psc
;
739 if (gc
!= NULL
&& gc
->driContext
) {
740 psc
= (struct dri_screen
*) pdraw
->psc
;
742 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
743 return psc
->swapControl
->getSwapInterval(pdraw
->driDrawable
);
750 /* Bind DRI1 specific extensions */
752 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
756 for (i
= 0; extensions
[i
]; i
++) {
757 /* No DRI2 support for swap_control at the moment, since SwapBuffers
758 * is done by the X server */
759 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
760 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
761 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
762 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
765 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
766 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
767 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
770 /* Ignore unknown extensions */
774 static __GLXscreenConfigs
*
775 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
777 struct dri_display
*pdp
;
779 const __DRIextension
**extensions
;
780 struct dri_screen
*psc
;
784 psc
= Xcalloc(1, sizeof *psc
);
788 memset(psc
, 0, sizeof *psc
);
789 if (!glx_screen_init(&psc
->base
, screen
, priv
))
792 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
797 psc
->driver
= driOpenDriver(driverName
);
799 if (psc
->driver
== NULL
) {
804 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
805 if (extensions
== NULL
) {
806 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
811 for (i
= 0; extensions
[i
]; i
++) {
812 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
813 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
814 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
815 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
818 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
823 pdp
= (struct dri_display
*) priv
->driDisplay
;
825 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
826 if (psc
->driScreen
== NULL
) {
827 dlclose(psc
->driver
);
832 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
833 driBindExtensions(psc
, extensions
);
834 driBindCommonExtensions(&psc
->base
, extensions
);
837 psc
->base
.driScreen
= psp
;
838 if (psc
->base
.driCopySubBuffer
)
839 psp
->copySubBuffer
= driCopySubBuffer
;
841 psp
->destroyScreen
= driDestroyScreen
;
842 psp
->createContext
= driCreateContext
;
843 psp
->createDrawable
= driCreateDrawable
;
844 psp
->swapBuffers
= driSwapBuffers
;
848 #ifdef __DRI_SWAP_BUFFER_COUNTER
849 psp
->getDrawableMSC
= driDrawableGetMSC
;
850 psp
->waitForMSC
= driWaitForMSC
;
851 psp
->waitForSBC
= driWaitForSBC
;
854 psp
->setSwapInterval
= driSetSwapInterval
;
855 psp
->getSwapInterval
= driGetSwapInterval
;
857 psc
->base
.direct_context_vtable
= &dri_context_vtable
;
862 /* Called from __glXFreeDisplayPrivate.
865 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
871 * Allocate, initialize and return a __DRIdisplayPrivate object.
872 * This is called from __glXInitialize() when we are given a new
875 _X_HIDDEN __GLXDRIdisplay
*
876 driCreateDisplay(Display
* dpy
)
878 struct dri_display
*pdpyp
;
879 int eventBase
, errorBase
;
880 int major
, minor
, patch
;
882 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
886 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
890 pdpyp
= Xmalloc(sizeof *pdpyp
);
895 pdpyp
->driMajor
= major
;
896 pdpyp
->driMinor
= minor
;
897 pdpyp
->driPatch
= patch
;
899 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
900 pdpyp
->base
.createScreen
= driCreateScreen
;
905 #endif /* GLX_DIRECT_RENDERING */