Home | History | Annotate | Download | only in swrast
      1 /*
      2  * Copyright 2008, 2010 George Sapountzis <gsapountzis (at) gmail.com>
      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 shall be included
     12  * in all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20  */
     21 
     22 /*
     23  * DRI software rasterizer
     24  *
     25  * This is the mesa swrast module packaged into a DRI driver structure.
     26  *
     27  * The front-buffer is allocated by the loader. The loader provides read/write
     28  * callbacks for access to the front-buffer. The driver uses a scratch row for
     29  * front-buffer rendering to avoid repeated calls to the loader.
     30  *
     31  * The back-buffer is allocated by the driver and is private.
     32  */
     33 
     34 #include "main/context.h"
     35 #include "main/extensions.h"
     36 #include "main/formats.h"
     37 #include "main/framebuffer.h"
     38 #include "main/imports.h"
     39 #include "main/renderbuffer.h"
     40 #include "swrast/swrast.h"
     41 #include "swrast/s_renderbuffer.h"
     42 #include "swrast_setup/swrast_setup.h"
     43 #include "tnl/tnl.h"
     44 #include "tnl/t_context.h"
     45 #include "tnl/t_pipeline.h"
     46 #include "vbo/vbo.h"
     47 #include "drivers/common/driverfuncs.h"
     48 #include "drivers/common/meta.h"
     49 #include "utils.h"
     50 
     51 #include "main/teximage.h"
     52 #include "main/texformat.h"
     53 #include "main/texstate.h"
     54 
     55 #include "swrast_priv.h"
     56 #include "swrast/s_context.h"
     57 
     58 
     59 /**
     60  * Screen and config-related functions
     61  */
     62 
     63 static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
     64 				GLint texture_format, __DRIdrawable *dPriv)
     65 {
     66     struct dri_context *dri_ctx;
     67     int x, y, w, h;
     68     __DRIscreen *sPriv = dPriv->driScreenPriv;
     69     struct gl_texture_unit *texUnit;
     70     struct gl_texture_object *texObj;
     71     struct gl_texture_image *texImage;
     72     struct swrast_texture_image *swImage;
     73     uint32_t internalFormat;
     74     gl_format texFormat;
     75 
     76     dri_ctx = pDRICtx->driverPrivate;
     77 
     78     internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
     79 
     80     texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
     81     texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
     82     texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
     83     swImage = swrast_texture_image(texImage);
     84 
     85     _mesa_lock_texture(&dri_ctx->Base, texObj);
     86 
     87     sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
     88 
     89     if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
     90 	texFormat = MESA_FORMAT_XRGB8888;
     91     else
     92 	texFormat = MESA_FORMAT_ARGB8888;
     93 
     94     _mesa_init_teximage_fields(&dri_ctx->Base, texImage,
     95 			       w, h, 1, 0, internalFormat, texFormat);
     96 
     97     sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Buffer,
     98 				   dPriv->loaderPrivate);
     99 
    100     _mesa_unlock_texture(&dri_ctx->Base, texObj);
    101 }
    102 
    103 static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
    104 			       __DRIdrawable *dPriv)
    105 {
    106     swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
    107 }
    108 
    109 static const __DRItexBufferExtension swrastTexBufferExtension = {
    110     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
    111     swrastSetTexBuffer,
    112     swrastSetTexBuffer2,
    113 };
    114 
    115 static const __DRIextension *dri_screen_extensions[] = {
    116     &swrastTexBufferExtension.base,
    117     NULL
    118 };
    119 
    120 static __DRIconfig **
    121 swrastFillInModes(__DRIscreen *psp,
    122 		  unsigned pixel_bits, unsigned depth_bits,
    123 		  unsigned stencil_bits, GLboolean have_back_buffer)
    124 {
    125     __DRIconfig **configs;
    126     unsigned depth_buffer_factor;
    127     unsigned back_buffer_factor;
    128     GLenum fb_format;
    129     GLenum fb_type;
    130 
    131     /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
    132      * support pageflipping at all.
    133      */
    134     static const GLenum back_buffer_modes[] = {
    135 	GLX_NONE, GLX_SWAP_UNDEFINED_OML
    136     };
    137 
    138     uint8_t depth_bits_array[4];
    139     uint8_t stencil_bits_array[4];
    140     uint8_t msaa_samples_array[1];
    141 
    142     (void) psp;
    143     (void) have_back_buffer;
    144 
    145     depth_bits_array[0] = 0;
    146     depth_bits_array[1] = 0;
    147     depth_bits_array[2] = depth_bits;
    148     depth_bits_array[3] = depth_bits;
    149 
    150     /* Just like with the accumulation buffer, always provide some modes
    151      * with a stencil buffer.
    152      */
    153     stencil_bits_array[0] = 0;
    154     stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
    155     stencil_bits_array[2] = 0;
    156     stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits;
    157 
    158     msaa_samples_array[0] = 0;
    159 
    160     depth_buffer_factor = 4;
    161     back_buffer_factor = 2;
    162 
    163     switch (pixel_bits) {
    164     case 8:
    165 	fb_format = GL_RGB;
    166 	fb_type = GL_UNSIGNED_BYTE_2_3_3_REV;
    167 	break;
    168     case 16:
    169 	fb_format = GL_RGB;
    170 	fb_type = GL_UNSIGNED_SHORT_5_6_5;
    171 	break;
    172     case 24:
    173 	fb_format = GL_BGR;
    174 	fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
    175 	break;
    176     case 32:
    177 	fb_format = GL_BGRA;
    178 	fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
    179 	break;
    180     default:
    181 	fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__,
    182 		pixel_bits);
    183 	return NULL;
    184     }
    185 
    186     configs = driCreateConfigs(fb_format, fb_type,
    187 			       depth_bits_array, stencil_bits_array,
    188 			       depth_buffer_factor, back_buffer_modes,
    189 			       back_buffer_factor, msaa_samples_array, 1,
    190 			       GL_TRUE);
    191     if (configs == NULL) {
    192 	fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
    193 		__LINE__);
    194 	return NULL;
    195     }
    196 
    197     return configs;
    198 }
    199 
    200 static const __DRIconfig **
    201 dri_init_screen(__DRIscreen * psp)
    202 {
    203     __DRIconfig **configs8, **configs16, **configs24, **configs32;
    204 
    205     TRACE;
    206 
    207     psp->extensions = dri_screen_extensions;
    208 
    209     configs8  = swrastFillInModes(psp,  8,  8, 0, 1);
    210     configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
    211     configs24 = swrastFillInModes(psp, 24, 24, 8, 1);
    212     configs32 = swrastFillInModes(psp, 32, 24, 8, 1);
    213 
    214     configs16 = driConcatConfigs(configs8, configs16);
    215     configs24 = driConcatConfigs(configs16, configs24);
    216     configs32 = driConcatConfigs(configs24, configs32);
    217 
    218     return (const __DRIconfig **)configs32;
    219 }
    220 
    221 static void
    222 dri_destroy_screen(__DRIscreen * sPriv)
    223 {
    224     TRACE;
    225     (void) sPriv;
    226 }
    227 
    228 
    229 /**
    230  * Framebuffer and renderbuffer-related functions.
    231  */
    232 
    233 static GLuint
    234 choose_pixel_format(const struct gl_config *v)
    235 {
    236     int depth = v->rgbBits;
    237 
    238     if (depth == 32
    239 	&& v->redMask   == 0xff0000
    240 	&& v->greenMask == 0x00ff00
    241 	&& v->blueMask  == 0x0000ff)
    242 	return PF_A8R8G8B8;
    243     else if (depth == 24
    244 	     && v->redMask   == 0xff0000
    245 	     && v->greenMask == 0x00ff00
    246 	     && v->blueMask  == 0x0000ff)
    247 	return PF_X8R8G8B8;
    248     else if (depth == 16
    249 	     && v->redMask   == 0xf800
    250 	     && v->greenMask == 0x07e0
    251 	     && v->blueMask  == 0x001f)
    252 	return PF_R5G6B5;
    253     else if (depth == 8
    254 	     && v->redMask   == 0x07
    255 	     && v->greenMask == 0x38
    256 	     && v->blueMask  == 0xc0)
    257 	return PF_R3G3B2;
    258 
    259     _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
    260     return 0;
    261 }
    262 
    263 static void
    264 swrast_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
    265 {
    266     struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
    267 
    268     TRACE;
    269 
    270     free(xrb->Base.Buffer);
    271     _mesa_delete_renderbuffer(ctx, rb);
    272 }
    273 
    274 /* see bytes_per_line in libGL */
    275 static INLINE int
    276 bytes_per_line(unsigned pitch_bits, unsigned mul)
    277 {
    278    unsigned mask = mul - 1;
    279 
    280    return ((pitch_bits + mask) & ~mask) / 8;
    281 }
    282 
    283 static GLboolean
    284 swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
    285 			   GLenum internalFormat, GLuint width, GLuint height)
    286 {
    287     struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
    288 
    289     TRACE;
    290 
    291     (void) ctx;
    292     (void) internalFormat;
    293 
    294     xrb->Base.Buffer = NULL;
    295     rb->Width = width;
    296     rb->Height = height;
    297     xrb->pitch = bytes_per_line(width * xrb->bpp, 32);
    298 
    299     return GL_TRUE;
    300 }
    301 
    302 static GLboolean
    303 swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
    304 			  GLenum internalFormat, GLuint width, GLuint height)
    305 {
    306     struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
    307 
    308     TRACE;
    309 
    310     free(xrb->Base.Buffer);
    311 
    312     swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
    313 
    314     xrb->Base.Buffer = malloc(height * xrb->pitch);
    315 
    316     return GL_TRUE;
    317 }
    318 
    319 static struct dri_swrast_renderbuffer *
    320 swrast_new_renderbuffer(const struct gl_config *visual, __DRIdrawable *dPriv,
    321 			GLboolean front)
    322 {
    323     struct dri_swrast_renderbuffer *xrb = calloc(1, sizeof *xrb);
    324     struct gl_renderbuffer *rb;
    325     GLuint pixel_format;
    326 
    327     TRACE;
    328 
    329     if (!xrb)
    330 	return NULL;
    331 
    332     rb = &xrb->Base.Base;
    333 
    334     _mesa_init_renderbuffer(rb, 0);
    335 
    336     pixel_format = choose_pixel_format(visual);
    337 
    338     xrb->dPriv = dPriv;
    339     xrb->Base.Base.Delete = swrast_delete_renderbuffer;
    340     if (front) {
    341         rb->AllocStorage = swrast_alloc_front_storage;
    342     }
    343     else {
    344 	rb->AllocStorage = swrast_alloc_back_storage;
    345     }
    346 
    347     switch (pixel_format) {
    348     case PF_A8R8G8B8:
    349 	rb->Format = MESA_FORMAT_ARGB8888;
    350 	rb->InternalFormat = GL_RGBA;
    351 	rb->_BaseFormat = GL_RGBA;
    352 	xrb->bpp = 32;
    353 	break;
    354     case PF_X8R8G8B8:
    355 	rb->Format = MESA_FORMAT_ARGB8888; /* XXX */
    356 	rb->InternalFormat = GL_RGB;
    357 	rb->_BaseFormat = GL_RGB;
    358 	xrb->bpp = 32;
    359 	break;
    360     case PF_R5G6B5:
    361 	rb->Format = MESA_FORMAT_RGB565;
    362 	rb->InternalFormat = GL_RGB;
    363 	rb->_BaseFormat = GL_RGB;
    364 	xrb->bpp = 16;
    365 	break;
    366     case PF_R3G3B2:
    367 	rb->Format = MESA_FORMAT_RGB332;
    368 	rb->InternalFormat = GL_RGB;
    369 	rb->_BaseFormat = GL_RGB;
    370 	xrb->bpp = 8;
    371 	break;
    372     default:
    373 	return NULL;
    374     }
    375 
    376     return xrb;
    377 }
    378 
    379 static void
    380 swrast_map_renderbuffer(struct gl_context *ctx,
    381 			struct gl_renderbuffer *rb,
    382 			GLuint x, GLuint y, GLuint w, GLuint h,
    383 			GLbitfield mode,
    384 			GLubyte **out_map,
    385 			GLint *out_stride)
    386 {
    387    struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
    388    GLubyte *map = xrb->Base.Buffer;
    389    int cpp = _mesa_get_format_bytes(rb->Format);
    390    int stride = rb->Width * cpp;
    391 
    392    if (rb->AllocStorage == swrast_alloc_front_storage) {
    393       __DRIdrawable *dPriv = xrb->dPriv;
    394       __DRIscreen *sPriv = dPriv->driScreenPriv;
    395 
    396       xrb->map_mode = mode;
    397       xrb->map_x = x;
    398       xrb->map_y = y;
    399       xrb->map_w = w;
    400       xrb->map_h = h;
    401 
    402       stride = w * cpp;
    403       xrb->Base.Buffer = malloc(h * stride);
    404 
    405       sPriv->swrast_loader->getImage(dPriv, x, y, w, h,
    406 				     (char *) xrb->Base.Buffer,
    407 				     dPriv->loaderPrivate);
    408 
    409       *out_map = xrb->Base.Buffer;
    410       *out_stride = stride;
    411       return;
    412    }
    413 
    414    ASSERT(xrb->Base.Buffer);
    415 
    416    if (rb->AllocStorage == swrast_alloc_back_storage) {
    417       map += (rb->Height - 1) * stride;
    418       stride = -stride;
    419    }
    420 
    421    map += (GLsizei)y * stride;
    422    map += (GLsizei)x * cpp;
    423 
    424    *out_map = map;
    425    *out_stride = stride;
    426 }
    427 
    428 static void
    429 swrast_unmap_renderbuffer(struct gl_context *ctx,
    430 			  struct gl_renderbuffer *rb)
    431 {
    432    struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
    433 
    434    if (rb->AllocStorage == swrast_alloc_front_storage) {
    435       __DRIdrawable *dPriv = xrb->dPriv;
    436       __DRIscreen *sPriv = dPriv->driScreenPriv;
    437 
    438       if (xrb->map_mode & GL_MAP_WRITE_BIT) {
    439 	 sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_DRAW,
    440 					xrb->map_x, xrb->map_y,
    441 					xrb->map_w, xrb->map_h,
    442 					(char *) xrb->Base.Buffer,
    443 					dPriv->loaderPrivate);
    444       }
    445 
    446       free(xrb->Base.Buffer);
    447       xrb->Base.Buffer = NULL;
    448    }
    449 }
    450 
    451 static GLboolean
    452 dri_create_buffer(__DRIscreen * sPriv,
    453 		  __DRIdrawable * dPriv,
    454 		  const struct gl_config * visual, GLboolean isPixmap)
    455 {
    456     struct dri_drawable *drawable = NULL;
    457     struct gl_framebuffer *fb;
    458     struct dri_swrast_renderbuffer *frontrb, *backrb;
    459 
    460     TRACE;
    461 
    462     (void) sPriv;
    463     (void) isPixmap;
    464 
    465     drawable = CALLOC_STRUCT(dri_drawable);
    466     if (drawable == NULL)
    467 	goto drawable_fail;
    468 
    469     dPriv->driverPrivate = drawable;
    470     drawable->dPriv = dPriv;
    471 
    472     drawable->row = malloc(SWRAST_MAX_WIDTH * 4);
    473     if (drawable->row == NULL)
    474 	goto drawable_fail;
    475 
    476     fb = &drawable->Base;
    477 
    478     /* basic framebuffer setup */
    479     _mesa_initialize_window_framebuffer(fb, visual);
    480 
    481     /* add front renderbuffer */
    482     frontrb = swrast_new_renderbuffer(visual, dPriv, GL_TRUE);
    483     _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base.Base);
    484 
    485     /* add back renderbuffer */
    486     if (visual->doubleBufferMode) {
    487 	backrb = swrast_new_renderbuffer(visual, dPriv, GL_FALSE);
    488 	_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base.Base);
    489     }
    490 
    491     /* add software renderbuffers */
    492     _swrast_add_soft_renderbuffers(fb,
    493                                    GL_FALSE, /* color */
    494                                    visual->haveDepthBuffer,
    495                                    visual->haveStencilBuffer,
    496                                    visual->haveAccumBuffer,
    497                                    GL_FALSE, /* alpha */
    498                                    GL_FALSE /* aux bufs */);
    499 
    500     return GL_TRUE;
    501 
    502 drawable_fail:
    503 
    504     if (drawable)
    505 	free(drawable->row);
    506 
    507     FREE(drawable);
    508 
    509     return GL_FALSE;
    510 }
    511 
    512 static void
    513 dri_destroy_buffer(__DRIdrawable * dPriv)
    514 {
    515     TRACE;
    516 
    517     if (dPriv) {
    518 	struct dri_drawable *drawable = dri_drawable(dPriv);
    519 	struct gl_framebuffer *fb;
    520 
    521 	free(drawable->row);
    522 
    523 	fb = &drawable->Base;
    524 
    525 	fb->DeletePending = GL_TRUE;
    526 	_mesa_reference_framebuffer(&fb, NULL);
    527     }
    528 }
    529 
    530 static void
    531 dri_swap_buffers(__DRIdrawable * dPriv)
    532 {
    533     __DRIscreen *sPriv = dPriv->driScreenPriv;
    534 
    535     GET_CURRENT_CONTEXT(ctx);
    536 
    537     struct dri_drawable *drawable = dri_drawable(dPriv);
    538     struct gl_framebuffer *fb;
    539     struct dri_swrast_renderbuffer *frontrb, *backrb;
    540 
    541     TRACE;
    542 
    543     fb = &drawable->Base;
    544 
    545     frontrb =
    546 	dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
    547     backrb =
    548 	dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
    549 
    550     /* check for signle-buffered */
    551     if (backrb == NULL)
    552 	return;
    553 
    554     /* check if swapping currently bound buffer */
    555     if (ctx && ctx->DrawBuffer == fb) {
    556 	/* flush pending rendering */
    557 	_mesa_notifySwapBuffers(ctx);
    558     }
    559 
    560     sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
    561 				   0, 0,
    562 				   frontrb->Base.Base.Width,
    563 				   frontrb->Base.Base.Height,
    564 				   (char *) backrb->Base.Buffer,
    565 				   dPriv->loaderPrivate);
    566 }
    567 
    568 
    569 /**
    570  * General device driver functions.
    571  */
    572 
    573 static void
    574 get_window_size( struct gl_framebuffer *fb, GLsizei *w, GLsizei *h )
    575 {
    576     __DRIdrawable *dPriv = swrast_drawable(fb)->dPriv;
    577     __DRIscreen *sPriv = dPriv->driScreenPriv;
    578     int x, y;
    579 
    580     sPriv->swrast_loader->getDrawableInfo(dPriv,
    581 					  &x, &y, w, h,
    582 					  dPriv->loaderPrivate);
    583 }
    584 
    585 static void
    586 swrast_check_and_update_window_size( struct gl_context *ctx, struct gl_framebuffer *fb )
    587 {
    588     GLsizei width, height;
    589 
    590     get_window_size(fb, &width, &height);
    591     if (fb->Width != width || fb->Height != height) {
    592 	_mesa_resize_framebuffer(ctx, fb, width, height);
    593     }
    594 }
    595 
    596 static const GLubyte *
    597 get_string(struct gl_context *ctx, GLenum pname)
    598 {
    599     (void) ctx;
    600     switch (pname) {
    601 	case GL_VENDOR:
    602 	    return (const GLubyte *) "Mesa Project";
    603 	case GL_RENDERER:
    604 	    return (const GLubyte *) "Software Rasterizer";
    605 	default:
    606 	    return NULL;
    607     }
    608 }
    609 
    610 static void
    611 update_state( struct gl_context *ctx, GLuint new_state )
    612 {
    613     /* not much to do here - pass it on */
    614     _swrast_InvalidateState( ctx, new_state );
    615     _swsetup_InvalidateState( ctx, new_state );
    616     _vbo_InvalidateState( ctx, new_state );
    617     _tnl_InvalidateState( ctx, new_state );
    618 }
    619 
    620 static void
    621 viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
    622 {
    623     struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
    624     struct gl_framebuffer *read = ctx->WinSysReadBuffer;
    625 
    626     (void) x;
    627     (void) y;
    628     (void) w;
    629     (void) h;
    630     swrast_check_and_update_window_size(ctx, draw);
    631     swrast_check_and_update_window_size(ctx, read);
    632 }
    633 
    634 static gl_format swrastChooseTextureFormat(struct gl_context * ctx,
    635                                            GLenum target,
    636 					   GLint internalFormat,
    637 					   GLenum format,
    638 					   GLenum type)
    639 {
    640     if (internalFormat == GL_RGB)
    641 	return MESA_FORMAT_XRGB8888;
    642     return _mesa_choose_tex_format(ctx, target, internalFormat, format, type);
    643 }
    644 
    645 static void
    646 swrast_init_driver_functions(struct dd_function_table *driver)
    647 {
    648     driver->GetString = get_string;
    649     driver->UpdateState = update_state;
    650     driver->GetBufferSize = NULL;
    651     driver->Viewport = viewport;
    652     driver->ChooseTextureFormat = swrastChooseTextureFormat;
    653     driver->MapRenderbuffer = swrast_map_renderbuffer;
    654     driver->UnmapRenderbuffer = swrast_unmap_renderbuffer;
    655 }
    656 
    657 static const char *es2_extensions[] = {
    658    /* Used by mesa internally (cf all_mesa_extensions in ../common/utils.c) */
    659    "GL_ARB_transpose_matrix",
    660    "GL_ARB_window_pos",
    661    "GL_EXT_blend_func_separate",
    662    "GL_EXT_compiled_vertex_array",
    663    "GL_EXT_framebuffer_blit",
    664    "GL_IBM_multimode_draw_arrays",
    665    "GL_MESA_window_pos",
    666    "GL_NV_vertex_program",
    667 
    668    /* Required by GLES2 */
    669    "GL_ARB_fragment_program",
    670    "GL_ARB_fragment_shader",
    671    "GL_ARB_shader_objects",
    672    "GL_ARB_texture_cube_map",
    673    "GL_ARB_texture_non_power_of_two",
    674    "GL_ARB_vertex_shader",
    675    "GL_EXT_blend_color",
    676    "GL_EXT_blend_equation_separate",
    677    "GL_EXT_blend_minmax",
    678 
    679    /* Optional GLES2 */
    680    "GL_ARB_framebuffer_object",
    681    "GL_EXT_texture_filter_anisotropic",
    682    "GL_ARB_depth_texture",
    683    "GL_EXT_packed_depth_stencil",
    684    "GL_EXT_framebuffer_object",
    685    NULL,
    686 };
    687 
    688 static void
    689 InitExtensionsES2(struct gl_context *ctx)
    690 {
    691    int i;
    692 
    693    for (i = 0; es2_extensions[i]; i++)
    694       _mesa_enable_extension(ctx, es2_extensions[i]);
    695 }
    696 
    697 /**
    698  * Context-related functions.
    699  */
    700 
    701 static GLboolean
    702 dri_create_context(gl_api api,
    703 		   const struct gl_config * visual,
    704 		   __DRIcontext * cPriv,
    705 		   unsigned major_version,
    706 		   unsigned minor_version,
    707 		   uint32_t flags,
    708 		   unsigned *error,
    709 		   void *sharedContextPrivate)
    710 {
    711     struct dri_context *ctx = NULL;
    712     struct dri_context *share = (struct dri_context *)sharedContextPrivate;
    713     struct gl_context *mesaCtx = NULL;
    714     struct gl_context *sharedCtx = NULL;
    715     struct dd_function_table functions;
    716 
    717     TRACE;
    718 
    719     /* Flag filtering is handled in dri2CreateContextAttribs.
    720      */
    721     (void) flags;
    722 
    723     switch (api) {
    724     case API_OPENGL:
    725         if (major_version > 2
    726 	    || (major_version == 2 && minor_version > 1)) {
    727             *error = __DRI_CTX_ERROR_BAD_VERSION;
    728             return GL_FALSE;
    729         }
    730         break;
    731     case API_OPENGLES:
    732     case API_OPENGLES2:
    733         break;
    734     case API_OPENGL_CORE:
    735         *error = __DRI_CTX_ERROR_BAD_API;
    736         return GL_FALSE;
    737     }
    738 
    739     ctx = CALLOC_STRUCT(dri_context);
    740     if (ctx == NULL) {
    741 	*error = __DRI_CTX_ERROR_NO_MEMORY;
    742 	goto context_fail;
    743     }
    744 
    745     cPriv->driverPrivate = ctx;
    746     ctx->cPriv = cPriv;
    747 
    748     /* build table of device driver functions */
    749     _mesa_init_driver_functions(&functions);
    750     swrast_init_driver_functions(&functions);
    751 
    752     if (share) {
    753 	sharedCtx = &share->Base;
    754     }
    755 
    756     mesaCtx = &ctx->Base;
    757 
    758     /* basic context setup */
    759     if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions, (void *) cPriv)) {
    760 	*error = __DRI_CTX_ERROR_NO_MEMORY;
    761 	goto context_fail;
    762     }
    763 
    764     /* do bounds checking to prevent segfaults and server crashes! */
    765     mesaCtx->Const.CheckArrayBounds = GL_TRUE;
    766 
    767     /* create module contexts */
    768     _swrast_CreateContext( mesaCtx );
    769     _vbo_CreateContext( mesaCtx );
    770     _tnl_CreateContext( mesaCtx );
    771     _swsetup_CreateContext( mesaCtx );
    772     _swsetup_Wakeup( mesaCtx );
    773 
    774     /* use default TCL pipeline */
    775     {
    776        TNLcontext *tnl = TNL_CONTEXT(mesaCtx);
    777        tnl->Driver.RunPipeline = _tnl_run_pipeline;
    778     }
    779 
    780     _mesa_meta_init(mesaCtx);
    781     _mesa_enable_sw_extensions(mesaCtx);
    782 
    783     switch (api) {
    784     case API_OPENGL_CORE:
    785         /* XXX fix me, fall-through for now */
    786     case API_OPENGL:
    787         _mesa_enable_1_3_extensions(mesaCtx);
    788         _mesa_enable_1_4_extensions(mesaCtx);
    789         _mesa_enable_1_5_extensions(mesaCtx);
    790         _mesa_enable_2_0_extensions(mesaCtx);
    791         _mesa_enable_2_1_extensions(mesaCtx);
    792         break;
    793     case API_OPENGLES:
    794         _mesa_enable_1_3_extensions(mesaCtx);
    795         _mesa_enable_1_4_extensions(mesaCtx);
    796         _mesa_enable_1_5_extensions(mesaCtx);
    797 
    798         break;
    799     case API_OPENGLES2:
    800         InitExtensionsES2( mesaCtx);
    801         break;
    802     }
    803 
    804     *error = __DRI_CTX_ERROR_SUCCESS;
    805     return GL_TRUE;
    806 
    807 context_fail:
    808 
    809     FREE(ctx);
    810 
    811     return GL_FALSE;
    812 }
    813 
    814 static void
    815 dri_destroy_context(__DRIcontext * cPriv)
    816 {
    817     TRACE;
    818 
    819     if (cPriv) {
    820 	struct dri_context *ctx = dri_context(cPriv);
    821 	struct gl_context *mesaCtx;
    822 
    823 	mesaCtx = &ctx->Base;
    824 
    825         _mesa_meta_free(mesaCtx);
    826 	_swsetup_DestroyContext( mesaCtx );
    827 	_swrast_DestroyContext( mesaCtx );
    828 	_tnl_DestroyContext( mesaCtx );
    829 	_vbo_DestroyContext( mesaCtx );
    830 	_mesa_destroy_context( mesaCtx );
    831     }
    832 }
    833 
    834 static GLboolean
    835 dri_make_current(__DRIcontext * cPriv,
    836 		 __DRIdrawable * driDrawPriv,
    837 		 __DRIdrawable * driReadPriv)
    838 {
    839     struct gl_context *mesaCtx;
    840     struct gl_framebuffer *mesaDraw;
    841     struct gl_framebuffer *mesaRead;
    842     TRACE;
    843 
    844     if (cPriv) {
    845 	struct dri_context *ctx = dri_context(cPriv);
    846 	struct dri_drawable *draw;
    847 	struct dri_drawable *read;
    848 
    849 	if (!driDrawPriv || !driReadPriv)
    850 	    return GL_FALSE;
    851 
    852 	draw = dri_drawable(driDrawPriv);
    853 	read = dri_drawable(driReadPriv);
    854 	mesaCtx = &ctx->Base;
    855 	mesaDraw = &draw->Base;
    856 	mesaRead = &read->Base;
    857 
    858 	/* check for same context and buffer */
    859 	if (mesaCtx == _mesa_get_current_context()
    860 	    && mesaCtx->DrawBuffer == mesaDraw
    861 	    && mesaCtx->ReadBuffer == mesaRead) {
    862 	    return GL_TRUE;
    863 	}
    864 
    865 	_glapi_check_multithread();
    866 
    867 	swrast_check_and_update_window_size(mesaCtx, mesaDraw);
    868 	if (mesaRead != mesaDraw)
    869 	    swrast_check_and_update_window_size(mesaCtx, mesaRead);
    870 
    871 	_mesa_make_current( mesaCtx,
    872 			    mesaDraw,
    873 			    mesaRead );
    874     }
    875     else {
    876 	/* unbind */
    877 	_mesa_make_current( NULL, NULL, NULL );
    878     }
    879 
    880     return GL_TRUE;
    881 }
    882 
    883 static GLboolean
    884 dri_unbind_context(__DRIcontext * cPriv)
    885 {
    886     TRACE;
    887     (void) cPriv;
    888 
    889     /* Unset current context and dispath table */
    890     _mesa_make_current(NULL, NULL, NULL);
    891 
    892     return GL_TRUE;
    893 }
    894 
    895 
    896 const struct __DriverAPIRec driDriverAPI = {
    897     .InitScreen = dri_init_screen,
    898     .DestroyScreen = dri_destroy_screen,
    899     .CreateContext = dri_create_context,
    900     .DestroyContext = dri_destroy_context,
    901     .CreateBuffer = dri_create_buffer,
    902     .DestroyBuffer = dri_destroy_buffer,
    903     .SwapBuffers = dri_swap_buffers,
    904     .MakeCurrent = dri_make_current,
    905     .UnbindContext = dri_unbind_context,
    906 };
    907 
    908 /* This is the table of extensions that the loader will dlsym() for. */
    909 PUBLIC const __DRIextension *__driDriverExtensions[] = {
    910     &driCoreExtension.base,
    911     &driSWRastExtension.base,
    912     NULL
    913 };
    914