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