Home | History | Annotate | Download | only in glx
      1 /*
      2  * Copyright 2008 George Sapountzis
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21  * SOFTWARE.
     22  */
     23 
     24 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
     25 
     26 #include <X11/Xlib.h>
     27 #include "glxclient.h"
     28 #include <dlfcn.h>
     29 #include "dri_common.h"
     30 #include "drisw_priv.h"
     31 
     32 static Bool
     33 XCreateDrawable(struct drisw_drawable * pdp,
     34                 Display * dpy, XID drawable, int visualid)
     35 {
     36    XGCValues gcvalues;
     37    long visMask;
     38    XVisualInfo visTemp;
     39    int num_visuals;
     40 
     41    /* create GC's */
     42    pdp->gc = XCreateGC(dpy, drawable, 0, NULL);
     43    pdp->swapgc = XCreateGC(dpy, drawable, 0, NULL);
     44 
     45    gcvalues.function = GXcopy;
     46    gcvalues.graphics_exposures = False;
     47    XChangeGC(dpy, pdp->gc, GCFunction, &gcvalues);
     48    XChangeGC(dpy, pdp->swapgc, GCFunction, &gcvalues);
     49    XChangeGC(dpy, pdp->swapgc, GCGraphicsExposures, &gcvalues);
     50 
     51    /* visual */
     52    visTemp.visualid = visualid;
     53    visMask = VisualIDMask;
     54    pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals);
     55 
     56    if (!pdp->visinfo || num_visuals == 0)
     57       return False;
     58 
     59    /* create XImage */
     60    pdp->ximage = XCreateImage(dpy,
     61                               pdp->visinfo->visual,
     62                               pdp->visinfo->depth,
     63                               ZPixmap, 0,             /* format, offset */
     64                               NULL,                   /* data */
     65                               0, 0,                   /* width, height */
     66                               32,                     /* bitmap_pad */
     67                               0);                     /* bytes_per_line */
     68 
     69   /**
     70    * swrast does not handle 24-bit depth with 24 bpp, so let X do the
     71    * the conversion for us.
     72    */
     73   if (pdp->ximage->bits_per_pixel == 24)
     74      pdp->ximage->bits_per_pixel = 32;
     75 
     76    return True;
     77 }
     78 
     79 static void
     80 XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable)
     81 {
     82    XDestroyImage(pdp->ximage);
     83    free(pdp->visinfo);
     84 
     85    XFreeGC(dpy, pdp->gc);
     86    XFreeGC(dpy, pdp->swapgc);
     87 }
     88 
     89 /**
     90  * swrast loader functions
     91  */
     92 
     93 static void
     94 swrastGetDrawableInfo(__DRIdrawable * draw,
     95                       int *x, int *y, int *w, int *h,
     96                       void *loaderPrivate)
     97 {
     98    struct drisw_drawable *pdp = loaderPrivate;
     99    __GLXDRIdrawable *pdraw = &(pdp->base);
    100    Display *dpy = pdraw->psc->dpy;
    101    Drawable drawable;
    102 
    103    Window root;
    104    unsigned uw, uh, bw, depth;
    105 
    106    drawable = pdraw->xDrawable;
    107 
    108    XGetGeometry(dpy, drawable, &root, x, y, &uw, &uh, &bw, &depth);
    109    *w = uw;
    110    *h = uh;
    111 }
    112 
    113 /**
    114  * Align renderbuffer pitch.
    115  *
    116  * This should be chosen by the driver and the loader (libGL, xserver/glx)
    117  * should use the driver provided pitch.
    118  *
    119  * It seems that the xorg loader (that is the xserver loading swrast_dri for
    120  * indirect rendering, not client-side libGL) requires that the pitch is
    121  * exactly the image width padded to 32 bits. XXX
    122  *
    123  * The above restriction can probably be overcome by using ScratchPixmap and
    124  * CopyArea in the xserver, similar to ShmPutImage, and setting the width of
    125  * the scratch pixmap to 'pitch / cpp'.
    126  */
    127 static inline int
    128 bytes_per_line(unsigned pitch_bits, unsigned mul)
    129 {
    130    unsigned mask = mul - 1;
    131 
    132    return ((pitch_bits + mask) & ~mask) / 8;
    133 }
    134 
    135 static void
    136 swrastPutImage2(__DRIdrawable * draw, int op,
    137                 int x, int y, int w, int h, int stride,
    138                 char *data, void *loaderPrivate)
    139 {
    140    struct drisw_drawable *pdp = loaderPrivate;
    141    __GLXDRIdrawable *pdraw = &(pdp->base);
    142    Display *dpy = pdraw->psc->dpy;
    143    Drawable drawable;
    144    XImage *ximage;
    145    GC gc;
    146 
    147    switch (op) {
    148    case __DRI_SWRAST_IMAGE_OP_DRAW:
    149       gc = pdp->gc;
    150       break;
    151    case __DRI_SWRAST_IMAGE_OP_SWAP:
    152       gc = pdp->swapgc;
    153       break;
    154    default:
    155       return;
    156    }
    157 
    158    drawable = pdraw->xDrawable;
    159 
    160    ximage = pdp->ximage;
    161    ximage->data = data;
    162    ximage->width = w;
    163    ximage->height = h;
    164    ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
    165 
    166    XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
    167 
    168    ximage->data = NULL;
    169 }
    170 
    171 static void
    172 swrastPutImage(__DRIdrawable * draw, int op,
    173                int x, int y, int w, int h,
    174                char *data, void *loaderPrivate)
    175 {
    176    swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate);
    177 }
    178 
    179 static void
    180 swrastGetImage2(__DRIdrawable * read,
    181                 int x, int y, int w, int h, int stride,
    182                 char *data, void *loaderPrivate)
    183 {
    184    struct drisw_drawable *prp = loaderPrivate;
    185    __GLXDRIdrawable *pread = &(prp->base);
    186    Display *dpy = pread->psc->dpy;
    187    Drawable readable;
    188    XImage *ximage;
    189 
    190    readable = pread->xDrawable;
    191 
    192    ximage = prp->ximage;
    193    ximage->data = data;
    194    ximage->width = w;
    195    ximage->height = h;
    196    ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
    197 
    198    XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
    199 
    200    ximage->data = NULL;
    201 }
    202 
    203 static void
    204 swrastGetImage(__DRIdrawable * read,
    205                int x, int y, int w, int h,
    206                char *data, void *loaderPrivate)
    207 {
    208    swrastGetImage2(read, x, y, w, h, 0, data, loaderPrivate);
    209 }
    210 
    211 static const __DRIswrastLoaderExtension swrastLoaderExtension = {
    212    .base = {__DRI_SWRAST_LOADER, 3 },
    213 
    214    .getDrawableInfo     = swrastGetDrawableInfo,
    215    .putImage            = swrastPutImage,
    216    .getImage            = swrastGetImage,
    217    .putImage2           = swrastPutImage2,
    218    .getImage2           = swrastGetImage2,
    219 };
    220 
    221 static const __DRIextension *loader_extensions[] = {
    222    &swrastLoaderExtension.base,
    223    NULL
    224 };
    225 
    226 /**
    227  * GLXDRI functions
    228  */
    229 
    230 static void
    231 drisw_destroy_context(struct glx_context *context)
    232 {
    233    struct drisw_context *pcp = (struct drisw_context *) context;
    234    struct drisw_screen *psc = (struct drisw_screen *) context->psc;
    235 
    236    driReleaseDrawables(&pcp->base);
    237 
    238    free((char *) context->extensions);
    239 
    240    (*psc->core->destroyContext) (pcp->driContext);
    241 
    242    free(pcp);
    243 }
    244 
    245 static int
    246 drisw_bind_context(struct glx_context *context, struct glx_context *old,
    247 		   GLXDrawable draw, GLXDrawable read)
    248 {
    249    struct drisw_context *pcp = (struct drisw_context *) context;
    250    struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
    251    struct drisw_drawable *pdraw, *pread;
    252 
    253    pdraw = (struct drisw_drawable *) driFetchDrawable(context, draw);
    254    pread = (struct drisw_drawable *) driFetchDrawable(context, read);
    255 
    256    driReleaseDrawables(&pcp->base);
    257 
    258    if ((*psc->core->bindContext) (pcp->driContext,
    259                                   pdraw ? pdraw->driDrawable : NULL,
    260                                   pread ? pread->driDrawable : NULL))
    261       return Success;
    262 
    263    return GLXBadContext;
    264 }
    265 
    266 static void
    267 drisw_unbind_context(struct glx_context *context, struct glx_context *new)
    268 {
    269    struct drisw_context *pcp = (struct drisw_context *) context;
    270    struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
    271 
    272    (*psc->core->unbindContext) (pcp->driContext);
    273 }
    274 
    275 static void
    276 drisw_bind_tex_image(Display * dpy,
    277 		    GLXDrawable drawable,
    278 		    int buffer, const int *attrib_list)
    279 {
    280    struct glx_context *gc = __glXGetCurrentContext();
    281    struct drisw_context *pcp = (struct drisw_context *) gc;
    282    __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
    283    struct drisw_drawable *pdraw = (struct drisw_drawable *) base;
    284    struct drisw_screen *psc;
    285 
    286    __glXInitialize(dpy);
    287 
    288    if (pdraw != NULL) {
    289       psc = (struct drisw_screen *) base->psc;
    290 
    291       if (!psc->texBuffer)
    292          return;
    293 
    294       if (psc->texBuffer->base.version >= 2 &&
    295         psc->texBuffer->setTexBuffer2 != NULL) {
    296 	      (*psc->texBuffer->setTexBuffer2) (pcp->driContext,
    297 					   pdraw->base.textureTarget,
    298 					   pdraw->base.textureFormat,
    299 					   pdraw->driDrawable);
    300       }
    301       else {
    302 	      (*psc->texBuffer->setTexBuffer) (pcp->driContext,
    303 					  pdraw->base.textureTarget,
    304 					  pdraw->driDrawable);
    305       }
    306    }
    307 }
    308 
    309 static void
    310 drisw_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
    311 {
    312    struct glx_context *gc = __glXGetCurrentContext();
    313    struct drisw_context *pcp = (struct drisw_context *) gc;
    314    __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
    315    struct glx_display *dpyPriv = __glXInitialize(dpy);
    316    struct drisw_drawable *pdraw = (struct drisw_drawable *) base;
    317    struct drisw_screen *psc;
    318 
    319    if (dpyPriv != NULL && pdraw != NULL) {
    320       psc = (struct drisw_screen *) base->psc;
    321 
    322       if (!psc->texBuffer)
    323          return;
    324 
    325       if (psc->texBuffer->base.version >= 3 &&
    326           psc->texBuffer->releaseTexBuffer != NULL) {
    327          (*psc->texBuffer->releaseTexBuffer) (pcp->driContext,
    328                                            pdraw->base.textureTarget,
    329                                            pdraw->driDrawable);
    330       }
    331    }
    332 }
    333 
    334 static const struct glx_context_vtable drisw_context_vtable = {
    335    .destroy             = drisw_destroy_context,
    336    .bind                = drisw_bind_context,
    337    .unbind              = drisw_unbind_context,
    338    .wait_gl             = NULL,
    339    .wait_x              = NULL,
    340    .use_x_font          = DRI_glXUseXFont,
    341    .bind_tex_image      = drisw_bind_tex_image,
    342    .release_tex_image   = drisw_release_tex_image,
    343    .get_proc_address    = NULL,
    344 };
    345 
    346 static struct glx_context *
    347 drisw_create_context(struct glx_screen *base,
    348 		     struct glx_config *config_base,
    349 		     struct glx_context *shareList, int renderType)
    350 {
    351    struct drisw_context *pcp, *pcp_shared;
    352    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
    353    struct drisw_screen *psc = (struct drisw_screen *) base;
    354    __DRIcontext *shared = NULL;
    355 
    356    if (!psc->base.driScreen)
    357       return NULL;
    358 
    359    /* Check the renderType value */
    360    if (!validate_renderType_against_config(config_base, renderType))
    361        return NULL;
    362 
    363    if (shareList) {
    364       /* If the shareList context is not a DRISW context, we cannot possibly
    365        * create a DRISW context that shares it.
    366        */
    367       if (shareList->vtable->destroy != drisw_destroy_context) {
    368 	 return NULL;
    369       }
    370 
    371       pcp_shared = (struct drisw_context *) shareList;
    372       shared = pcp_shared->driContext;
    373    }
    374 
    375    pcp = calloc(1, sizeof *pcp);
    376    if (pcp == NULL)
    377       return NULL;
    378 
    379    if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
    380       free(pcp);
    381       return NULL;
    382    }
    383 
    384    pcp->base.renderType = renderType;
    385 
    386    pcp->driContext =
    387       (*psc->core->createNewContext) (psc->driScreen,
    388 				      config->driConfig, shared, pcp);
    389    if (pcp->driContext == NULL) {
    390       free(pcp);
    391       return NULL;
    392    }
    393 
    394    pcp->base.vtable = &drisw_context_vtable;
    395 
    396    return &pcp->base;
    397 }
    398 
    399 static struct glx_context *
    400 drisw_create_context_attribs(struct glx_screen *base,
    401 			     struct glx_config *config_base,
    402 			     struct glx_context *shareList,
    403 			     unsigned num_attribs,
    404 			     const uint32_t *attribs,
    405 			     unsigned *error)
    406 {
    407    struct drisw_context *pcp, *pcp_shared;
    408    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
    409    struct drisw_screen *psc = (struct drisw_screen *) base;
    410    __DRIcontext *shared = NULL;
    411 
    412    uint32_t minor_ver;
    413    uint32_t major_ver;
    414    uint32_t renderType;
    415    uint32_t flags;
    416    unsigned api;
    417    int reset;
    418    int release;
    419    uint32_t ctx_attribs[2 * 5];
    420    unsigned num_ctx_attribs = 0;
    421 
    422    if (!psc->base.driScreen)
    423       return NULL;
    424 
    425    if (psc->swrast->base.version < 3)
    426       return NULL;
    427 
    428    /* Remap the GLX tokens to DRI2 tokens.
    429     */
    430    if (!dri2_convert_glx_attribs(num_attribs, attribs,
    431                                  &major_ver, &minor_ver, &renderType, &flags,
    432                                  &api, &reset, &release, error))
    433       return NULL;
    434 
    435    /* Check the renderType value */
    436    if (!validate_renderType_against_config(config_base, renderType)) {
    437        return NULL;
    438    }
    439 
    440    if (reset != __DRI_CTX_RESET_NO_NOTIFICATION)
    441       return NULL;
    442 
    443    if (release != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH &&
    444        release != __DRI_CTX_RELEASE_BEHAVIOR_NONE)
    445       return NULL;
    446 
    447    if (shareList) {
    448       pcp_shared = (struct drisw_context *) shareList;
    449       shared = pcp_shared->driContext;
    450    }
    451 
    452    pcp = calloc(1, sizeof *pcp);
    453    if (pcp == NULL)
    454       return NULL;
    455 
    456    if (!glx_context_init(&pcp->base, &psc->base, config_base)) {
    457       free(pcp);
    458       return NULL;
    459    }
    460 
    461    ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
    462    ctx_attribs[num_ctx_attribs++] = major_ver;
    463    ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
    464    ctx_attribs[num_ctx_attribs++] = minor_ver;
    465    if (release != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH) {
    466        ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR;
    467        ctx_attribs[num_ctx_attribs++] = release;
    468    }
    469 
    470    if (flags != 0) {
    471       ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS;
    472 
    473       /* The current __DRI_CTX_FLAG_* values are identical to the
    474        * GLX_CONTEXT_*_BIT values.
    475        */
    476       ctx_attribs[num_ctx_attribs++] = flags;
    477    }
    478 
    479    pcp->base.renderType = renderType;
    480 
    481    pcp->driContext =
    482       (*psc->swrast->createContextAttribs) (psc->driScreen,
    483 					    api,
    484 					    config ? config->driConfig : 0,
    485 					    shared,
    486 					    num_ctx_attribs / 2,
    487 					    ctx_attribs,
    488 					    error,
    489 					    pcp);
    490    if (pcp->driContext == NULL) {
    491       free(pcp);
    492       return NULL;
    493    }
    494 
    495    pcp->base.vtable = &drisw_context_vtable;
    496 
    497    return &pcp->base;
    498 }
    499 
    500 static void
    501 driswDestroyDrawable(__GLXDRIdrawable * pdraw)
    502 {
    503    struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
    504    struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
    505 
    506    (*psc->core->destroyDrawable) (pdp->driDrawable);
    507 
    508    XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
    509    free(pdp);
    510 }
    511 
    512 static __GLXDRIdrawable *
    513 driswCreateDrawable(struct glx_screen *base, XID xDrawable,
    514 		    GLXDrawable drawable, struct glx_config *modes)
    515 {
    516    struct drisw_drawable *pdp;
    517    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
    518    struct drisw_screen *psc = (struct drisw_screen *) base;
    519    Bool ret;
    520    const __DRIswrastExtension *swrast = psc->swrast;
    521 
    522    pdp = calloc(1, sizeof(*pdp));
    523    if (!pdp)
    524       return NULL;
    525 
    526    pdp->base.xDrawable = xDrawable;
    527    pdp->base.drawable = drawable;
    528    pdp->base.psc = &psc->base;
    529 
    530    ret = XCreateDrawable(pdp, psc->base.dpy, xDrawable, modes->visualID);
    531    if (!ret) {
    532       free(pdp);
    533       return NULL;
    534    }
    535 
    536    /* Create a new drawable */
    537    pdp->driDrawable =
    538       (*swrast->createNewDrawable) (psc->driScreen, config->driConfig, pdp);
    539 
    540    if (!pdp->driDrawable) {
    541       XDestroyDrawable(pdp, psc->base.dpy, xDrawable);
    542       free(pdp);
    543       return NULL;
    544    }
    545 
    546    pdp->base.destroyDrawable = driswDestroyDrawable;
    547 
    548    return &pdp->base;
    549 }
    550 
    551 static int64_t
    552 driswSwapBuffers(__GLXDRIdrawable * pdraw,
    553                  int64_t target_msc, int64_t divisor, int64_t remainder,
    554                  Bool flush)
    555 {
    556    struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
    557    struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
    558 
    559    (void) target_msc;
    560    (void) divisor;
    561    (void) remainder;
    562 
    563    if (flush) {
    564       glFlush();
    565    }
    566 
    567    (*psc->core->swapBuffers) (pdp->driDrawable);
    568 
    569    return 0;
    570 }
    571 
    572 static void
    573 driswCopySubBuffer(__GLXDRIdrawable * pdraw,
    574                    int x, int y, int width, int height, Bool flush)
    575 {
    576    struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
    577    struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
    578 
    579    if (flush) {
    580       glFlush();
    581    }
    582 
    583    (*psc->copySubBuffer->copySubBuffer) (pdp->driDrawable,
    584 					    x, y, width, height);
    585 }
    586 
    587 static void
    588 driswDestroyScreen(struct glx_screen *base)
    589 {
    590    struct drisw_screen *psc = (struct drisw_screen *) base;
    591 
    592    /* Free the direct rendering per screen data */
    593    (*psc->core->destroyScreen) (psc->driScreen);
    594    driDestroyConfigs(psc->driver_configs);
    595    psc->driScreen = NULL;
    596    if (psc->driver)
    597       dlclose(psc->driver);
    598    free(psc);
    599 }
    600 
    601 #define SWRAST_DRIVER_NAME "swrast"
    602 
    603 static void *
    604 driOpenSwrast(void)
    605 {
    606    void *driver = NULL;
    607 
    608    if (driver == NULL)
    609       driver = driOpenDriver(SWRAST_DRIVER_NAME);
    610 
    611    return driver;
    612 }
    613 
    614 static const struct glx_screen_vtable drisw_screen_vtable = {
    615    .create_context         = drisw_create_context,
    616    .create_context_attribs = drisw_create_context_attribs,
    617    .query_renderer_integer = drisw_query_renderer_integer,
    618    .query_renderer_string  = drisw_query_renderer_string,
    619 };
    620 
    621 static void
    622 driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
    623 {
    624    int i;
    625 
    626    __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
    627 
    628    if (psc->swrast->base.version >= 3) {
    629       __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context");
    630       __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context_profile");
    631 
    632       /* DRISW version >= 2 implies support for OpenGL ES.
    633        */
    634       __glXEnableDirectExtension(&psc->base,
    635 				 "GLX_EXT_create_context_es_profile");
    636       __glXEnableDirectExtension(&psc->base,
    637 				 "GLX_EXT_create_context_es2_profile");
    638    }
    639 
    640    if (psc->copySubBuffer)
    641       __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
    642 
    643    /* FIXME: Figure out what other extensions can be ported here from dri2. */
    644    for (i = 0; extensions[i]; i++) {
    645       if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
    646 	 psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
    647 	 __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
    648       }
    649       /* DRISW version 3 is also required because GLX_MESA_query_renderer
    650        * requires GLX_ARB_create_context_profile.
    651        */
    652       if (psc->swrast->base.version >= 3
    653           && strcmp(extensions[i]->name, __DRI2_RENDERER_QUERY) == 0) {
    654          psc->rendererQuery = (__DRI2rendererQueryExtension *) extensions[i];
    655          __glXEnableDirectExtension(&psc->base, "GLX_MESA_query_renderer");
    656       }
    657       if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) {
    658 	  __glXEnableDirectExtension(&psc->base,
    659 				     "GLX_ARB_context_flush_control");
    660       }
    661    }
    662 }
    663 
    664 static struct glx_screen *
    665 driswCreateScreen(int screen, struct glx_display *priv)
    666 {
    667    __GLXDRIscreen *psp;
    668    const __DRIconfig **driver_configs;
    669    const __DRIextension **extensions;
    670    struct drisw_screen *psc;
    671    struct glx_config *configs = NULL, *visuals = NULL;
    672    int i;
    673 
    674    psc = calloc(1, sizeof *psc);
    675    if (psc == NULL)
    676       return NULL;
    677 
    678    if (!glx_screen_init(&psc->base, screen, priv)) {
    679       free(psc);
    680       return NULL;
    681    }
    682 
    683    psc->driver = driOpenSwrast();
    684    if (psc->driver == NULL)
    685       goto handle_error;
    686 
    687    extensions = driGetDriverExtensions(psc->driver, SWRAST_DRIVER_NAME);
    688    if (extensions == NULL)
    689       goto handle_error;
    690 
    691    for (i = 0; extensions[i]; i++) {
    692       if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
    693 	 psc->core = (__DRIcoreExtension *) extensions[i];
    694       if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
    695 	 psc->swrast = (__DRIswrastExtension *) extensions[i];
    696       if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0)
    697 	 psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
    698    }
    699 
    700    if (psc->core == NULL || psc->swrast == NULL) {
    701       ErrorMessageF("core dri extension not found\n");
    702       goto handle_error;
    703    }
    704 
    705    if (psc->swrast->base.version >= 4) {
    706       psc->driScreen =
    707          psc->swrast->createNewScreen2(screen, loader_extensions,
    708                                        extensions,
    709                                        &driver_configs, psc);
    710    } else {
    711       psc->driScreen =
    712          psc->swrast->createNewScreen(screen, loader_extensions,
    713                                       &driver_configs, psc);
    714    }
    715    if (psc->driScreen == NULL) {
    716       ErrorMessageF("failed to create dri screen\n");
    717       goto handle_error;
    718    }
    719 
    720    extensions = psc->core->getExtensions(psc->driScreen);
    721    driswBindExtensions(psc, extensions);
    722 
    723    configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
    724    visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
    725 
    726    if (!configs || !visuals) {
    727        ErrorMessageF("No matching fbConfigs or visuals found\n");
    728        goto handle_error;
    729    }
    730 
    731    glx_config_destroy_list(psc->base.configs);
    732    psc->base.configs = configs;
    733    glx_config_destroy_list(psc->base.visuals);
    734    psc->base.visuals = visuals;
    735 
    736    psc->driver_configs = driver_configs;
    737 
    738    psc->base.vtable = &drisw_screen_vtable;
    739    psp = &psc->vtable;
    740    psc->base.driScreen = psp;
    741    psp->destroyScreen = driswDestroyScreen;
    742    psp->createDrawable = driswCreateDrawable;
    743    psp->swapBuffers = driswSwapBuffers;
    744 
    745    if (psc->copySubBuffer)
    746       psp->copySubBuffer = driswCopySubBuffer;
    747 
    748    return &psc->base;
    749 
    750  handle_error:
    751    if (configs)
    752        glx_config_destroy_list(configs);
    753    if (visuals)
    754        glx_config_destroy_list(visuals);
    755    if (psc->driScreen)
    756        psc->core->destroyScreen(psc->driScreen);
    757    psc->driScreen = NULL;
    758 
    759    if (psc->driver)
    760       dlclose(psc->driver);
    761    glx_screen_cleanup(&psc->base);
    762    free(psc);
    763 
    764    CriticalErrorMessageF("failed to load driver: %s\n", SWRAST_DRIVER_NAME);
    765 
    766    return NULL;
    767 }
    768 
    769 /* Called from __glXFreeDisplayPrivate.
    770  */
    771 static void
    772 driswDestroyDisplay(__GLXDRIdisplay * dpy)
    773 {
    774    free(dpy);
    775 }
    776 
    777 /*
    778  * Allocate, initialize and return a __DRIdisplayPrivate object.
    779  * This is called from __glXInitialize() when we are given a new
    780  * display pointer.
    781  */
    782 _X_HIDDEN __GLXDRIdisplay *
    783 driswCreateDisplay(Display * dpy)
    784 {
    785    struct drisw_display *pdpyp;
    786 
    787    pdpyp = malloc(sizeof *pdpyp);
    788    if (pdpyp == NULL)
    789       return NULL;
    790 
    791    pdpyp->base.destroyDisplay = driswDestroyDisplay;
    792    pdpyp->base.createScreen = driswCreateScreen;
    793 
    794    return &pdpyp->base;
    795 }
    796 
    797 #endif /* GLX_DIRECT_RENDERING */
    798