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
;
87 __GLXDRIdrawable base
;
89 __DRIdrawable
*driDrawable
;
93 * Given a display pointer and screen number, determine the name of
94 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
95 * Return True for success, False for failure.
98 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
103 int driverMajor
, driverMinor
, driverPatch
;
107 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
108 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
109 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
112 if (!directCapable
) {
113 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
117 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
118 &driverPatch
, driverName
);
120 ErrorMessageF("Cannot determine driver name for screen %d\n",
125 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
126 driverMajor
, driverMinor
, driverPatch
, *driverName
,
131 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
133 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
145 * Exported function for querying the DRI driver for a given screen.
147 * The returned char pointer points to a static array that will be
148 * overwritten by subsequent calls.
151 glXGetScreenDriver(Display
* dpy
, int scrNum
)
155 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
159 len
= strlen(driverName
);
162 memcpy(ret
, driverName
, len
+ 1);
170 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
172 * The returned char pointer points directly into the driver. Therefore
173 * it should be treated as a constant.
175 * If the driver was not found or does not support configuration NULL is
178 * Note: The driver remains opened after this function returns.
181 glXGetDriverConfig(const char *driverName
)
183 void *handle
= driOpenDriver(driverName
);
185 return dlsym(handle
, "__driConfigOptions");
190 #ifdef XDAMAGE_1_1_INTERFACE
193 has_damage_post(Display
* dpy
)
195 static GLboolean inited
= GL_FALSE
;
196 static GLboolean has_damage
;
201 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
202 major
== 1 && minor
>= 1) {
203 has_damage
= GL_TRUE
;
206 has_damage
= GL_FALSE
;
215 __glXReportDamage(__DRIdrawable
* driDraw
,
217 drm_clip_rect_t
* rects
, int num_rects
,
218 GLboolean front_buffer
, void *loaderPrivate
)
221 XserverRegion region
;
224 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
225 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
226 Display
*dpy
= psc
->dpy
;
229 if (!has_damage_post(dpy
))
235 drawable
= RootWindow(dpy
, psc
->scr
);
240 drawable
= glxDraw
->xDrawable
;
243 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
247 for (i
= 0; i
< num_rects
; i
++) {
248 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
249 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
250 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
251 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
253 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
255 XDamageAdd(dpy
, drawable
, region
);
256 XFixesDestroyRegion(dpy
, region
);
259 static const __DRIdamageExtension damageExtension
= {
260 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
267 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
268 unsigned int *index
, unsigned int *stamp
,
269 int *X
, int *Y
, int *W
, int *H
,
270 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
271 int *backX
, int *backY
,
272 int *numBackClipRects
,
273 drm_clip_rect_t
** pBackClipRects
,
276 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
277 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
278 Display
*dpy
= psc
->dpy
;
280 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
281 index
, stamp
, X
, Y
, W
, H
,
282 numClipRects
, pClipRects
,
284 numBackClipRects
, pBackClipRects
);
287 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
288 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
289 __glXDRIGetDrawableInfo
292 static const __DRIextension
*loader_extensions
[] = {
293 &systemTimeExtension
.base
,
294 &getDrawableInfoExtension
.base
,
295 #ifdef XDAMAGE_1_1_INTERFACE
296 &damageExtension
.base
,
302 * Perform the required libGL-side initialization and call the client-side
303 * driver's \c __driCreateNewScreen function.
305 * \param dpy Display pointer.
306 * \param scrn Screen number on the display.
307 * \param psc DRI screen information.
308 * \param driDpy DRI display information.
309 * \param createNewScreen Pointer to the client-side driver's
310 * \c __driCreateNewScreen function.
311 * \returns A pointer to the \c __DRIscreen structure returned by
312 * the client-side driver on success, or \c NULL on failure.
315 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
316 struct dri_display
* driDpy
)
320 drmAddress pSAREA
= MAP_FAILED
;
322 __DRIversion ddx_version
;
323 __DRIversion dri_version
;
324 __DRIversion drm_version
;
325 __DRIframebuffer framebuffer
;
330 drmVersionPtr version
;
335 const __DRIconfig
**driver_configs
;
336 __GLcontextModes
*visual
;
338 /* DRI protocol version. */
339 dri_version
.major
= driDpy
->driMajor
;
340 dri_version
.minor
= driDpy
->driMinor
;
341 dri_version
.patch
= driDpy
->driPatch
;
343 framebuffer
.base
= MAP_FAILED
;
344 framebuffer
.dev_priv
= NULL
;
345 framebuffer
.size
= 0;
347 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
348 ErrorMessageF("XF86DRIOpenConnection failed\n");
352 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
354 Xfree(BusID
); /* No longer needed */
357 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
361 if (drmGetMagic(fd
, &magic
)) {
362 ErrorMessageF("drmGetMagic failed\n");
366 version
= drmGetVersion(fd
);
368 drm_version
.major
= version
->version_major
;
369 drm_version
.minor
= version
->version_minor
;
370 drm_version
.patch
= version
->version_patchlevel
;
371 drmFreeVersion(version
);
374 drm_version
.major
= -1;
375 drm_version
.minor
= -1;
376 drm_version
.patch
= -1;
379 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
380 ErrorMessageF("XF86DRIAuthConnection failed\n");
384 /* Get device name (like "tdfx") and the ddx version numbers.
385 * We'll check the version in each DRI driver's "createNewScreen"
387 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
390 &ddx_version
.patch
, &driverName
)) {
391 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
395 Xfree(driverName
); /* No longer needed. */
398 * Get device-specific info. pDevPriv will point to a struct
399 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
400 * has information about the screen size, depth, pitch, ancilliary
401 * buffers, DRM mmap handles, etc.
403 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
404 &framebuffer
.size
, &framebuffer
.stride
,
405 &framebuffer
.dev_priv_size
,
406 &framebuffer
.dev_priv
)) {
407 ErrorMessageF("XF86DRIGetDeviceInfo failed");
411 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
412 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
414 /* Map the framebuffer region. */
415 status
= drmMap(fd
, hFB
, framebuffer
.size
,
416 (drmAddressPtr
) & framebuffer
.base
);
418 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
422 /* Map the SAREA region. Further mmap regions may be setup in
423 * each DRI driver's "createNewScreen" function.
425 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
427 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
431 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
439 &driver_configs
, psc
);
442 ErrorMessageF("Calling driver entry point failed");
447 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
449 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
451 psc
->base
.driver_configs
= driver_configs
;
453 /* Visuals with depth != screen depth are subject to automatic compositing
454 * in the X server, so DRI1 can't render to them properly. Mark them as
455 * non-conformant to prevent apps from picking them up accidentally.
457 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
458 XVisualInfo
template;
459 XVisualInfo
*visuals
;
463 template.visualid
= visual
->visualID
;
465 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
468 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
469 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
478 if (pSAREA
!= MAP_FAILED
)
479 drmUnmap(pSAREA
, SAREA_MAX
);
481 if (framebuffer
.base
!= MAP_FAILED
)
482 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
484 if (framebuffer
.dev_priv
!= NULL
)
485 Xfree(framebuffer
.dev_priv
);
490 XF86DRICloseConnection(dpy
, scrn
);
492 ErrorMessageF("reverting to software direct rendering\n");
498 driDestroyContext(__GLXDRIcontext
* context
,
499 __GLXscreenConfigs
*base
, Display
* dpy
)
501 struct dri_context
*pcp
= (struct dri_context
*) context
;
502 struct dri_screen
*psc
= (struct dri_screen
*) base
;
504 (*psc
->core
->destroyContext
) (pcp
->driContext
);
506 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
511 driBindContext(__GLXDRIcontext
*context
,
512 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
514 struct dri_context
*pcp
= (struct dri_context
*) context
;
515 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
516 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
517 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
519 return (*psc
->core
->bindContext
) (pcp
->driContext
,
520 pdr
->driDrawable
, prd
->driDrawable
);
524 driUnbindContext(__GLXDRIcontext
* context
)
526 struct dri_context
*pcp
= (struct dri_context
*) context
;
527 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
529 (*psc
->core
->unbindContext
) (pcp
->driContext
);
532 static __GLXDRIcontext
*
533 driCreateContext(__GLXscreenConfigs
*base
,
534 const __GLcontextModes
* mode
,
535 GLXContext gc
, GLXContext shareList
, int renderType
)
537 struct dri_context
*pcp
, *pcp_shared
;
538 struct dri_screen
*psc
= (struct dri_screen
*) base
;
539 drm_context_t hwContext
;
540 __DRIcontext
*shared
= NULL
;
541 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
543 if (!psc
->base
.driScreen
)
547 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
548 shared
= pcp_shared
->driContext
;
551 pcp
= Xmalloc(sizeof *pcp
);
555 pcp
->psc
= &psc
->base
;
556 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
558 &pcp
->hwContextID
, &hwContext
)) {
564 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
566 renderType
, shared
, hwContext
, pcp
);
567 if (pcp
->driContext
== NULL
) {
568 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
573 pcp
->base
.destroyContext
= driDestroyContext
;
574 pcp
->base
.bindContext
= driBindContext
;
575 pcp
->base
.unbindContext
= driUnbindContext
;
581 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
583 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
584 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
586 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
587 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
591 static __GLXDRIdrawable
*
592 driCreateDrawable(__GLXscreenConfigs
*base
,
594 GLXDrawable drawable
, const __GLcontextModes
* modes
)
596 drm_drawable_t hwDrawable
;
597 void *empty_attribute_list
= NULL
;
598 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
599 struct dri_screen
*psc
= (struct dri_screen
*) base
;
600 struct dri_drawable
*pdp
;
602 /* Old dri can't handle GLX 1.3+ drawable constructors. */
603 if (xDrawable
!= drawable
)
606 pdp
= Xmalloc(sizeof *pdp
);
610 pdp
->base
.drawable
= drawable
;
611 pdp
->base
.psc
= &psc
->base
;
613 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
614 drawable
, &hwDrawable
)) {
619 /* Create a new drawable */
621 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
625 empty_attribute_list
, pdp
);
627 if (!pdp
->driDrawable
) {
628 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
633 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
639 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
642 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
643 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
645 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
650 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
651 int x
, int y
, int width
, int height
)
653 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
655 (*pdp
->base
.psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
656 x
, y
, width
, height
);
660 driDestroyScreen(__GLXscreenConfigs
*base
)
662 struct dri_screen
*psc
= (struct dri_screen
*) base
;
664 /* Free the direct rendering per screen data */
666 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
667 psc
->driScreen
= NULL
;
669 dlclose(psc
->driver
);
672 static const struct glx_context_vtable dri_context_vtable
= {
677 #ifdef __DRI_SWAP_BUFFER_COUNTER
680 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
681 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
683 struct dri_screen
*psc
= (struct dri_screen
*) base
;
684 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
686 if (pdp
&& psc
->sbc
&& psc
->msc
)
687 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
688 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
689 __glXGetUST(ust
) == 0 );
693 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
694 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
696 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
697 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
699 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
700 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
701 divisor
, remainder
, 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;
711 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
712 int64_t *msc
, int64_t *sbc
)
714 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
716 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
718 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
720 /* __glXGetUST returns zero on success and non-zero on failure.
721 * This function returns True on success and False on failure.
723 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
726 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
727 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
733 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
735 GLXContext gc
= __glXGetCurrentContext();
736 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
737 struct dri_screen
*psc
;
739 if (gc
->driContext
) {
740 psc
= (struct dri_screen
*) pdraw
->psc
;
742 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
743 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
748 return GLX_BAD_CONTEXT
;
752 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
754 GLXContext gc
= __glXGetCurrentContext();
755 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
756 struct dri_screen
*psc
;
758 if (gc
!= NULL
&& gc
->driContext
) {
759 psc
= (struct dri_screen
*) pdraw
->psc
;
761 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
762 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
769 /* Bind DRI1 specific extensions */
771 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
775 for (i
= 0; extensions
[i
]; i
++) {
776 /* No DRI2 support for swap_control at the moment, since SwapBuffers
777 * is done by the X server */
778 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
779 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
780 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
781 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
784 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
785 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
786 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
789 /* Ignore unknown extensions */
793 static __GLXscreenConfigs
*
794 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
796 struct dri_display
*pdp
;
798 const __DRIextension
**extensions
;
799 struct dri_screen
*psc
;
803 psc
= Xcalloc(1, sizeof *psc
);
807 memset(psc
, 0, sizeof *psc
);
808 if (!glx_screen_init(&psc
->base
, screen
, priv
))
811 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
816 psc
->driver
= driOpenDriver(driverName
);
818 if (psc
->driver
== NULL
) {
823 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
824 if (extensions
== NULL
) {
825 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
830 for (i
= 0; extensions
[i
]; i
++) {
831 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
832 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
833 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
834 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
837 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
842 pdp
= (struct dri_display
*) priv
->driDisplay
;
844 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
845 if (psc
->driScreen
== NULL
) {
846 dlclose(psc
->driver
);
851 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
852 driBindExtensions(psc
, extensions
);
853 driBindCommonExtensions(&psc
->base
, extensions
);
856 psc
->base
.driScreen
= psp
;
857 if (psc
->base
.driCopySubBuffer
)
858 psp
->copySubBuffer
= driCopySubBuffer
;
860 psp
->destroyScreen
= driDestroyScreen
;
861 psp
->createContext
= driCreateContext
;
862 psp
->createDrawable
= driCreateDrawable
;
863 psp
->swapBuffers
= driSwapBuffers
;
867 #ifdef __DRI_SWAP_BUFFER_COUNTER
868 psp
->getDrawableMSC
= driDrawableGetMSC
;
869 psp
->waitForMSC
= driWaitForMSC
;
870 psp
->waitForSBC
= driWaitForSBC
;
873 psp
->setSwapInterval
= driSetSwapInterval
;
874 psp
->getSwapInterval
= driGetSwapInterval
;
876 psc
->base
.direct_context_vtable
= &dri_context_vtable
;
881 /* Called from __glXFreeDisplayPrivate.
884 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
890 * Allocate, initialize and return a __DRIdisplayPrivate object.
891 * This is called from __glXInitialize() when we are given a new
894 _X_HIDDEN __GLXDRIdisplay
*
895 driCreateDisplay(Display
* dpy
)
897 struct dri_display
*pdpyp
;
898 int eventBase
, errorBase
;
899 int major
, minor
, patch
;
901 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
905 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
909 pdpyp
= Xmalloc(sizeof *pdpyp
);
914 pdpyp
->driMajor
= major
;
915 pdpyp
->driMinor
= minor
;
916 pdpyp
->driPatch
= patch
;
918 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
919 pdpyp
->base
.createScreen
= driCreateScreen
;
924 #endif /* GLX_DIRECT_RENDERING */