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 __GLXDRIscreen driScreen
;
67 const __DRIlegacyExtension
*legacy
;
68 const __DRIcoreExtension
*core
;
69 const __DRIswapControlExtension
*swapControl
;
70 const __DRImediaStreamCounterExtension
*msc
;
79 __DRIcontext
*driContext
;
81 __GLXscreenConfigs
*psc
;
85 * Given a display pointer and screen number, determine the name of
86 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
87 * Return True for success, False for failure.
90 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
95 int driverMajor
, driverMinor
, driverPatch
;
99 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
100 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
101 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
104 if (!directCapable
) {
105 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
109 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
110 &driverPatch
, driverName
);
112 ErrorMessageF("Cannot determine driver name for screen %d\n",
117 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
118 driverMajor
, driverMinor
, driverPatch
, *driverName
,
123 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
125 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
137 * Exported function for querying the DRI driver for a given screen.
139 * The returned char pointer points to a static array that will be
140 * overwritten by subsequent calls.
143 glXGetScreenDriver(Display
* dpy
, int scrNum
)
147 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
151 len
= strlen(driverName
);
154 memcpy(ret
, driverName
, len
+ 1);
162 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
164 * The returned char pointer points directly into the driver. Therefore
165 * it should be treated as a constant.
167 * If the driver was not found or does not support configuration NULL is
170 * Note: The driver remains opened after this function returns.
173 glXGetDriverConfig(const char *driverName
)
175 void *handle
= driOpenDriver(driverName
);
177 return dlsym(handle
, "__driConfigOptions");
182 #ifdef XDAMAGE_1_1_INTERFACE
185 has_damage_post(Display
* dpy
)
187 static GLboolean inited
= GL_FALSE
;
188 static GLboolean has_damage
;
193 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
194 major
== 1 && minor
>= 1) {
195 has_damage
= GL_TRUE
;
198 has_damage
= GL_FALSE
;
207 __glXReportDamage(__DRIdrawable
* driDraw
,
209 drm_clip_rect_t
* rects
, int num_rects
,
210 GLboolean front_buffer
, void *loaderPrivate
)
213 XserverRegion region
;
216 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
217 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
218 Display
*dpy
= psc
->dpy
;
221 if (!has_damage_post(dpy
))
227 drawable
= RootWindow(dpy
, psc
->scr
);
232 drawable
= glxDraw
->xDrawable
;
235 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
239 for (i
= 0; i
< num_rects
; i
++) {
240 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
241 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
242 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
243 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
245 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
247 XDamageAdd(dpy
, drawable
, region
);
248 XFixesDestroyRegion(dpy
, region
);
251 static const __DRIdamageExtension damageExtension
= {
252 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
259 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
260 unsigned int *index
, unsigned int *stamp
,
261 int *X
, int *Y
, int *W
, int *H
,
262 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
263 int *backX
, int *backY
,
264 int *numBackClipRects
,
265 drm_clip_rect_t
** pBackClipRects
,
268 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
269 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
270 Display
*dpy
= psc
->dpy
;
272 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
273 index
, stamp
, X
, Y
, W
, H
,
274 numClipRects
, pClipRects
,
276 numBackClipRects
, pBackClipRects
);
279 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
280 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
281 __glXDRIGetDrawableInfo
284 static const __DRIextension
*loader_extensions
[] = {
285 &systemTimeExtension
.base
,
286 &getDrawableInfoExtension
.base
,
287 #ifdef XDAMAGE_1_1_INTERFACE
288 &damageExtension
.base
,
294 * Perform the required libGL-side initialization and call the client-side
295 * driver's \c __driCreateNewScreen function.
297 * \param dpy Display pointer.
298 * \param scrn Screen number on the display.
299 * \param psc DRI screen information.
300 * \param driDpy DRI display information.
301 * \param createNewScreen Pointer to the client-side driver's
302 * \c __driCreateNewScreen function.
303 * \returns A pointer to the \c __DRIscreen structure returned by
304 * the client-side driver on success, or \c NULL on failure.
307 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
308 struct dri_display
* driDpy
)
312 drmAddress pSAREA
= MAP_FAILED
;
314 __DRIversion ddx_version
;
315 __DRIversion dri_version
;
316 __DRIversion drm_version
;
317 __DRIframebuffer framebuffer
;
322 drmVersionPtr version
;
327 const __DRIconfig
**driver_configs
;
328 __GLcontextModes
*visual
;
330 /* DRI protocol version. */
331 dri_version
.major
= driDpy
->driMajor
;
332 dri_version
.minor
= driDpy
->driMinor
;
333 dri_version
.patch
= driDpy
->driPatch
;
335 framebuffer
.base
= MAP_FAILED
;
336 framebuffer
.dev_priv
= NULL
;
337 framebuffer
.size
= 0;
339 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
340 ErrorMessageF("XF86DRIOpenConnection failed\n");
344 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
346 Xfree(BusID
); /* No longer needed */
349 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
353 if (drmGetMagic(fd
, &magic
)) {
354 ErrorMessageF("drmGetMagic failed\n");
358 version
= drmGetVersion(fd
);
360 drm_version
.major
= version
->version_major
;
361 drm_version
.minor
= version
->version_minor
;
362 drm_version
.patch
= version
->version_patchlevel
;
363 drmFreeVersion(version
);
366 drm_version
.major
= -1;
367 drm_version
.minor
= -1;
368 drm_version
.patch
= -1;
371 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
372 ErrorMessageF("XF86DRIAuthConnection failed\n");
376 /* Get device name (like "tdfx") and the ddx version numbers.
377 * We'll check the version in each DRI driver's "createNewScreen"
379 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
382 &ddx_version
.patch
, &driverName
)) {
383 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
387 Xfree(driverName
); /* No longer needed. */
390 * Get device-specific info. pDevPriv will point to a struct
391 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
392 * has information about the screen size, depth, pitch, ancilliary
393 * buffers, DRM mmap handles, etc.
395 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
396 &framebuffer
.size
, &framebuffer
.stride
,
397 &framebuffer
.dev_priv_size
,
398 &framebuffer
.dev_priv
)) {
399 ErrorMessageF("XF86DRIGetDeviceInfo failed");
403 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
404 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
406 /* Map the framebuffer region. */
407 status
= drmMap(fd
, hFB
, framebuffer
.size
,
408 (drmAddressPtr
) & framebuffer
.base
);
410 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
414 /* Map the SAREA region. Further mmap regions may be setup in
415 * each DRI driver's "createNewScreen" function.
417 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
419 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
423 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
431 &driver_configs
, psc
);
434 ErrorMessageF("Calling driver entry point failed");
439 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
441 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
443 psc
->base
.driver_configs
= driver_configs
;
445 /* Visuals with depth != screen depth are subject to automatic compositing
446 * in the X server, so DRI1 can't render to them properly. Mark them as
447 * non-conformant to prevent apps from picking them up accidentally.
449 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
450 XVisualInfo
template;
451 XVisualInfo
*visuals
;
455 template.visualid
= visual
->visualID
;
457 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
460 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
461 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
470 if (pSAREA
!= MAP_FAILED
)
471 drmUnmap(pSAREA
, SAREA_MAX
);
473 if (framebuffer
.base
!= MAP_FAILED
)
474 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
476 if (framebuffer
.dev_priv
!= NULL
)
477 Xfree(framebuffer
.dev_priv
);
482 XF86DRICloseConnection(dpy
, scrn
);
484 ErrorMessageF("reverting to software direct rendering\n");
490 driDestroyContext(__GLXDRIcontext
* context
,
491 __GLXscreenConfigs
*base
, Display
* dpy
)
493 struct dri_context
*pcp
= (struct dri_context
*) context
;
494 struct dri_screen
*psc
= (struct dri_screen
*) base
;
496 (*psc
->core
->destroyContext
) (pcp
->driContext
);
498 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
503 driBindContext(__GLXDRIcontext
*context
,
504 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
506 struct dri_context
*pcp
= (struct dri_context
*) context
;
507 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
509 return (*psc
->core
->bindContext
) (pcp
->driContext
,
510 draw
->driDrawable
, read
->driDrawable
);
514 driUnbindContext(__GLXDRIcontext
* context
)
516 struct dri_context
*pcp
= (struct dri_context
*) context
;
517 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
519 (*psc
->core
->unbindContext
) (pcp
->driContext
);
522 static __GLXDRIcontext
*
523 driCreateContext(__GLXscreenConfigs
*base
,
524 const __GLcontextModes
* mode
,
525 GLXContext gc
, GLXContext shareList
, int renderType
)
527 struct dri_context
*pcp
, *pcp_shared
;
528 struct dri_screen
*psc
= (struct dri_screen
*) base
;
529 drm_context_t hwContext
;
530 __DRIcontext
*shared
= NULL
;
531 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
533 if (!psc
->base
.driScreen
)
537 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
538 shared
= pcp_shared
->driContext
;
541 pcp
= Xmalloc(sizeof *pcp
);
545 pcp
->psc
= &psc
->base
;
546 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
548 &pcp
->hwContextID
, &hwContext
)) {
554 (*psc
->legacy
->createNewContext
) (psc
->base
.__driScreen
,
556 renderType
, shared
, hwContext
, pcp
);
557 if (pcp
->driContext
== NULL
) {
558 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
563 pcp
->base
.destroyContext
= driDestroyContext
;
564 pcp
->base
.bindContext
= driBindContext
;
565 pcp
->base
.unbindContext
= driUnbindContext
;
571 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
573 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
575 (*psc
->core
->destroyDrawable
) (pdraw
->driDrawable
);
576 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
580 static __GLXDRIdrawable
*
581 driCreateDrawable(__GLXscreenConfigs
*base
,
583 GLXDrawable drawable
, const __GLcontextModes
* modes
)
585 __GLXDRIdrawable
*pdraw
;
586 drm_drawable_t hwDrawable
;
587 void *empty_attribute_list
= NULL
;
588 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
589 struct dri_screen
*psc
= (struct dri_screen
*) base
;
591 /* Old dri can't handle GLX 1.3+ drawable constructors. */
592 if (xDrawable
!= drawable
)
595 pdraw
= Xmalloc(sizeof(*pdraw
));
599 pdraw
->drawable
= drawable
;
600 pdraw
->psc
= &psc
->base
;
602 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
603 drawable
, &hwDrawable
)) {
608 /* Create a new drawable */
610 (*psc
->legacy
->createNewDrawable
) (psc
->base
.__driScreen
,
614 empty_attribute_list
, pdraw
);
616 if (!pdraw
->driDrawable
) {
617 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
622 pdraw
->destroyDrawable
= driDestroyDrawable
;
628 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
631 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
633 (*psc
->core
->swapBuffers
) (pdraw
->driDrawable
);
638 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
639 int x
, int y
, int width
, int height
)
641 (*pdraw
->psc
->driCopySubBuffer
->copySubBuffer
) (pdraw
->driDrawable
,
642 x
, y
, width
, height
);
646 driDestroyScreen(__GLXscreenConfigs
*base
)
648 struct dri_screen
*psc
= (struct dri_screen
*) base
;
650 /* Free the direct rendering per screen data */
651 if (psc
->base
.__driScreen
)
652 (*psc
->core
->destroyScreen
) (psc
->base
.__driScreen
);
653 psc
->base
.__driScreen
= NULL
;
655 dlclose(psc
->driver
);
658 static const struct glx_context_vtable dri_context_vtable
= {
663 #ifdef __DRI_SWAP_BUFFER_COUNTER
666 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
667 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
669 struct dri_screen
*psc
= (struct dri_screen
*) base
;
671 if (pdraw
&& psc
->sbc
&& psc
->msc
)
672 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
673 (*psc
->sbc
->getSBC
)(pdraw
->driDrawable
, sbc
) == 0 &&
674 __glXGetUST(ust
) == 0 );
678 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
679 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
681 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
683 if (pdraw
!= NULL
&& psc
->msc
!= NULL
) {
684 ret
= (*psc
->msc
->waitForMSC
) (pdraw
->driDrawable
, target_msc
,
685 divisor
, remainder
, msc
, sbc
);
687 /* __glXGetUST returns zero on success and non-zero on failure.
688 * This function returns True on success and False on failure.
690 return ret
== 0 && __glXGetUST(ust
) == 0;
695 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
696 int64_t *msc
, int64_t *sbc
)
698 if (pdraw
!= NULL
&& psc
->sbc
!= NULL
) {
700 (*psc
->sbc
->waitForSBC
) (pdraw
->driDrawable
, target_sbc
, msc
, sbc
);
702 /* __glXGetUST returns zero on success and non-zero on failure.
703 * This function returns True on success and False on failure.
705 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
708 return DRI2WaitSBC(pdraw
->psc
->dpy
, pdraw
->xDrawable
, target_sbc
, ust
, msc
,
715 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
717 GLXContext gc
= __glXGetCurrentContext();
718 struct dri_screen
*psc
;
720 if (gc
->driContext
) {
721 psc
= (struct dri_screen
*) pdraw
->psc
;
723 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
724 psc
->swapControl
->setSwapInterval(pdraw
->driDrawable
, interval
);
729 return GLX_BAD_CONTEXT
;
733 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
735 GLXContext gc
= __glXGetCurrentContext();
736 struct dri_screen
*psc
;
738 if (gc
!= NULL
&& gc
->driContext
) {
739 psc
= (struct dri_screen
*) pdraw
->psc
;
741 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
742 return psc
->swapControl
->getSwapInterval(pdraw
->driDrawable
);
749 /* Bind DRI1 specific extensions */
751 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
755 for (i
= 0; extensions
[i
]; i
++) {
756 /* No DRI2 support for swap_control at the moment, since SwapBuffers
757 * is done by the X server */
758 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
759 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
760 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
761 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
764 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
765 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
766 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
769 /* Ignore unknown extensions */
773 static __GLXscreenConfigs
*
774 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
776 struct dri_display
*pdp
;
778 const __DRIextension
**extensions
;
779 struct dri_screen
*psc
;
783 psc
= Xcalloc(1, sizeof *psc
);
787 memset(psc
, 0, sizeof *psc
);
788 if (!glx_screen_init(&psc
->base
, screen
, priv
))
791 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
796 psc
->driver
= driOpenDriver(driverName
);
798 if (psc
->driver
== NULL
) {
803 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
804 if (extensions
== NULL
) {
805 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
810 for (i
= 0; extensions
[i
]; i
++) {
811 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
812 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
813 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
814 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
817 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
822 pdp
= (struct dri_display
*) priv
->driDisplay
;
823 psc
->base
.__driScreen
=
824 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
825 if (psc
->base
.__driScreen
== NULL
) {
826 dlclose(psc
->driver
);
831 extensions
= psc
->core
->getExtensions(psc
->base
.__driScreen
);
832 driBindExtensions(psc
, extensions
);
833 driBindCommonExtensions(&psc
->base
, extensions
);
835 psp
= &psc
->driScreen
;
836 psc
->base
.driScreen
= psp
;
837 if (psc
->base
.driCopySubBuffer
)
838 psp
->copySubBuffer
= driCopySubBuffer
;
840 psp
->destroyScreen
= driDestroyScreen
;
841 psp
->createContext
= driCreateContext
;
842 psp
->createDrawable
= driCreateDrawable
;
843 psp
->swapBuffers
= driSwapBuffers
;
847 #ifdef __DRI_SWAP_BUFFER_COUNTER
848 psp
->getDrawableMSC
= driDrawableGetMSC
;
849 psp
->waitForMSC
= driWaitForMSC
;
850 psp
->waitForSBC
= driWaitForSBC
;
853 psp
->setSwapInterval
= driSetSwapInterval
;
854 psp
->getSwapInterval
= driGetSwapInterval
;
856 psc
->base
.direct_context_vtable
= &dri_context_vtable
;
861 /* Called from __glXFreeDisplayPrivate.
864 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
870 * Allocate, initialize and return a __DRIdisplayPrivate object.
871 * This is called from __glXInitialize() when we are given a new
874 _X_HIDDEN __GLXDRIdisplay
*
875 driCreateDisplay(Display
* dpy
)
877 struct dri_display
*pdpyp
;
878 int eventBase
, errorBase
;
879 int major
, minor
, patch
;
881 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
885 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
889 pdpyp
= Xmalloc(sizeof *pdpyp
);
894 pdpyp
->driMajor
= major
;
895 pdpyp
->driMinor
= minor
;
896 pdpyp
->driPatch
= patch
;
898 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
899 pdpyp
->base
.createScreen
= driCreateScreen
;
904 #endif /* GLX_DIRECT_RENDERING */