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
= {
104 * Given a display pointer and screen number, determine the name of
105 * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
106 * Return True for success, False for failure.
109 driGetDriverName(Display
* dpy
, int scrNum
, char **driverName
)
114 int driverMajor
, driverMinor
, driverPatch
;
118 if (XF86DRIQueryExtension(dpy
, &event
, &error
)) { /* DRI1 */
119 if (!XF86DRIQueryDirectRenderingCapable(dpy
, scrNum
, &directCapable
)) {
120 ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
123 if (!directCapable
) {
124 ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
128 b
= XF86DRIGetClientDriverName(dpy
, scrNum
, &driverMajor
, &driverMinor
,
129 &driverPatch
, driverName
);
131 ErrorMessageF("Cannot determine driver name for screen %d\n",
136 InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
137 driverMajor
, driverMinor
, driverPatch
, *driverName
,
142 else if (DRI2QueryExtension(dpy
, &event
, &error
)) { /* DRI2 */
144 Bool ret
= DRI2Connect(dpy
, RootWindow(dpy
, scrNum
), driverName
, &dev
);
156 * Exported function for querying the DRI driver for a given screen.
158 * The returned char pointer points to a static array that will be
159 * overwritten by subsequent calls.
162 glXGetScreenDriver(Display
* dpy
, int scrNum
)
166 if (driGetDriverName(dpy
, scrNum
, &driverName
)) {
170 len
= strlen(driverName
);
173 memcpy(ret
, driverName
, len
+ 1);
181 * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
183 * The returned char pointer points directly into the driver. Therefore
184 * it should be treated as a constant.
186 * If the driver was not found or does not support configuration NULL is
189 * Note: The driver remains opened after this function returns.
192 glXGetDriverConfig(const char *driverName
)
194 void *handle
= driOpenDriver(driverName
);
196 return dlsym(handle
, "__driConfigOptions");
201 #ifdef XDAMAGE_1_1_INTERFACE
204 has_damage_post(Display
* dpy
)
206 static GLboolean inited
= GL_FALSE
;
207 static GLboolean has_damage
;
212 if (XDamageQueryVersion(dpy
, &major
, &minor
) &&
213 major
== 1 && minor
>= 1) {
214 has_damage
= GL_TRUE
;
217 has_damage
= GL_FALSE
;
226 __glXReportDamage(__DRIdrawable
* driDraw
,
228 drm_clip_rect_t
* rects
, int num_rects
,
229 GLboolean front_buffer
, void *loaderPrivate
)
232 XserverRegion region
;
235 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
236 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
237 Display
*dpy
= psc
->dpy
;
240 if (!has_damage_post(dpy
))
246 drawable
= RootWindow(dpy
, psc
->scr
);
251 drawable
= glxDraw
->xDrawable
;
254 xrects
= malloc(sizeof(XRectangle
) * num_rects
);
258 for (i
= 0; i
< num_rects
; i
++) {
259 xrects
[i
].x
= rects
[i
].x1
+ x_off
;
260 xrects
[i
].y
= rects
[i
].y1
+ y_off
;
261 xrects
[i
].width
= rects
[i
].x2
- rects
[i
].x1
;
262 xrects
[i
].height
= rects
[i
].y2
- rects
[i
].y1
;
264 region
= XFixesCreateRegion(dpy
, xrects
, num_rects
);
266 XDamageAdd(dpy
, drawable
, region
);
267 XFixesDestroyRegion(dpy
, region
);
270 static const __DRIdamageExtension damageExtension
= {
271 {__DRI_DAMAGE
, __DRI_DAMAGE_VERSION
},
278 __glXDRIGetDrawableInfo(__DRIdrawable
* drawable
,
279 unsigned int *index
, unsigned int *stamp
,
280 int *X
, int *Y
, int *W
, int *H
,
281 int *numClipRects
, drm_clip_rect_t
** pClipRects
,
282 int *backX
, int *backY
,
283 int *numBackClipRects
,
284 drm_clip_rect_t
** pBackClipRects
,
287 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
288 __GLXscreenConfigs
*psc
= glxDraw
->psc
;
289 Display
*dpy
= psc
->dpy
;
291 return XF86DRIGetDrawableInfo(dpy
, psc
->scr
, glxDraw
->drawable
,
292 index
, stamp
, X
, Y
, W
, H
,
293 numClipRects
, pClipRects
,
295 numBackClipRects
, pBackClipRects
);
298 static const __DRIgetDrawableInfoExtension getDrawableInfoExtension
= {
299 {__DRI_GET_DRAWABLE_INFO
, __DRI_GET_DRAWABLE_INFO_VERSION
},
300 __glXDRIGetDrawableInfo
303 static const __DRIextension
*loader_extensions
[] = {
304 &systemTimeExtension
.base
,
305 &getDrawableInfoExtension
.base
,
306 #ifdef XDAMAGE_1_1_INTERFACE
307 &damageExtension
.base
,
313 * Perform the required libGL-side initialization and call the client-side
314 * driver's \c __driCreateNewScreen function.
316 * \param dpy Display pointer.
317 * \param scrn Screen number on the display.
318 * \param psc DRI screen information.
319 * \param driDpy DRI display information.
320 * \param createNewScreen Pointer to the client-side driver's
321 * \c __driCreateNewScreen function.
322 * \returns A pointer to the \c __DRIscreen structure returned by
323 * the client-side driver on success, or \c NULL on failure.
326 CallCreateNewScreen(Display
*dpy
, int scrn
, struct dri_screen
*psc
,
327 struct dri_display
* driDpy
)
331 drmAddress pSAREA
= MAP_FAILED
;
333 __DRIversion ddx_version
;
334 __DRIversion dri_version
;
335 __DRIversion drm_version
;
336 __DRIframebuffer framebuffer
;
341 drmVersionPtr version
;
346 const __DRIconfig
**driver_configs
;
347 __GLcontextModes
*visual
;
349 /* DRI protocol version. */
350 dri_version
.major
= driDpy
->driMajor
;
351 dri_version
.minor
= driDpy
->driMinor
;
352 dri_version
.patch
= driDpy
->driPatch
;
354 framebuffer
.base
= MAP_FAILED
;
355 framebuffer
.dev_priv
= NULL
;
356 framebuffer
.size
= 0;
358 if (!XF86DRIOpenConnection(dpy
, scrn
, &hSAREA
, &BusID
)) {
359 ErrorMessageF("XF86DRIOpenConnection failed\n");
363 fd
= drmOpenOnce(NULL
, BusID
, &newlyopened
);
365 Xfree(BusID
); /* No longer needed */
368 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd
));
372 if (drmGetMagic(fd
, &magic
)) {
373 ErrorMessageF("drmGetMagic failed\n");
377 version
= drmGetVersion(fd
);
379 drm_version
.major
= version
->version_major
;
380 drm_version
.minor
= version
->version_minor
;
381 drm_version
.patch
= version
->version_patchlevel
;
382 drmFreeVersion(version
);
385 drm_version
.major
= -1;
386 drm_version
.minor
= -1;
387 drm_version
.patch
= -1;
390 if (newlyopened
&& !XF86DRIAuthConnection(dpy
, scrn
, magic
)) {
391 ErrorMessageF("XF86DRIAuthConnection failed\n");
395 /* Get device name (like "tdfx") and the ddx version numbers.
396 * We'll check the version in each DRI driver's "createNewScreen"
398 if (!XF86DRIGetClientDriverName(dpy
, scrn
,
401 &ddx_version
.patch
, &driverName
)) {
402 ErrorMessageF("XF86DRIGetClientDriverName failed\n");
406 Xfree(driverName
); /* No longer needed. */
409 * Get device-specific info. pDevPriv will point to a struct
410 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
411 * has information about the screen size, depth, pitch, ancilliary
412 * buffers, DRM mmap handles, etc.
414 if (!XF86DRIGetDeviceInfo(dpy
, scrn
, &hFB
, &junk
,
415 &framebuffer
.size
, &framebuffer
.stride
,
416 &framebuffer
.dev_priv_size
,
417 &framebuffer
.dev_priv
)) {
418 ErrorMessageF("XF86DRIGetDeviceInfo failed");
422 framebuffer
.width
= DisplayWidth(dpy
, scrn
);
423 framebuffer
.height
= DisplayHeight(dpy
, scrn
);
425 /* Map the framebuffer region. */
426 status
= drmMap(fd
, hFB
, framebuffer
.size
,
427 (drmAddressPtr
) & framebuffer
.base
);
429 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status
));
433 /* Map the SAREA region. Further mmap regions may be setup in
434 * each DRI driver's "createNewScreen" function.
436 status
= drmMap(fd
, hSAREA
, SAREA_MAX
, &pSAREA
);
438 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status
));
442 psp
= (*psc
->legacy
->createNewScreen
) (scrn
,
450 &driver_configs
, psc
);
453 ErrorMessageF("Calling driver entry point failed");
458 driConvertConfigs(psc
->core
, psc
->base
.configs
, driver_configs
);
460 driConvertConfigs(psc
->core
, psc
->base
.visuals
, driver_configs
);
462 psc
->driver_configs
= driver_configs
;
464 /* Visuals with depth != screen depth are subject to automatic compositing
465 * in the X server, so DRI1 can't render to them properly. Mark them as
466 * non-conformant to prevent apps from picking them up accidentally.
468 for (visual
= psc
->base
.visuals
; visual
; visual
= visual
->next
) {
469 XVisualInfo
template;
470 XVisualInfo
*visuals
;
474 template.visualid
= visual
->visualID
;
476 visuals
= XGetVisualInfo(dpy
, mask
, &template, &num_visuals
);
479 if (num_visuals
> 0 && visuals
->depth
!= DefaultDepth(dpy
, scrn
))
480 visual
->visualRating
= GLX_NON_CONFORMANT_CONFIG
;
489 if (pSAREA
!= MAP_FAILED
)
490 drmUnmap(pSAREA
, SAREA_MAX
);
492 if (framebuffer
.base
!= MAP_FAILED
)
493 drmUnmap((drmAddress
) framebuffer
.base
, framebuffer
.size
);
495 if (framebuffer
.dev_priv
!= NULL
)
496 Xfree(framebuffer
.dev_priv
);
501 XF86DRICloseConnection(dpy
, scrn
);
503 ErrorMessageF("reverting to software direct rendering\n");
509 driDestroyContext(__GLXcontext
* context
)
511 struct dri_context
*pcp
= (struct dri_context
*) context
;
512 struct dri_screen
*psc
= (struct dri_screen
*) context
->psc
;
514 (*psc
->core
->destroyContext
) (pcp
->driContext
);
516 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
521 driBindContext(__GLXcontext
*context
,
522 __GLXDRIdrawable
*draw
, __GLXDRIdrawable
*read
)
524 struct dri_context
*pcp
= (struct dri_context
*) context
;
525 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
526 struct dri_drawable
*pdr
= (struct dri_drawable
*) draw
;
527 struct dri_drawable
*prd
= (struct dri_drawable
*) read
;
529 return (*psc
->core
->bindContext
) (pcp
->driContext
,
530 pdr
->driDrawable
, prd
->driDrawable
);
534 driUnbindContext(__GLXcontext
* context
)
536 struct dri_context
*pcp
= (struct dri_context
*) context
;
537 struct dri_screen
*psc
= (struct dri_screen
*) pcp
->psc
;
539 (*psc
->core
->unbindContext
) (pcp
->driContext
);
542 static __GLXcontext
*
543 driCreateContext(__GLXscreenConfigs
*base
,
544 const __GLcontextModes
* mode
,
545 GLXContext shareList
, int renderType
)
547 struct dri_context
*pcp
, *pcp_shared
;
548 struct dri_screen
*psc
= (struct dri_screen
*) base
;
549 drm_context_t hwContext
;
550 __DRIcontext
*shared
= NULL
;
551 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) mode
;
553 if (!psc
->base
.driScreen
)
557 pcp_shared
= (struct dri_context
*) shareList
->driContext
;
558 shared
= pcp_shared
->driContext
;
561 pcp
= Xmalloc(sizeof *pcp
);
565 memset(pcp
, 0, sizeof *pcp
);
566 if (!glx_context_init(&pcp
->base
, &psc
->base
, mode
)) {
571 if (!XF86DRICreateContextWithConfig(psc
->base
.dpy
, psc
->base
.scr
,
573 &pcp
->hwContextID
, &hwContext
)) {
579 (*psc
->legacy
->createNewContext
) (psc
->driScreen
,
581 renderType
, shared
, hwContext
, pcp
);
582 if (pcp
->driContext
== NULL
) {
583 XF86DRIDestroyContext(psc
->base
.dpy
, psc
->base
.scr
, pcp
->hwContextID
);
588 pcp
->base
.vtable
= &dri_context_vtable
;
589 pcp
->base
.driContext
= &pcp
->dri_vtable
;
590 pcp
->dri_vtable
.destroyContext
= driDestroyContext
;
591 pcp
->dri_vtable
.bindContext
= driBindContext
;
592 pcp
->dri_vtable
.unbindContext
= driUnbindContext
;
598 driDestroyDrawable(__GLXDRIdrawable
* pdraw
)
600 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
601 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
603 (*psc
->core
->destroyDrawable
) (pdp
->driDrawable
);
604 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, pdraw
->drawable
);
608 static __GLXDRIdrawable
*
609 driCreateDrawable(__GLXscreenConfigs
*base
,
611 GLXDrawable drawable
, const __GLcontextModes
* modes
)
613 drm_drawable_t hwDrawable
;
614 void *empty_attribute_list
= NULL
;
615 __GLXDRIconfigPrivate
*config
= (__GLXDRIconfigPrivate
*) modes
;
616 struct dri_screen
*psc
= (struct dri_screen
*) base
;
617 struct dri_drawable
*pdp
;
619 /* Old dri can't handle GLX 1.3+ drawable constructors. */
620 if (xDrawable
!= drawable
)
623 pdp
= Xmalloc(sizeof *pdp
);
627 pdp
->base
.drawable
= drawable
;
628 pdp
->base
.psc
= &psc
->base
;
630 if (!XF86DRICreateDrawable(psc
->base
.dpy
, psc
->base
.scr
,
631 drawable
, &hwDrawable
)) {
636 /* Create a new drawable */
638 (*psc
->legacy
->createNewDrawable
) (psc
->driScreen
,
642 empty_attribute_list
, pdp
);
644 if (!pdp
->driDrawable
) {
645 XF86DRIDestroyDrawable(psc
->base
.dpy
, psc
->base
.scr
, drawable
);
650 pdp
->base
.destroyDrawable
= driDestroyDrawable
;
656 driSwapBuffers(__GLXDRIdrawable
* pdraw
, int64_t unused1
, int64_t unused2
,
659 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
660 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
662 (*psc
->core
->swapBuffers
) (pdp
->driDrawable
);
667 driCopySubBuffer(__GLXDRIdrawable
* pdraw
,
668 int x
, int y
, int width
, int height
)
670 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
671 struct dri_screen
*psc
= (struct dri_screen
*) pdp
->base
.psc
;
673 (*psc
->driCopySubBuffer
->copySubBuffer
) (pdp
->driDrawable
,
674 x
, y
, width
, height
);
678 driDestroyScreen(__GLXscreenConfigs
*base
)
680 struct dri_screen
*psc
= (struct dri_screen
*) base
;
682 /* Free the direct rendering per screen data */
684 (*psc
->core
->destroyScreen
) (psc
->driScreen
);
685 driDestroyConfigs(psc
->driver_configs
);
686 psc
->driScreen
= NULL
;
688 dlclose(psc
->driver
);
691 #ifdef __DRI_SWAP_BUFFER_COUNTER
694 driDrawableGetMSC(__GLXscreenConfigs
*base
, __GLXDRIdrawable
*pdraw
,
695 int64_t *ust
, int64_t *msc
, int64_t *sbc
)
697 struct dri_screen
*psc
= (struct dri_screen
*) base
;
698 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
700 if (pdp
&& psc
->sbc
&& psc
->msc
)
701 return ( (*psc
->msc
->getMSC
)(psc
->driScreen
, msc
) == 0 &&
702 (*psc
->sbc
->getSBC
)(pdp
->driDrawable
, sbc
) == 0 &&
703 __glXGetUST(ust
) == 0 );
707 driWaitForMSC(__GLXDRIdrawable
*pdraw
, int64_t target_msc
, int64_t divisor
,
708 int64_t remainder
, int64_t *ust
, int64_t *msc
, int64_t *sbc
)
710 struct dri_screen
*psc
= (struct dri_screen
*) pdraw
->psc
;
711 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
713 if (pdp
!= NULL
&& psc
->msc
!= NULL
) {
714 ret
= (*psc
->msc
->waitForMSC
) (pdp
->driDrawable
, target_msc
,
715 divisor
, remainder
, msc
, sbc
);
717 /* __glXGetUST returns zero on success and non-zero on failure.
718 * This function returns True on success and False on failure.
720 return ret
== 0 && __glXGetUST(ust
) == 0;
725 driWaitForSBC(__GLXDRIdrawable
*pdraw
, int64_t target_sbc
, int64_t *ust
,
726 int64_t *msc
, int64_t *sbc
)
728 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
730 if (pdp
!= NULL
&& psc
->sbc
!= NULL
) {
732 (*psc
->sbc
->waitForSBC
) (pdp
->driDrawable
, target_sbc
, msc
, sbc
);
734 /* __glXGetUST returns zero on success and non-zero on failure.
735 * This function returns True on success and False on failure.
737 return ((ret
== 0) && (__glXGetUST(ust
) == 0));
740 return DRI2WaitSBC(pdp
->base
.psc
->dpy
,
741 pdp
->base
.xDrawable
, target_sbc
, ust
, msc
, sbc
);
747 driSetSwapInterval(__GLXDRIdrawable
*pdraw
, int interval
)
749 GLXContext gc
= __glXGetCurrentContext();
750 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
751 struct dri_screen
*psc
;
753 if (gc
->driContext
) {
754 psc
= (struct dri_screen
*) pdraw
->psc
;
756 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
757 psc
->swapControl
->setSwapInterval(pdp
->driDrawable
, interval
);
762 return GLX_BAD_CONTEXT
;
766 driGetSwapInterval(__GLXDRIdrawable
*pdraw
)
768 GLXContext gc
= __glXGetCurrentContext();
769 struct dri_drawable
*pdp
= (struct dri_drawable
*) pdraw
;
770 struct dri_screen
*psc
;
772 if (gc
!= NULL
&& gc
->driContext
) {
773 psc
= (struct dri_screen
*) pdraw
->psc
;
775 if (psc
->swapControl
!= NULL
&& pdraw
!= NULL
) {
776 return psc
->swapControl
->getSwapInterval(pdp
->driDrawable
);
783 /* Bind DRI1 specific extensions */
785 driBindExtensions(struct dri_screen
*psc
, const __DRIextension
**extensions
)
789 for (i
= 0; extensions
[i
]; i
++) {
790 /* No DRI2 support for swap_control at the moment, since SwapBuffers
791 * is done by the X server */
792 if (strcmp(extensions
[i
]->name
, __DRI_SWAP_CONTROL
) == 0) {
793 psc
->swapControl
= (__DRIswapControlExtension
*) extensions
[i
];
794 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_swap_control");
795 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_swap_control");
798 if (strcmp(extensions
[i
]->name
, __DRI_MEDIA_STREAM_COUNTER
) == 0) {
799 psc
->msc
= (__DRImediaStreamCounterExtension
*) extensions
[i
];
800 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_video_sync");
803 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
804 psc
->driCopySubBuffer
= (__DRIcopySubBufferExtension
*) extensions
[i
];
805 __glXEnableDirectExtension(&psc
->base
, "GLX_MESA_copy_sub_buffer");
808 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
809 __glXEnableDirectExtension(&psc
->base
, "GLX_SGI_make_current_read");
811 /* Ignore unknown extensions */
815 static __GLXscreenConfigs
*
816 driCreateScreen(int screen
, __GLXdisplayPrivate
*priv
)
818 struct dri_display
*pdp
;
820 const __DRIextension
**extensions
;
821 struct dri_screen
*psc
;
825 psc
= Xcalloc(1, sizeof *psc
);
829 memset(psc
, 0, sizeof *psc
);
830 if (!glx_screen_init(&psc
->base
, screen
, priv
))
833 if (!driGetDriverName(priv
->dpy
, screen
, &driverName
)) {
838 psc
->driver
= driOpenDriver(driverName
);
840 if (psc
->driver
== NULL
) {
845 extensions
= dlsym(psc
->driver
, __DRI_DRIVER_EXTENSIONS
);
846 if (extensions
== NULL
) {
847 ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
852 for (i
= 0; extensions
[i
]; i
++) {
853 if (strcmp(extensions
[i
]->name
, __DRI_CORE
) == 0)
854 psc
->core
= (__DRIcoreExtension
*) extensions
[i
];
855 if (strcmp(extensions
[i
]->name
, __DRI_LEGACY
) == 0)
856 psc
->legacy
= (__DRIlegacyExtension
*) extensions
[i
];
859 if (psc
->core
== NULL
|| psc
->legacy
== NULL
) {
864 pdp
= (struct dri_display
*) priv
->driDisplay
;
866 CallCreateNewScreen(psc
->base
.dpy
, screen
, psc
, pdp
);
867 if (psc
->driScreen
== NULL
) {
868 dlclose(psc
->driver
);
873 extensions
= psc
->core
->getExtensions(psc
->driScreen
);
874 driBindExtensions(psc
, extensions
);
877 psc
->base
.driScreen
= psp
;
878 if (psc
->driCopySubBuffer
)
879 psp
->copySubBuffer
= driCopySubBuffer
;
881 psp
->destroyScreen
= driDestroyScreen
;
882 psp
->createContext
= driCreateContext
;
883 psp
->createDrawable
= driCreateDrawable
;
884 psp
->swapBuffers
= driSwapBuffers
;
886 #ifdef __DRI_SWAP_BUFFER_COUNTER
887 psp
->getDrawableMSC
= driDrawableGetMSC
;
888 psp
->waitForMSC
= driWaitForMSC
;
889 psp
->waitForSBC
= driWaitForSBC
;
892 psp
->setSwapInterval
= driSetSwapInterval
;
893 psp
->getSwapInterval
= driGetSwapInterval
;
898 /* Called from __glXFreeDisplayPrivate.
901 driDestroyDisplay(__GLXDRIdisplay
* dpy
)
907 * Allocate, initialize and return a __DRIdisplayPrivate object.
908 * This is called from __glXInitialize() when we are given a new
911 _X_HIDDEN __GLXDRIdisplay
*
912 driCreateDisplay(Display
* dpy
)
914 struct dri_display
*pdpyp
;
915 int eventBase
, errorBase
;
916 int major
, minor
, patch
;
918 if (!XF86DRIQueryExtension(dpy
, &eventBase
, &errorBase
)) {
922 if (!XF86DRIQueryVersion(dpy
, &major
, &minor
, &patch
)) {
926 pdpyp
= Xmalloc(sizeof *pdpyp
);
931 pdpyp
->driMajor
= major
;
932 pdpyp
->driMinor
= minor
;
933 pdpyp
->driPatch
= patch
;
935 pdpyp
->base
.destroyDisplay
= driDestroyDisplay
;
936 pdpyp
->base
.createScreen
= driCreateScreen
;
941 #endif /* GLX_DIRECT_RENDERING */