libGL: Consolidate DRI initialization in dri_glx.c

Move a lot of code over from glx_ext.c.
This commit is contained in:
Kristian Høgsberg 2008-03-07 00:45:54 -05:00
parent db7fc63110
commit 890d44e54f
3 changed files with 411 additions and 406 deletions

View File

@ -48,6 +48,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri_glx.h"
#include <sys/types.h>
#include <stdarg.h>
#include "glcontextmodes.h"
#include <sys/mman.h>
#include "xf86drm.h"
#ifndef RTLD_NOW
#define RTLD_NOW 0
@ -383,6 +387,409 @@ PUBLIC const char *glXGetDriverConfig (const char *driverName) {
return NULL;
}
static void
filter_modes( __GLcontextModes ** server_modes,
const __GLcontextModes * driver_modes )
{
__GLcontextModes * m;
__GLcontextModes ** prev_next;
const __GLcontextModes * check;
if (driver_modes == NULL) {
fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
return;
}
/* For each mode in server_modes, check to see if a matching mode exists
* in driver_modes. If not, then the mode is not available.
*/
prev_next = server_modes;
for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
GLboolean do_delete = GL_TRUE;
for ( check = driver_modes ; check != NULL ; check = check->next ) {
if ( _gl_context_modes_are_same( m, check ) ) {
do_delete = GL_FALSE;
break;
}
}
/* The 3D has to support all the modes that match the GLX visuals
* sent from the X server.
*/
if ( do_delete && (m->visualID != 0) ) {
do_delete = GL_FALSE;
/* don't warn for this visual (Novell #247471 / X.Org #6689) */
if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) {
fprintf(stderr, "libGL warning: 3D driver claims to not "
"support visual 0x%02x\n", m->visualID);
}
}
if ( do_delete ) {
*prev_next = m->next;
m->next = NULL;
_gl_context_modes_destroy( m );
}
else {
prev_next = & m->next;
}
}
}
#ifdef XDAMAGE_1_1_INTERFACE
static GLboolean has_damage_post(Display *dpy)
{
static GLboolean inited = GL_FALSE;
static GLboolean has_damage;
if (!inited) {
int major, minor;
if (XDamageQueryVersion(dpy, &major, &minor) &&
major == 1 && minor >= 1)
{
has_damage = GL_TRUE;
} else {
has_damage = GL_FALSE;
}
inited = GL_TRUE;
}
return has_damage;
}
#endif /* XDAMAGE_1_1_INTERFACE */
static void __glXReportDamage(__DRIdrawable *driDraw,
int x, int y,
drm_clip_rect_t *rects, int num_rects,
GLboolean front_buffer)
{
#ifdef XDAMAGE_1_1_INTERFACE
XRectangle *xrects;
XserverRegion region;
int i;
int x_off, y_off;
__GLXdrawable *glxDraw =
containerOf(driDraw, __GLXdrawable, driDrawable);
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
Drawable drawable;
if (!has_damage_post(dpy))
return;
if (front_buffer) {
x_off = x;
y_off = y;
drawable = RootWindow(dpy, psc->scr);
} else{
x_off = 0;
y_off = 0;
drawable = glxDraw->drawable;
}
xrects = malloc(sizeof(XRectangle) * num_rects);
if (xrects == NULL)
return;
for (i = 0; i < num_rects; i++) {
xrects[i].x = rects[i].x1 + x_off;
xrects[i].y = rects[i].y1 + y_off;
xrects[i].width = rects[i].x2 - rects[i].x1;
xrects[i].height = rects[i].y2 - rects[i].y1;
}
region = XFixesCreateRegion(dpy, xrects, num_rects);
free(xrects);
XDamageAdd(dpy, drawable, region);
XFixesDestroyRegion(dpy, region);
#endif
}
static GLboolean
__glXDRIGetDrawableInfo(__DRIdrawable *drawable,
unsigned int *index, unsigned int *stamp,
int *X, int *Y, int *W, int *H,
int *numClipRects, drm_clip_rect_t ** pClipRects,
int *backX, int *backY,
int *numBackClipRects, drm_clip_rect_t **pBackClipRects)
{
__GLXdrawable *glxDraw =
containerOf(drawable, __GLXdrawable, driDrawable);
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
index, stamp, X, Y, W, H,
numClipRects, pClipRects,
backX, backY,
numBackClipRects, pBackClipRects);
}
/**
* Table of functions exported by the loader to the driver.
*/
static const __DRIcontextModesExtension contextModesExtension = {
{ __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION },
_gl_context_modes_create,
_gl_context_modes_destroy,
};
static const __DRIsystemTimeExtension systemTimeExtension = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
__glXGetUST,
__driGetMscRateOML,
};
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
{ __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
__glXDRIGetDrawableInfo
};
static const __DRIdamageExtension damageExtension = {
{ __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
__glXReportDamage,
};
static const __DRIextension *loader_extensions[] = {
&contextModesExtension.base,
&systemTimeExtension.base,
&getDrawableInfoExtension.base,
&damageExtension.base,
NULL
};
/**
* Perform the required libGL-side initialization and call the client-side
* driver's \c __driCreateNewScreen function.
*
* \param dpy Display pointer.
* \param scrn Screen number on the display.
* \param psc DRI screen information.
* \param driDpy DRI display information.
* \param createNewScreen Pointer to the client-side driver's
* \c __driCreateNewScreen function.
* \returns A pointer to the \c __DRIscreenPrivate structure returned by
* the client-side driver on success, or \c NULL on failure.
*
* \todo This function needs to be modified to remove context-modes from the
* list stored in the \c __GLXscreenConfigsRec to match the list
* returned by the client-side driver.
*/
static void *
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
__DRIdisplay * driDpy,
PFNCREATENEWSCREENFUNC createNewScreen)
{
__DRIscreenPrivate *psp = NULL;
#ifndef GLX_USE_APPLEGL
drm_handle_t hSAREA;
drmAddress pSAREA = MAP_FAILED;
char *BusID;
__DRIversion ddx_version;
__DRIversion dri_version;
__DRIversion drm_version;
__DRIframebuffer framebuffer;
int fd = -1;
int status;
const char * err_msg;
const char * err_extra;
dri_version.major = driDpy->private->driMajor;
dri_version.minor = driDpy->private->driMinor;
dri_version.patch = driDpy->private->driPatch;
err_msg = "XF86DRIOpenConnection";
err_extra = NULL;
framebuffer.base = MAP_FAILED;
framebuffer.dev_priv = NULL;
if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
int newlyopened;
fd = drmOpenOnce(NULL,BusID, &newlyopened);
Xfree(BusID); /* No longer needed */
err_msg = "open DRM";
err_extra = strerror( -fd );
if (fd >= 0) {
drm_magic_t magic;
err_msg = "drmGetMagic";
err_extra = NULL;
if (!drmGetMagic(fd, &magic)) {
drmVersionPtr version = drmGetVersion(fd);
if (version) {
drm_version.major = version->version_major;
drm_version.minor = version->version_minor;
drm_version.patch = version->version_patchlevel;
drmFreeVersion(version);
}
else {
drm_version.major = -1;
drm_version.minor = -1;
drm_version.patch = -1;
}
err_msg = "XF86DRIAuthConnection";
if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
char *driverName;
/*
* Get device name (like "tdfx") and the ddx version
* numbers. We'll check the version in each DRI driver's
* "createNewScreen" function.
*/
err_msg = "XF86DRIGetClientDriverName";
if (XF86DRIGetClientDriverName(dpy, scrn,
&ddx_version.major,
&ddx_version.minor,
&ddx_version.patch,
&driverName)) {
drm_handle_t hFB;
int junk;
/* No longer needed. */
Xfree( driverName );
/*
* Get device-specific info. pDevPriv will point to a struct
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
* that has information about the screen size, depth, pitch,
* ancilliary buffers, DRM mmap handles, etc.
*/
err_msg = "XF86DRIGetDeviceInfo";
if (XF86DRIGetDeviceInfo(dpy, scrn,
&hFB,
&junk,
&framebuffer.size,
&framebuffer.stride,
&framebuffer.dev_priv_size,
&framebuffer.dev_priv)) {
framebuffer.width = DisplayWidth(dpy, scrn);
framebuffer.height = DisplayHeight(dpy, scrn);
/*
* Map the framebuffer region.
*/
status = drmMap(fd, hFB, framebuffer.size,
(drmAddressPtr)&framebuffer.base);
err_msg = "drmMap of framebuffer";
err_extra = strerror( -status );
if ( status == 0 ) {
/*
* Map the SAREA region. Further mmap regions
* may be setup in each DRI driver's
* "createNewScreen" function.
*/
status = drmMap(fd, hSAREA, SAREA_MAX,
&pSAREA);
err_msg = "drmMap of sarea";
err_extra = strerror( -status );
if ( status == 0 ) {
__GLcontextModes * driver_modes = NULL;
err_msg = "InitDriver";
err_extra = NULL;
psp = (*createNewScreen)(scrn,
&psc->driScreen,
& ddx_version,
& dri_version,
& drm_version,
& framebuffer,
pSAREA,
fd,
loader_extensions,
& driver_modes );
filter_modes(&psc->configs, driver_modes);
filter_modes(&psc->visuals, driver_modes);
_gl_context_modes_destroy(driver_modes);
}
}
}
}
}
}
}
}
if ( psp == NULL ) {
if ( pSAREA != MAP_FAILED ) {
(void)drmUnmap(pSAREA, SAREA_MAX);
}
if ( framebuffer.base != MAP_FAILED ) {
(void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
}
if ( framebuffer.dev_priv != NULL ) {
Xfree(framebuffer.dev_priv);
}
if ( fd >= 0 ) {
(void)drmCloseOnce(fd);
}
(void)XF86DRICloseConnection(dpy, scrn);
if ( err_extra != NULL ) {
fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
err_extra);
}
else {
fprintf(stderr, "libGL error: %s failed\n", err_msg );
}
fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
}
#endif /* !GLX_USE_APPLEGL */
return psp;
}
void
driCreateScreen(__GLXscreenConfigs *psc, int screen,
__GLXdisplayPrivate *priv)
{
/* Create drawable hash */
psc->drawHash = __glxHashCreate();
if ( psc->drawHash == NULL )
return;
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
/* Initialize the direct rendering per screen data and functions */
if (priv->driDisplay.private != NULL) {
/* FIXME: Should it be some sort of an error if createNewScreen[i]
* FIXME: is NULL?
*/
if (priv->driDisplay.createNewScreen &&
priv->driDisplay.createNewScreen[screen]) {
psc->driScreen.private =
CallCreateNewScreen(psc->dpy, screen, psc,
& priv->driDisplay,
priv->driDisplay.createNewScreen[screen] );
if (psc->driScreen.private != NULL)
__glXScrEnableDRIExtension(psc);
}
}
}
/* Called from __glXFreeDisplayPrivate.
*/

View File

@ -128,6 +128,8 @@ struct __DRIdriverRec {
** dependent methods.
*/
extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp);
extern void driCreateScreen(__GLXscreenConfigs *psc, int screen,
__GLXdisplayPrivate *priv);
extern __DRIdriver *driGetDriver(Display *dpy, int scrNum);

View File

@ -633,385 +633,6 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
config->haveStencilBuffer = (config->stencilBits > 0);
}
#ifdef GLX_DIRECT_RENDERING
static void
filter_modes( __GLcontextModes ** server_modes,
const __GLcontextModes * driver_modes )
{
__GLcontextModes * m;
__GLcontextModes ** prev_next;
const __GLcontextModes * check;
if (driver_modes == NULL) {
fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
return;
}
/* For each mode in server_modes, check to see if a matching mode exists
* in driver_modes. If not, then the mode is not available.
*/
prev_next = server_modes;
for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
GLboolean do_delete = GL_TRUE;
for ( check = driver_modes ; check != NULL ; check = check->next ) {
if ( _gl_context_modes_are_same( m, check ) ) {
do_delete = GL_FALSE;
break;
}
}
/* The 3D has to support all the modes that match the GLX visuals
* sent from the X server.
*/
if ( do_delete && (m->visualID != 0) ) {
do_delete = GL_FALSE;
/* don't warn for this visual (Novell #247471 / X.Org #6689) */
if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) {
fprintf(stderr, "libGL warning: 3D driver claims to not "
"support visual 0x%02x\n", m->visualID);
}
}
if ( do_delete ) {
*prev_next = m->next;
m->next = NULL;
_gl_context_modes_destroy( m );
}
else {
prev_next = & m->next;
}
}
}
#ifdef XDAMAGE_1_1_INTERFACE
static GLboolean has_damage_post(Display *dpy)
{
static GLboolean inited = GL_FALSE;
static GLboolean has_damage;
if (!inited) {
int major, minor;
if (XDamageQueryVersion(dpy, &major, &minor) &&
major == 1 && minor >= 1)
{
has_damage = GL_TRUE;
} else {
has_damage = GL_FALSE;
}
inited = GL_TRUE;
}
return has_damage;
}
#endif /* XDAMAGE_1_1_INTERFACE */
static void __glXReportDamage(__DRIdrawable *driDraw,
int x, int y,
drm_clip_rect_t *rects, int num_rects,
GLboolean front_buffer)
{
#ifdef XDAMAGE_1_1_INTERFACE
XRectangle *xrects;
XserverRegion region;
int i;
int x_off, y_off;
__GLXdrawable *glxDraw =
containerOf(driDraw, __GLXdrawable, driDrawable);
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
Drawable drawable;
if (!has_damage_post(dpy))
return;
if (front_buffer) {
x_off = x;
y_off = y;
drawable = RootWindow(dpy, psc->scr);
} else{
x_off = 0;
y_off = 0;
drawable = glxDraw->drawable;
}
xrects = malloc(sizeof(XRectangle) * num_rects);
if (xrects == NULL)
return;
for (i = 0; i < num_rects; i++) {
xrects[i].x = rects[i].x1 + x_off;
xrects[i].y = rects[i].y1 + y_off;
xrects[i].width = rects[i].x2 - rects[i].x1;
xrects[i].height = rects[i].y2 - rects[i].y1;
}
region = XFixesCreateRegion(dpy, xrects, num_rects);
free(xrects);
XDamageAdd(dpy, drawable, region);
XFixesDestroyRegion(dpy, region);
#endif
}
static GLboolean
__glXDRIGetDrawableInfo(__DRIdrawable *drawable,
unsigned int *index, unsigned int *stamp,
int *X, int *Y, int *W, int *H,
int *numClipRects, drm_clip_rect_t ** pClipRects,
int *backX, int *backY,
int *numBackClipRects, drm_clip_rect_t **pBackClipRects)
{
__GLXdrawable *glxDraw =
containerOf(drawable, __GLXdrawable, driDrawable);
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
index, stamp, X, Y, W, H,
numClipRects, pClipRects,
backX, backY,
numBackClipRects, pBackClipRects);
}
/**
* Table of functions exported by the loader to the driver.
*/
static const __DRIcontextModesExtension contextModesExtension = {
{ __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION },
_gl_context_modes_create,
_gl_context_modes_destroy,
};
static const __DRIsystemTimeExtension systemTimeExtension = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
__glXGetUST,
__driGetMscRateOML,
};
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
{ __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
__glXDRIGetDrawableInfo
};
static const __DRIdamageExtension damageExtension = {
{ __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
__glXReportDamage,
};
static const __DRIextension *loader_extensions[] = {
&contextModesExtension.base,
&systemTimeExtension.base,
&getDrawableInfoExtension.base,
&damageExtension.base,
NULL
};
/**
* Perform the required libGL-side initialization and call the client-side
* driver's \c __driCreateNewScreen function.
*
* \param dpy Display pointer.
* \param scrn Screen number on the display.
* \param psc DRI screen information.
* \param driDpy DRI display information.
* \param createNewScreen Pointer to the client-side driver's
* \c __driCreateNewScreen function.
* \returns A pointer to the \c __DRIscreenPrivate structure returned by
* the client-side driver on success, or \c NULL on failure.
*
* \todo This function needs to be modified to remove context-modes from the
* list stored in the \c __GLXscreenConfigsRec to match the list
* returned by the client-side driver.
*/
static void *
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
__DRIdisplay * driDpy,
PFNCREATENEWSCREENFUNC createNewScreen)
{
__DRIscreenPrivate *psp = NULL;
#ifndef GLX_USE_APPLEGL
drm_handle_t hSAREA;
drmAddress pSAREA = MAP_FAILED;
char *BusID;
__DRIversion ddx_version;
__DRIversion dri_version;
__DRIversion drm_version;
__DRIframebuffer framebuffer;
int fd = -1;
int status;
const char * err_msg;
const char * err_extra;
dri_version.major = driDpy->private->driMajor;
dri_version.minor = driDpy->private->driMinor;
dri_version.patch = driDpy->private->driPatch;
err_msg = "XF86DRIOpenConnection";
err_extra = NULL;
framebuffer.base = MAP_FAILED;
framebuffer.dev_priv = NULL;
if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
int newlyopened;
fd = drmOpenOnce(NULL,BusID, &newlyopened);
Xfree(BusID); /* No longer needed */
err_msg = "open DRM";
err_extra = strerror( -fd );
if (fd >= 0) {
drm_magic_t magic;
err_msg = "drmGetMagic";
err_extra = NULL;
if (!drmGetMagic(fd, &magic)) {
drmVersionPtr version = drmGetVersion(fd);
if (version) {
drm_version.major = version->version_major;
drm_version.minor = version->version_minor;
drm_version.patch = version->version_patchlevel;
drmFreeVersion(version);
}
else {
drm_version.major = -1;
drm_version.minor = -1;
drm_version.patch = -1;
}
err_msg = "XF86DRIAuthConnection";
if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
char *driverName;
/*
* Get device name (like "tdfx") and the ddx version
* numbers. We'll check the version in each DRI driver's
* "createNewScreen" function.
*/
err_msg = "XF86DRIGetClientDriverName";
if (XF86DRIGetClientDriverName(dpy, scrn,
&ddx_version.major,
&ddx_version.minor,
&ddx_version.patch,
&driverName)) {
drm_handle_t hFB;
int junk;
/* No longer needed. */
Xfree( driverName );
/*
* Get device-specific info. pDevPriv will point to a struct
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
* that has information about the screen size, depth, pitch,
* ancilliary buffers, DRM mmap handles, etc.
*/
err_msg = "XF86DRIGetDeviceInfo";
if (XF86DRIGetDeviceInfo(dpy, scrn,
&hFB,
&junk,
&framebuffer.size,
&framebuffer.stride,
&framebuffer.dev_priv_size,
&framebuffer.dev_priv)) {
framebuffer.width = DisplayWidth(dpy, scrn);
framebuffer.height = DisplayHeight(dpy, scrn);
/*
* Map the framebuffer region.
*/
status = drmMap(fd, hFB, framebuffer.size,
(drmAddressPtr)&framebuffer.base);
err_msg = "drmMap of framebuffer";
err_extra = strerror( -status );
if ( status == 0 ) {
/*
* Map the SAREA region. Further mmap regions
* may be setup in each DRI driver's
* "createNewScreen" function.
*/
status = drmMap(fd, hSAREA, SAREA_MAX,
&pSAREA);
err_msg = "drmMap of sarea";
err_extra = strerror( -status );
if ( status == 0 ) {
__GLcontextModes * driver_modes = NULL;
err_msg = "InitDriver";
err_extra = NULL;
psp = (*createNewScreen)(scrn,
&psc->driScreen,
& ddx_version,
& dri_version,
& drm_version,
& framebuffer,
pSAREA,
fd,
loader_extensions,
& driver_modes );
filter_modes(&psc->configs, driver_modes);
filter_modes(&psc->visuals, driver_modes);
_gl_context_modes_destroy(driver_modes);
}
}
}
}
}
}
}
}
if ( psp == NULL ) {
if ( pSAREA != MAP_FAILED ) {
(void)drmUnmap(pSAREA, SAREA_MAX);
}
if ( framebuffer.base != MAP_FAILED ) {
(void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
}
if ( framebuffer.dev_priv != NULL ) {
Xfree(framebuffer.dev_priv);
}
if ( fd >= 0 ) {
(void)drmCloseOnce(fd);
}
(void)XF86DRICloseConnection(dpy, scrn);
if ( err_extra != NULL ) {
fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
err_extra);
}
else {
fprintf(stderr, "libGL error: %s failed\n", err_msg );
}
fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
}
#endif /* !GLX_USE_APPLEGL */
return psp;
}
#endif /* GLX_DIRECT_RENDERING */
static __GLcontextModes *
createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
int screen, GLboolean tagged_only)
@ -1167,35 +788,10 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
getVisualConfigs(dpy, priv, i);
getFBConfigs(dpy, priv, i);
#ifdef GLX_DIRECT_RENDERING
psc->scr = i;
psc->dpy = dpy;
/* Create drawable hash */
psc->drawHash = __glxHashCreate();
if ( psc->drawHash == NULL ) {
SyncHandle();
FreeScreenConfigs(priv);
return GL_FALSE;
}
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
/* Initialize the direct rendering per screen data and functions */
if (priv->driDisplay.private != NULL) {
/* FIXME: Should it be some sort of an error if createNewScreen[i]
* FIXME: is NULL?
*/
if (priv->driDisplay.createNewScreen &&
priv->driDisplay.createNewScreen[i]) {
psc->driScreen.private =
CallCreateNewScreen(dpy, i, psc,
& priv->driDisplay,
priv->driDisplay.createNewScreen[i] );
if (psc->driScreen.private != NULL)
__glXScrEnableDRIExtension(psc);
}
}
#ifdef GLX_DIRECT_RENDERING
driCreateScreen(psc, i, priv);
#endif
}
SyncHandle();