i965: clip: Add VUE map computation to clip stage for Gen4-5.
[mesa.git] / src / mesa / drivers / dri / swrast / swrast.c
index 03c672ecf1b6cb4d61d4553bfddfddbec5191025..719b406ec05feeef79ff22f8dace5ba3230d3954 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 George Sapountzis <gsap7@yahoo.gr>
+ * Copyright 2008, 2010 George Sapountzis <gsapountzis@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "drivers/common/meta.h"
 #include "utils.h"
 
+#include "main/teximage.h"
+#include "main/texformat.h"
+#include "main/texstate.h"
+
 #include "swrast_priv.h"
 
 
  * Screen and config-related functions
  */
 
-static void
-setupLoaderExtensions(__DRIscreen *psp,
-                     const __DRIextension **extensions)
+static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+                               GLint texture_format, __DRIdrawable *dPriv)
 {
-    int i;
+    struct dri_context *dri_ctx;
+    int x, y, w, h;
+    __DRIscreen *sPriv = dPriv->driScreenPriv;
+    struct gl_texture_unit *texUnit;
+    struct gl_texture_object *texObj;
+    struct gl_texture_image *texImage;
+    uint32_t internalFormat;
+    gl_format texFormat;
 
-    for (i = 0; extensions[i]; i++) {
-       if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
-           psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
-    }
+    dri_ctx = pDRICtx->driverPrivate;
+
+    internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
+
+    texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
+    texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
+    texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
+
+    _mesa_lock_texture(&dri_ctx->Base, texObj);
+
+    sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
+
+    if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
+       texFormat = MESA_FORMAT_XRGB8888;
+    else
+       texFormat = MESA_FORMAT_ARGB8888;
+
+    _mesa_init_teximage_fields(&dri_ctx->Base, target, texImage,
+                              w, h, 1, 0, internalFormat, texFormat);
+
+    sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data,
+                                  dPriv->loaderPrivate);
+
+    _mesa_unlock_texture(&dri_ctx->Base, texObj);
 }
 
+static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
+                              __DRIdrawable *dPriv)
+{
+    swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension swrastTexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+    swrastSetTexBuffer,
+    swrastSetTexBuffer2,
+};
+
+static const __DRIextension *dri_screen_extensions[] = {
+    &swrastTexBufferExtension.base,
+    NULL
+};
+
 static __DRIconfig **
 swrastFillInModes(__DRIscreen *psp,
                  unsigned pixel_bits, unsigned depth_bits,
@@ -143,26 +190,14 @@ swrastFillInModes(__DRIscreen *psp,
     return configs;
 }
 
-static __DRIscreen *
-driCreateNewScreen(int scrn, const __DRIextension **extensions,
-                  const __DRIconfig ***driver_configs, void *data)
+static const __DRIconfig **
+dri_init_screen(__DRIscreen * psp)
 {
-    static const __DRIextension *emptyExtensionList[] = { NULL };
-    __DRIscreen *psp;
     __DRIconfig **configs8, **configs16, **configs24, **configs32;
 
-    (void) data;
-
     TRACE;
 
-    psp = calloc(1, sizeof(*psp));
-    if (!psp)
-       return NULL;
-
-    setupLoaderExtensions(psp, extensions);
-
-    psp->num = scrn;
-    psp->extensions = emptyExtensionList;
+    psp->extensions = dri_screen_extensions;
 
     configs8  = swrastFillInModes(psp,  8,  8, 0, 1);
     configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
@@ -171,28 +206,15 @@ driCreateNewScreen(int scrn, const __DRIextension **extensions,
 
     configs16 = driConcatConfigs(configs8, configs16);
     configs24 = driConcatConfigs(configs16, configs24);
-    *driver_configs = (const __DRIconfig **)
-       driConcatConfigs(configs24, configs32);
-
-    driInitExtensions( NULL, NULL, GL_FALSE );
+    configs32 = driConcatConfigs(configs24, configs32);
 
-    return psp;
+    return (const __DRIconfig **)configs32;
 }
 
-static void driDestroyScreen(__DRIscreen *psp)
-{
-    TRACE;
-
-    if (psp) {
-       free(psp);
-    }
-}
-
-static const __DRIextension **driGetExtensions(__DRIscreen *psp)
+static void
+dri_destroy_screen(__DRIscreen * sPriv)
 {
     TRACE;
-
-    return psp->extensions;
 }
 
 
@@ -201,7 +223,7 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
  */
 
 static GLuint
-choose_pixel_format(const GLvisual *v)
+choose_pixel_format(const struct gl_config *v)
 {
     int depth = v->rgbBits;
 
@@ -239,12 +261,20 @@ swrast_delete_renderbuffer(struct gl_renderbuffer *rb)
     free(rb);
 }
 
+/* see bytes_per_line in libGL */
+static INLINE int
+bytes_per_line(unsigned pitch_bits, unsigned mul)
+{
+   unsigned mask = mul - 1;
+
+   return ((pitch_bits + mask) & ~mask) / 8;
+}
+
 static GLboolean
-swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                           GLenum internalFormat, GLuint width, GLuint height)
 {
     struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
-    unsigned mask = PITCH_ALIGN_BITS - 1;
 
     TRACE;
 
@@ -252,14 +282,13 @@ swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
     rb->Width = width;
     rb->Height = height;
 
-    /* always pad to PITCH_ALIGN_BITS */
-    xrb->pitch = ((width * xrb->bpp + mask) & ~mask) / 8;
+    xrb->pitch = bytes_per_line(width * xrb->bpp, 32);
 
     return GL_TRUE;
 }
 
 static GLboolean
-swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                          GLenum internalFormat, GLuint width, GLuint height)
 {
     struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
@@ -276,7 +305,7 @@ swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 }
 
 static struct swrast_renderbuffer *
-swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
+swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front)
 {
     struct swrast_renderbuffer *xrb = calloc(1, sizeof *xrb);
     GLuint pixel_format;
@@ -336,94 +365,118 @@ swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
     return xrb;
 }
 
-static __DRIdrawable *
-driCreateNewDrawable(__DRIscreen *screen,
-                    const __DRIconfig *config, void *data)
+static GLboolean
+dri_create_buffer(__DRIscreen * sPriv,
+                 __DRIdrawable * dPriv,
+                 const struct gl_config * visual, GLboolean isPixmap)
 {
-    __DRIdrawable *buf;
+    struct dri_drawable *drawable = NULL;
+    struct gl_framebuffer *fb;
     struct swrast_renderbuffer *frontrb, *backrb;
 
     TRACE;
 
-    buf = calloc(1, sizeof *buf);
-    if (!buf)
-       return NULL;
+    drawable = CALLOC_STRUCT(dri_drawable);
+    if (drawable == NULL)
+       goto drawable_fail;
 
-    buf->loaderPrivate = data;
+    dPriv->driverPrivate = drawable;
+    drawable->dPriv = dPriv;
 
-    buf->driScreenPriv = screen;
+    drawable->row = malloc(MAX_WIDTH * 4);
+    if (drawable->row == NULL)
+       goto drawable_fail;
 
-    buf->row = malloc(MAX_WIDTH * 4);
+    fb = &drawable->Base;
 
     /* basic framebuffer setup */
-    _mesa_initialize_window_framebuffer(&buf->Base, &config->modes);
+    _mesa_initialize_window_framebuffer(fb, visual);
 
     /* add front renderbuffer */
-    frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE);
-    _mesa_add_renderbuffer(&buf->Base, BUFFER_FRONT_LEFT, &frontrb->Base);
+    frontrb = swrast_new_renderbuffer(visual, GL_TRUE);
+    _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base);
 
     /* add back renderbuffer */
-    if (config->modes.doubleBufferMode) {
-       backrb = swrast_new_renderbuffer(&config->modes, GL_FALSE);
-       _mesa_add_renderbuffer(&buf->Base, BUFFER_BACK_LEFT, &backrb->Base);
+    if (visual->doubleBufferMode) {
+       backrb = swrast_new_renderbuffer(visual, GL_FALSE);
+       _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base);
     }
 
     /* add software renderbuffers */
-    _mesa_add_soft_renderbuffers(&buf->Base,
+    _mesa_add_soft_renderbuffers(fb,
                                 GL_FALSE, /* color */
-                                config->modes.haveDepthBuffer,
-                                config->modes.haveStencilBuffer,
-                                config->modes.haveAccumBuffer,
+                                visual->haveDepthBuffer,
+                                visual->haveStencilBuffer,
+                                visual->haveAccumBuffer,
                                 GL_FALSE, /* alpha */
                                 GL_FALSE /* aux bufs */);
 
-    return buf;
+    return GL_TRUE;
+
+drawable_fail:
+
+    if (drawable)
+       free(drawable->row);
+
+    FREE(drawable);
+
+    return GL_FALSE;
 }
 
 static void
-driDestroyDrawable(__DRIdrawable *buf)
+dri_destroy_buffer(__DRIdrawable * dPriv)
 {
     TRACE;
 
-    if (buf) {
-       struct gl_framebuffer *fb = &buf->Base;
+    if (dPriv) {
+       struct dri_drawable *drawable = dri_drawable(dPriv);
+       struct gl_framebuffer *fb;
 
-       free(buf->row);
+       free(drawable->row);
+
+       fb = &drawable->Base;
 
        fb->DeletePending = GL_TRUE;
        _mesa_reference_framebuffer(&fb, NULL);
     }
 }
 
-static void driSwapBuffers(__DRIdrawable *buf)
+static void
+dri_swap_buffers(__DRIdrawable * dPriv)
 {
-    GET_CURRENT_CONTEXT(ctx);
+    __DRIscreen *sPriv = dPriv->driScreenPriv;
 
-    struct swrast_renderbuffer *frontrb =
-       swrast_renderbuffer(buf->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
-    struct swrast_renderbuffer *backrb =
-       swrast_renderbuffer(buf->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+    GET_CURRENT_CONTEXT(ctx);
 
-    __DRIscreen *screen = buf->driScreenPriv;
+    struct dri_drawable *drawable = dri_drawable(dPriv);
+    struct gl_framebuffer *fb;
+    struct swrast_renderbuffer *frontrb, *backrb;
 
     TRACE;
 
+    fb = &drawable->Base;
+
+    frontrb =
+       swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+    backrb =
+       swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
     /* check for signle-buffered */
     if (backrb == NULL)
        return;
 
     /* check if swapping currently bound buffer */
-    if (ctx && ctx->DrawBuffer == &(buf->Base)) {
+    if (ctx && ctx->DrawBuffer == fb) {
        /* flush pending rendering */
        _mesa_notifySwapBuffers(ctx);
     }
 
-    screen->swrast_loader->putImage(buf, __DRI_SWRAST_IMAGE_OP_SWAP,
-                                   0, 0,
-                                   frontrb->Base.Width,
-                                   frontrb->Base.Height,
-                                   backrb->Base.Data,
-                                   buf->loaderPrivate);
+    sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+                                  0, 0,
+                                  frontrb->Base.Width,
+                                  frontrb->Base.Height,
+                                  backrb->Base.Data,
+                                  dPriv->loaderPrivate);
 }
 
 
@@ -432,19 +485,19 @@ static void driSwapBuffers(__DRIdrawable *buf)
  */
 
 static void
-get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h )
+get_window_size( struct gl_framebuffer *fb, GLsizei *w, GLsizei *h )
 {
-    __DRIdrawable *buf = swrast_drawable(fb);
-    __DRIscreen *screen = buf->driScreenPriv;
+    __DRIdrawable *dPriv = swrast_drawable(fb)->dPriv;
+    __DRIscreen *sPriv = dPriv->driScreenPriv;
     int x, y;
 
-    screen->swrast_loader->getDrawableInfo(buf,
-                                          &x, &y, w, h,
-                                          buf->loaderPrivate);
+    sPriv->swrast_loader->getDrawableInfo(dPriv,
+                                         &x, &y, w, h,
+                                         dPriv->loaderPrivate);
 }
 
 static void
-swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb )
+swrast_check_and_update_window_size( struct gl_context *ctx, struct gl_framebuffer *fb )
 {
     GLsizei width, height;
 
@@ -455,7 +508,7 @@ swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb )
 }
 
 static const GLubyte *
-get_string(GLcontext *ctx, GLenum pname)
+get_string(struct gl_context *ctx, GLenum pname)
 {
     (void) ctx;
     switch (pname) {
@@ -469,7 +522,7 @@ get_string(GLcontext *ctx, GLenum pname)
 }
 
 static void
-update_state( GLcontext *ctx, GLuint new_state )
+update_state( struct gl_context *ctx, GLuint new_state )
 {
     /* not much to do here - pass it on */
     _swrast_InvalidateState( ctx, new_state );
@@ -479,15 +532,25 @@ update_state( GLcontext *ctx, GLuint new_state )
 }
 
 static void
-viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
-    GLframebuffer *draw = ctx->WinSysDrawBuffer;
-    GLframebuffer *read = ctx->WinSysReadBuffer;
+    struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
+    struct gl_framebuffer *read = ctx->WinSysReadBuffer;
 
     swrast_check_and_update_window_size(ctx, draw);
     swrast_check_and_update_window_size(ctx, read);
 }
 
+static gl_format swrastChooseTextureFormat(struct gl_context * ctx,
+                                          GLint internalFormat,
+                                          GLenum format,
+                                          GLenum type)
+{
+    if (internalFormat == GL_RGB)
+       return MESA_FORMAT_XRGB8888;
+    return _mesa_choose_tex_format(ctx, internalFormat, format, type);
+}
+
 static void
 swrast_init_driver_functions(struct dd_function_table *driver)
 {
@@ -495,44 +558,103 @@ swrast_init_driver_functions(struct dd_function_table *driver)
     driver->UpdateState = update_state;
     driver->GetBufferSize = NULL;
     driver->Viewport = viewport;
+    driver->ChooseTextureFormat = swrastChooseTextureFormat;
 }
 
+static const char *es2_extensions[] = {
+   /* Used by mesa internally (cf all_mesa_extensions in ../common/utils.c) */
+   "GL_ARB_draw_buffers",
+   "GL_ARB_multisample",
+   "GL_ARB_texture_compression",
+   "GL_ARB_transpose_matrix",
+   "GL_ARB_vertex_buffer_object",
+   "GL_ARB_window_pos",
+   "GL_EXT_blend_func_separate",
+   "GL_EXT_compiled_vertex_array",
+   "GL_EXT_framebuffer_blit",
+   "GL_EXT_multi_draw_arrays",
+   "GL_EXT_polygon_offset",
+   "GL_EXT_texture_object",
+   "GL_EXT_vertex_array",
+   "GL_IBM_multimode_draw_arrays",
+   "GL_MESA_window_pos",
+   "GL_NV_vertex_program",
+
+   /* Required by GLES2 */
+   "GL_ARB_fragment_program",
+   "GL_ARB_fragment_shader",
+   "GL_ARB_multitexture",
+   "GL_ARB_shader_objects",
+   "GL_ARB_texture_cube_map",
+   "GL_ARB_texture_mirrored_repeat",
+   "GL_ARB_texture_non_power_of_two",
+   "GL_ARB_vertex_shader",
+   "GL_EXT_blend_color",
+   "GL_EXT_blend_equation_separate",
+   "GL_EXT_blend_minmax",
+   "GL_EXT_blend_subtract",
+   "GL_EXT_stencil_wrap",
+
+   /* Optional GLES2 */
+   "GL_ARB_framebuffer_object",
+   "GL_EXT_texture_filter_anisotropic",
+   "GL_ARB_depth_texture",
+   "GL_EXT_packed_depth_stencil",
+   "GL_EXT_framebuffer_object",
+   NULL,
+};
+
+static void
+InitExtensionsES2(struct gl_context *ctx)
+{
+   int i;
+
+   /* Can't use driInitExtensions() since it uses extensions from
+    * main/remap_helper.h when called the first time. */
+
+   for (i = 0; es2_extensions[i]; i++)
+      _mesa_enable_extension(ctx, es2_extensions[i]);
+}
 
 /**
  * Context-related functions.
  */
 
-static __DRIcontext *
-driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
-                   __DRIcontext *shared, void *data)
+static GLboolean
+dri_create_context(gl_api api,
+                  const struct gl_config * visual,
+                  __DRIcontext * cPriv, void *sharedContextPrivate)
 {
-    __DRIcontext *ctx;
-    GLcontext *mesaCtx;
+    struct dri_context *ctx = NULL;
+    struct dri_context *share = (struct dri_context *)sharedContextPrivate;
+    struct gl_context *mesaCtx = NULL;
+    struct gl_context *sharedCtx = NULL;
     struct dd_function_table functions;
 
     TRACE;
 
-    ctx = calloc(1, sizeof *ctx);
-    if (!ctx)
-       return NULL;
-
-    ctx->loaderPrivate = data;
+    ctx = CALLOC_STRUCT(dri_context);
+    if (ctx == NULL)
+       goto context_fail;
 
-    ctx->driScreenPriv = screen;
+    cPriv->driverPrivate = ctx;
+    ctx->cPriv = cPriv;
 
     /* build table of device driver functions */
     _mesa_init_driver_functions(&functions);
     swrast_init_driver_functions(&functions);
 
-    if (!_mesa_initialize_context(&ctx->Base, &config->modes,
-                                 shared ? &shared->Base : NULL,
-                                 &functions, (void *) ctx)) {
-      free(ctx);
-      return NULL;
+    if (share) {
+       sharedCtx = &share->Base;
     }
 
     mesaCtx = &ctx->Base;
 
+    /* basic context setup */
+    if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions, (void *) cPriv)) {
+       goto context_fail;
+    }
+
     /* do bounds checking to prevent segfaults and server crashes! */
     mesaCtx->Const.CheckArrayBounds = GL_TRUE;
 
@@ -549,26 +671,50 @@ driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
        tnl->Driver.RunPipeline = _tnl_run_pipeline;
     }
 
+    _mesa_meta_init(mesaCtx);
     _mesa_enable_sw_extensions(mesaCtx);
-    _mesa_enable_1_3_extensions(mesaCtx);
-    _mesa_enable_1_4_extensions(mesaCtx);
-    _mesa_enable_1_5_extensions(mesaCtx);
-    _mesa_enable_2_0_extensions(mesaCtx);
-    _mesa_enable_2_1_extensions(mesaCtx);
 
-    _mesa_meta_init(mesaCtx);
+    switch (api) {
+    case API_OPENGL:
+        _mesa_enable_1_3_extensions(mesaCtx);
+        _mesa_enable_1_4_extensions(mesaCtx);
+        _mesa_enable_1_5_extensions(mesaCtx);
+        _mesa_enable_2_0_extensions(mesaCtx);
+        _mesa_enable_2_1_extensions(mesaCtx);
+
+        driInitExtensions( mesaCtx, NULL, GL_FALSE );
+        break;
+    case API_OPENGLES:
+        _mesa_enable_1_3_extensions(mesaCtx);
+        _mesa_enable_1_4_extensions(mesaCtx);
+        _mesa_enable_1_5_extensions(mesaCtx);
+
+        break;
+    case API_OPENGLES2:
+        InitExtensionsES2( mesaCtx);
+        break;
+    }
+
+    return GL_TRUE;
+
+context_fail:
 
-    return ctx;
+    FREE(ctx);
+
+    return GL_FALSE;
 }
 
 static void
-driDestroyContext(__DRIcontext *ctx)
+dri_destroy_context(__DRIcontext * cPriv)
 {
-    GLcontext *mesaCtx;
     TRACE;
 
-    if (ctx) {
+    if (cPriv) {
+       struct dri_context *ctx = dri_context(cPriv);
+       struct gl_context *mesaCtx;
+
        mesaCtx = &ctx->Base;
+
         _mesa_meta_free(mesaCtx);
        _swsetup_DestroyContext( mesaCtx );
        _swrast_DestroyContext( mesaCtx );
@@ -578,28 +724,26 @@ driDestroyContext(__DRIcontext *ctx)
     }
 }
 
-static int
-driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask)
+static GLboolean
+dri_make_current(__DRIcontext * cPriv,
+                __DRIdrawable * driDrawPriv,
+                __DRIdrawable * driReadPriv)
 {
+    struct gl_context *mesaCtx;
+    struct gl_framebuffer *mesaDraw;
+    struct gl_framebuffer *mesaRead;
     TRACE;
 
-    _mesa_copy_context(&src->Base, &dst->Base, mask);
-    return GL_TRUE;
-}
+    if (cPriv) {
+       struct dri_context *ctx = dri_context(cPriv);
+       struct dri_drawable *draw;
+       struct dri_drawable *read;
 
-static int driBindContext(__DRIcontext *ctx,
-                         __DRIdrawable *draw,
-                         __DRIdrawable *read)
-{
-    GLcontext *mesaCtx;
-    GLframebuffer *mesaDraw;
-    GLframebuffer *mesaRead;
-    TRACE;
-
-    if (ctx) {
-       if (!draw || !read)
+       if (!driDrawPriv || !driReadPriv)
            return GL_FALSE;
 
+       draw = dri_drawable(driDrawPriv);
+       read = dri_drawable(driReadPriv);
        mesaCtx = &ctx->Base;
        mesaDraw = &draw->Base;
        mesaRead = &read->Base;
@@ -614,7 +758,7 @@ static int driBindContext(__DRIcontext *ctx,
        _glapi_check_multithread();
 
        swrast_check_and_update_window_size(mesaCtx, mesaDraw);
-       if (read != draw)
+       if (mesaRead != mesaDraw)
            swrast_check_and_update_window_size(mesaCtx, mesaRead);
 
        _mesa_make_current( mesaCtx,
@@ -629,35 +773,29 @@ static int driBindContext(__DRIcontext *ctx,
     return GL_TRUE;
 }
 
-static int driUnbindContext(__DRIcontext *ctx)
+static GLboolean
+dri_unbind_context(__DRIcontext * cPriv)
 {
     TRACE;
-    (void) ctx;
+    (void) cPriv;
+
+    /* Unset current context and dispath table */
+    _mesa_make_current(NULL, NULL, NULL);
+
     return GL_TRUE;
 }
 
 
-static const __DRIcoreExtension driCoreExtension = {
-    { __DRI_CORE, __DRI_CORE_VERSION },
-    NULL, /* driCreateNewScreen */
-    driDestroyScreen,
-    driGetExtensions,
-    driGetConfigAttrib,
-    driIndexConfigAttrib,
-    NULL, /* driCreateNewDrawable */
-    driDestroyDrawable,
-    driSwapBuffers,
-    driCreateNewContext,
-    driCopyContext,
-    driDestroyContext,
-    driBindContext,
-    driUnbindContext
-};
-
-static const __DRIswrastExtension driSWRastExtension = {
-    { __DRI_SWRAST, __DRI_SWRAST_VERSION },
-    driCreateNewScreen,
-    driCreateNewDrawable
+const struct __DriverAPIRec driDriverAPI = {
+    .InitScreen = dri_init_screen,
+    .DestroyScreen = dri_destroy_screen,
+    .CreateContext = dri_create_context,
+    .DestroyContext = dri_destroy_context,
+    .CreateBuffer = dri_create_buffer,
+    .DestroyBuffer = dri_destroy_buffer,
+    .SwapBuffers = dri_swap_buffers,
+    .MakeCurrent = dri_make_current,
+    .UnbindContext = dri_unbind_context,
 };
 
 /* This is the table of extensions that the loader will dlsym() for. */