Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / fbdev / glfbdev.c
index c8d9375b62409a7043b51d19e14b13185c77a14e..5195bca97fa5e5437f4aaa5ddc742200d19e9bdf 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  7.1
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * 24 bits |    ?     0x312   0x315    0x318      ?      0x31B     0x31F
  * 32 bits |    ?       ?       ?        ?      0x164      ?
  */
+
 #ifdef USE_GLFBDEV_DRIVER
 
-#include "glheader.h"
-#include <linux/fb.h>
 #include "GL/glfbdev.h"
-#include "buffers.h"
-#include "context.h"
-#include "extensions.h"
-#include "fbobject.h"
-#include "framebuffer.h"
-#include "imports.h"
-#include "renderbuffer.h"
-#include "texformat.h"
-#include "teximage.h"
-#include "texstore.h"
-#include "array_cache/acache.h"
+#include <linux/fb.h>
+#include "main/glheader.h"
+#include "main/buffers.h"
+#include "main/context.h"
+#include "main/extensions.h"
+#include "main/fbobject.h"
+#include "main/framebuffer.h"
+#include "main/imports.h"
+#include "main/renderbuffer.h"
+#include "main/texformat.h"
+#include "main/teximage.h"
+#include "main/texstore.h"
+#include "vbo/vbo.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "tnl/tnl.h"
 #include "drivers/common/driverfuncs.h"
 
 
+/**
+ * Pixel formats we support:
+ */
 #define PF_B8G8R8     1
 #define PF_B8G8R8A8   2
 #define PF_B5G6R5     3
 #define PF_B5G5R5     4
-#define PF_CI8        5
 
 
-/*
- * Derived from Mesa's GLvisual class.
+/**
+ * Derived from Mesa's struct gl_config class.
  */
 struct GLFBDevVisualRec {
-   GLvisual glvisual;              /* base class */
+   struct gl_config glvisual;              /* base class */
    struct fb_fix_screeninfo fix;
    struct fb_var_screeninfo var;
    int pixelFormat;
 };
 
-/*
- * Derived from Mesa's GLframebuffer class.
+/**
+ * Derived from Mesa's struct gl_framebuffer class.
  */
 struct GLFBDevBufferRec {
-   GLframebuffer glframebuffer;    /* base class */
+   struct gl_framebuffer glframebuffer;    /* base class */
    GLFBDevVisualPtr visual;
    struct fb_fix_screeninfo fix;
    struct fb_var_screeninfo var;
@@ -91,18 +94,18 @@ struct GLFBDevBufferRec {
    GLuint bytesPerPixel;
 };
 
-/*
- * Derived from Mesa's GLcontext class.
+/**
+ * Derived from Mesa's struct gl_context class.
  */
 struct GLFBDevContextRec {
-   GLcontext glcontext;            /* base class */
+   struct gl_context glcontext;            /* base class */
    GLFBDevVisualPtr visual;
    GLFBDevBufferPtr drawBuffer;
    GLFBDevBufferPtr readBuffer;
    GLFBDevBufferPtr curBuffer;
 };
 
-/*
+/**
  * Derived from Mesa's gl_renderbuffer class.
  */
 struct GLFBDevRenderbufferRec {
@@ -113,18 +116,13 @@ struct GLFBDevRenderbufferRec {
 };
 
 
-
-#define GLFBDEV_CONTEXT(CTX)  ((GLFBDevContextPtr) (CTX))
-#define GLFBDEV_BUFFER(BUF)  ((GLFBDevBufferPtr) (BUF))
-
-
 /**********************************************************************/
 /* Internal device driver functions                                   */
 /**********************************************************************/
 
 
 static const GLubyte *
-get_string(GLcontext *ctx, GLenum pname)
+get_string(struct gl_context *ctx, GLenum pname)
 {
    (void) ctx;
    switch (pname) {
@@ -137,38 +135,46 @@ 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 );
    _swsetup_InvalidateState( ctx, new_state );
-   _ac_InvalidateState( ctx, new_state );
+   _vbo_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
 }
 
 
 static void
-get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
+get_buffer_size( struct gl_framebuffer *buffer, GLuint *width, GLuint *height )
 {
-   const GLFBDevBufferPtr fbdevbuffer = GLFBDEV_BUFFER(buffer);
-   *width = fbdevbuffer->var.xres_virtual;
-   *height = fbdevbuffer->var.yres_virtual;
+   const GLFBDevBufferPtr fbdevbuffer = (GLFBDevBufferPtr) buffer;
+   *width = fbdevbuffer->var.xres;
+   *height = fbdevbuffer->var.yres;
 }
 
 
+/**
+ * We only implement this function as a mechanism to check if the
+ * framebuffer size has changed (and update corresponding 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)
 {
-   /* poll for window size change and realloc software Z/stencil/etc if needed */
-   _mesa_ResizeBuffersMESA();
-}
+   GLuint newWidth, newHeight;
+   struct gl_framebuffer *buffer;
 
+   buffer = ctx->WinSysDrawBuffer;
+   get_buffer_size( buffer, &newWidth, &newHeight );
+   if (buffer->Width != newWidth || buffer->Height != newHeight) {
+      _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
+   }
 
-/* specifies the buffer for swrast span rendering/reading */
-static void
-set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
-{
-   /* this is a no-op when using the new gl_renderbuffer span functions. */
+   buffer = ctx->WinSysReadBuffer;
+   get_buffer_size( buffer, &newWidth, &newHeight );
+   if (buffer->Width != newWidth || buffer->Height != newHeight) {
+      _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
+   }
 }
 
 
@@ -178,7 +184,7 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
 
 /* 24-bit BGR */
 #define NAME(PREFIX) PREFIX##_B8G8R8
-#define FORMAT GL_RGBA8
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
    struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
@@ -194,12 +200,12 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
    DST[BCOMP] = SRC[0];  \
    DST[ACOMP] = CHAN_MAX
 
-#include "swrast/s_spantemp2.h"
+#include "swrast/s_spantemp.h"
 
 
 /* 32-bit BGRA */
 #define NAME(PREFIX) PREFIX##_B8G8R8A8
-#define FORMAT GL_RGBA8
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
    struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
@@ -210,18 +216,22 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
    DST[1] = VALUE[GCOMP];  \
    DST[2] = VALUE[RCOMP];  \
    DST[3] = VALUE[ACOMP]
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+   DST[0] = VALUE[BCOMP];  \
+   DST[1] = VALUE[GCOMP];  \
+   DST[2] = VALUE[RCOMP];
 #define FETCH_PIXEL(DST, SRC) \
    DST[RCOMP] = SRC[2];  \
    DST[GCOMP] = SRC[1];  \
    DST[BCOMP] = SRC[0];  \
    DST[ACOMP] = SRC[3]
 
-#include "swrast/s_spantemp2.h"
+#include "swrast/s_spantemp.h"
 
 
 /* 16-bit BGR (XXX implement dithering someday) */
 #define NAME(PREFIX) PREFIX##_B5G6R5
-#define FORMAT GL_RGBA8
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
    struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
@@ -235,12 +245,12 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
    DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
    DST[ACOMP] = CHAN_MAX
 
-#include "swrast/s_spantemp2.h"
+#include "swrast/s_spantemp.h"
 
 
 /* 15-bit BGR (XXX implement dithering someday) */
 #define NAME(PREFIX) PREFIX##_B5G5R5
-#define FORMAT GL_RGBA8
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
    struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
@@ -254,25 +264,7 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
    DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
    DST[ACOMP] = CHAN_MAX
 
-#include "swrast/s_spantemp2.h"
-
-
-/* 8-bit color index */
-#define NAME(PREFIX) PREFIX##_CI8
-#define FORMAT GL_COLOR_INDEX8_EXT
-#define SPAN_VARS \
-   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X)
-#define INC_PIXEL_PTR(P) P += 1
-#define STORE_PIXEL(DST, X, Y, VALUE) \
-   *DST = VALUE[0]
-#define FETCH_PIXEL(DST, SRC) \
-   DST = SRC[0]
-
-#include "swrast/s_spantemp2.h"
-
-
+#include "swrast/s_spantemp.h"
 
 
 /**********************************************************************/
@@ -287,14 +279,14 @@ glFBDevGetString( int str )
    case GLFBDEV_VENDOR:
       return "Mesa Project";
    case GLFBDEV_VERSION:
-      return "1.0.0";
+      return "1.0.1";
    default:
       return NULL;
    }
 }
 
 
-const GLFBDevProc
+GLFBDevProc
 glFBDevGetProcAddress( const char *procName )
 {
    struct name_address {
@@ -322,7 +314,7 @@ glFBDevGetProcAddress( const char *procName )
    };
    const struct name_address *entry;
    for (entry = functions; entry->name; entry++) {
-      if (_mesa_strcmp(entry->name, procName) == 0) {
+      if (strcmp(entry->name, procName) == 0) {
          return entry->func;
       }
    }
@@ -337,9 +329,9 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
 {
    GLFBDevVisualPtr vis;
    const int *attrib;
-   GLboolean rgbFlag = GL_TRUE, dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
+   GLboolean dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
    GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
-   GLint indexBits = 0, depthBits = 0, stencilBits = 0;
+   GLint depthBits = 0, stencilBits = 0;
    GLint accumRedBits = 0, accumGreenBits = 0;
    GLint accumBlueBits = 0, accumAlphaBits = 0;
    GLint numSamples = 0;
@@ -359,9 +351,6 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
       case GLFBDEV_DOUBLE_BUFFER:
          dbFlag = GL_TRUE;
          break;
-      case GLFBDEV_COLOR_INDEX:
-         rgbFlag = GL_FALSE;
-         break;
       case GLFBDEV_DEPTH_SIZE:
          depthBits = attrib[1];
          attrib++;
@@ -378,47 +367,45 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
       case GLFBDEV_LEVEL:
          /* ignored for now */
          break;
+      case GLFBDEV_MULTISAMPLE:
+         numSamples = attrib[1];
+         attrib++;
+         break;
+      case GLFBDEV_COLOR_INDEX:
+         /* Mesa no longer supports color-index rendering. */
       default:
          /* unexpected token */
-         _mesa_free(vis);
+         free(vis);
          return NULL;
       }
    }
 
-   if (rgbFlag) {
-      redBits   = varInfo->red.length;
-      greenBits = varInfo->green.length;
-      blueBits  = varInfo->blue.length;
-      alphaBits = varInfo->transp.length;
+   redBits   = varInfo->red.length;
+   greenBits = varInfo->green.length;
+   blueBits  = varInfo->blue.length;
+   alphaBits = varInfo->transp.length;
 
-      if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
-           fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
-          && varInfo->bits_per_pixel == 24
+   if (fixInfo->visual == FB_VISUAL_TRUECOLOR ||
+       fixInfo->visual == FB_VISUAL_DIRECTCOLOR) {
+      if (varInfo->bits_per_pixel == 24
           && varInfo->red.offset == 16
           && varInfo->green.offset == 8
           && varInfo->blue.offset == 0) {
          vis->pixelFormat = PF_B8G8R8;
       }
-      else if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
-                fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
-               && varInfo->bits_per_pixel == 32
+      else if (varInfo->bits_per_pixel == 32
                && varInfo->red.offset == 16
                && varInfo->green.offset == 8
-               && varInfo->blue.offset == 0
-               && varInfo->transp.offset == 24) {
+               && varInfo->blue.offset == 0) {
          vis->pixelFormat = PF_B8G8R8A8;
       }
-      else if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
-                fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
-               && varInfo->bits_per_pixel == 16
+      else if (varInfo->bits_per_pixel == 16
                && varInfo->red.offset == 11
                && varInfo->green.offset == 5
                && varInfo->blue.offset == 0) {
          vis->pixelFormat = PF_B5G6R5;
       }
-      else if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
-                fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
-               && varInfo->bits_per_pixel == 16
+      else if (varInfo->bits_per_pixel == 16
                && varInfo->red.offset == 10
                && varInfo->green.offset == 5
                && varInfo->blue.offset == 0) {
@@ -426,39 +413,19 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
       }
       else {
          _mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
-         /*
-         printf("fixInfo->visual = 0x%x\n", fixInfo->visual);
-         printf("varInfo->bits_per_pixel = %d\n", varInfo->bits_per_pixel);
-         printf("varInfo->red.offset = %d\n", varInfo->red.offset);
-         printf("varInfo->green.offset = %d\n", varInfo->green.offset);
-         printf("varInfo->blue.offset = %d\n", varInfo->blue.offset);
-         */
-         _mesa_free(vis);
-         return NULL;
-      }
-   }
-   else {
-      indexBits = varInfo->bits_per_pixel;
-      if ((fixInfo->visual == FB_VISUAL_PSEUDOCOLOR ||
-           fixInfo->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
-          && varInfo->bits_per_pixel == 8) {
-         vis->pixelFormat = PF_CI8;
-      }
-      else {
-         _mesa_problem(NULL, "Unsupported fbdev CI visual/bitdepth!\n");
-         _mesa_free(vis);
+         free(vis);
          return NULL;
       }
    }
 
-   if (!_mesa_initialize_visual(&vis->glvisual, rgbFlag, dbFlag, stereoFlag,
+   if (!_mesa_initialize_visual(&vis->glvisual, dbFlag, stereoFlag,
                                 redBits, greenBits, blueBits, alphaBits,
-                                indexBits, depthBits, stencilBits,
+                                depthBits, stencilBits,
                                 accumRedBits, accumGreenBits,
                                 accumBlueBits, accumAlphaBits,
                                 numSamples)) {
       /* something was invalid */
-      _mesa_free(vis);
+      free(vis);
       return NULL;
    }
 
@@ -470,7 +437,7 @@ void
 glFBDevDestroyVisual( GLFBDevVisualPtr visual )
 {
    if (visual)
-      _mesa_free(visual);
+      free(visual);
 }
 
 
@@ -489,14 +456,14 @@ delete_renderbuffer(struct gl_renderbuffer *rb)
 {
    struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
    if (frb->mallocedBuffer) {
-      _mesa_free(frb->Base.Data);
+      free(frb->Base.Data);
    }
-   _mesa_free(frb);
+   free(frb);
 }
 
 
 static GLboolean
-renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                      GLenum internalFormat, GLuint width, GLuint height)
 {
    /* no-op: the renderbuffer storage is allocated just once when it's
@@ -507,11 +474,13 @@ renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 
 
 static struct GLFBDevRenderbufferRec *
-new_glfbdev_renderbuffer(void *bufferStart, int pixelFormat)
+new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
 {
    struct GLFBDevRenderbufferRec *rb = CALLOC_STRUCT(GLFBDevRenderbufferRec);
    if (rb) {
       GLuint name = 0;
+      int pixelFormat = visual->pixelFormat;
+
       _mesa_init_renderbuffer(&rb->Base, name);
 
       rb->Base.Delete = delete_renderbuffer;
@@ -521,6 +490,7 @@ new_glfbdev_renderbuffer(void *bufferStart, int pixelFormat)
          rb->Base.GetRow = get_row_B8G8R8;
          rb->Base.GetValues = get_values_B8G8R8;
          rb->Base.PutRow = put_row_B8G8R8;
+         rb->Base.PutRowRGB = put_row_rgb_B8G8R8;
          rb->Base.PutMonoRow = put_mono_row_B8G8R8;
          rb->Base.PutValues = put_values_B8G8R8;
          rb->Base.PutMonoValues = put_mono_values_B8G8R8;
@@ -529,6 +499,7 @@ new_glfbdev_renderbuffer(void *bufferStart, int pixelFormat)
          rb->Base.GetRow = get_row_B8G8R8A8;
          rb->Base.GetValues = get_values_B8G8R8A8;
          rb->Base.PutRow = put_row_B8G8R8A8;
+         rb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
          rb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
          rb->Base.PutValues = put_values_B8G8R8A8;
          rb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
@@ -537,6 +508,7 @@ new_glfbdev_renderbuffer(void *bufferStart, int pixelFormat)
          rb->Base.GetRow = get_row_B5G6R5;
          rb->Base.GetValues = get_values_B5G6R5;
          rb->Base.PutRow = put_row_B5G6R5;
+         rb->Base.PutRowRGB = put_row_rgb_B5G6R5;
          rb->Base.PutMonoRow = put_mono_row_B5G6R5;
          rb->Base.PutValues = put_values_B5G6R5;
          rb->Base.PutMonoValues = put_mono_values_B5G6R5;
@@ -545,34 +517,36 @@ new_glfbdev_renderbuffer(void *bufferStart, int pixelFormat)
          rb->Base.GetRow = get_row_B5G5R5;
          rb->Base.GetValues = get_values_B5G5R5;
          rb->Base.PutRow = put_row_B5G5R5;
+         rb->Base.PutRowRGB = put_row_rgb_B5G5R5;
          rb->Base.PutMonoRow = put_mono_row_B5G5R5;
          rb->Base.PutValues = put_values_B5G5R5;
          rb->Base.PutMonoValues = put_mono_values_B5G5R5;
       }
-      else if (pixelFormat == PF_CI8) {
-         rb->Base.GetRow = get_row_CI8;
-         rb->Base.GetValues = get_values_CI8;
-         rb->Base.PutRow = put_row_CI8;
-         rb->Base.PutMonoRow = put_mono_row_CI8;
-         rb->Base.PutValues = put_values_CI8;
-         rb->Base.PutMonoValues = put_mono_values_CI8;
-      }
 
-      if (pixelFormat == PF_CI8) {
-         rb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
-         rb->Base._BaseFormat = GL_COLOR_INDEX;
-      }
-      else {
-         rb->Base.InternalFormat = GL_RGBA;
-         rb->Base._BaseFormat = GL_RGBA;
-      }
+      rb->Base.InternalFormat = GL_RGBA;
+      rb->Base._BaseFormat = GL_RGBA;
       rb->Base.DataType = GL_UNSIGNED_BYTE;
       rb->Base.Data = bufferStart;
+
+      rb->rowStride = visual->var.xres_virtual * visual->var.bits_per_pixel / 8;
+      rb->bottom = (GLubyte *) bufferStart
+                 + (visual->var.yres - 1) * rb->rowStride;
+
+      rb->Base.Width = visual->var.xres;
+      rb->Base.Height = visual->var.yres;
+
+      /*
+      rb->Base.RedBits = visual->var.red.length;
+      rb->Base.GreenBits = visual->var.green.length;
+      rb->Base.BlueBits = visual->var.blue.length;
+      rb->Base.AlphaBits = visual->var.transp.length;
+      */
+
+      rb->Base.InternalFormat = pixelFormat;
    }
    return rb;
 }
 
-
 GLFBDevBufferPtr
 glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                      const struct fb_var_screeninfo *varInfo,
@@ -586,6 +560,11 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
    ASSERT(frontBuffer);
    ASSERT(size > 0);
 
+   /* this is to update the visual if there was a resize and the
+      buffer is created again */
+   visual->var = *varInfo;
+   visual->fix = *fixInfo;
+
    if (visual->fix.visual != fixInfo->visual ||
        visual->fix.type != fixInfo->type ||
        visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
@@ -603,14 +582,31 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
       return NULL;
 
    /* basic framebuffer setup */
-   _mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual);
+   _mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual);
    /* add front renderbuffer */
-   frontrb = new_glfbdev_renderbuffer(frontBuffer, visual->pixelFormat);
+   frontrb = new_glfbdev_renderbuffer(frontBuffer, visual);
    _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
                           &frontrb->Base);
    /* add back renderbuffer */
    if (visual->glvisual.doubleBufferMode) {
-      backrb = new_glfbdev_renderbuffer(backBuffer, visual->pixelFormat);
+      const int malloced = !backBuffer;
+      if (malloced) {
+         /* malloc a back buffer */
+         backBuffer = malloc(size);
+         if (!backBuffer) {
+            _mesa_free_framebuffer_data(&buf->glframebuffer);
+            free(buf);
+            return NULL;
+         }
+      }
+
+      backrb = new_glfbdev_renderbuffer(backBuffer, visual);
+      if (!backrb) {
+         /* out of mem */
+         return NULL;
+      }
+      backrb->mallocedBuffer = malloced;
+
       _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
                              &backrb->Base);
    }
@@ -623,36 +619,11 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                                 GL_FALSE, /* alpha */
                                 GL_FALSE /* aux bufs */);
 
-
-
    buf->fix = *fixInfo;   /* struct assignment */
    buf->var = *varInfo;   /* struct assignment */
    buf->visual = visual;  /* ptr assignment */
    buf->size = size;
    buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
-   frontrb->rowStride = visual->var.xres_virtual * buf->bytesPerPixel;
-   frontrb->bottom = (GLubyte *) frontrb->Base.Data
-      + (visual->var.yres_virtual - 1) * frontrb->rowStride;
-
-   if (visual->glvisual.doubleBufferMode) {
-      if (!backBuffer) {
-         /* malloc a back buffer */
-         backrb->Base.Data = _mesa_malloc(size);
-         if (!backrb->Base.Data) {
-            _mesa_free_framebuffer_data(&buf->glframebuffer);
-            _mesa_free(buf);
-            return NULL;
-         }
-         backrb->mallocedBuffer = GL_TRUE;
-      }
-      backrb->rowStride = frontrb->rowStride;
-      backrb->bottom = (GLubyte *) backrb->Base.Data
-         + (visual->var.yres_virtual - 1) * backrb->rowStride;
-   }
-   else {
-      backrb->bottom = NULL;
-      backrb->rowStride = 0;
-   }
 
    return buf;
 }
@@ -668,9 +639,10 @@ glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
       if (buffer == curDraw || buffer == curRead) {
          glFBDevMakeCurrent( NULL, NULL, NULL);
       }
-      /* free the software depth, stencil, accum buffers */
-      _mesa_free_framebuffer_data(&buffer->glframebuffer);
-      _mesa_free(buffer);
+      {
+         struct gl_framebuffer *fb = &buffer->glframebuffer;
+         _mesa_reference_framebuffer(&fb, NULL);
+      }
    }
 }
 
@@ -726,7 +698,7 @@ glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
 
    ASSERT(frontrb->Base.Data);
    ASSERT(backrb->Base.Data);
-   _mesa_memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
+   memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
 }
 
 
@@ -734,7 +706,7 @@ GLFBDevContextPtr
 glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
 {
    GLFBDevContextPtr ctx;
-   GLcontext *glctx;
+   struct gl_context *glctx;
    struct dd_function_table functions;
 
    ASSERT(visual);
@@ -753,36 +725,20 @@ glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
    if (!_mesa_initialize_context(&ctx->glcontext, &visual->glvisual,
                                  share ? &share->glcontext : NULL,
                                  &functions, (void *) ctx)) {
-      _mesa_free(ctx);
+      free(ctx);
       return NULL;
    }
 
    ctx->visual = visual;
 
    /* Create module contexts */
-   glctx = (GLcontext *) &ctx->glcontext;
+   glctx = (struct gl_context *) &ctx->glcontext;
    _swrast_CreateContext( glctx );
-   _ac_CreateContext( glctx );
+   _vbo_CreateContext( glctx );
    _tnl_CreateContext( glctx );
    _swsetup_CreateContext( glctx );
    _swsetup_Wakeup( glctx );
 
-   /* swrast init */
-   {
-      struct swrast_device_driver *swdd;
-      swdd = _swrast_GetDeviceDriverReference( glctx );
-      swdd->SetBuffer = set_buffer;
-
-      /* no longer used */
-      swdd->WriteRGBASpan = NULL;
-      swdd->WriteRGBSpan = NULL;
-      swdd->WriteMonoRGBASpan = NULL;
-      swdd->WriteRGBAPixels = NULL;
-      swdd->WriteMonoRGBAPixels = NULL;
-      swdd->ReadRGBASpan = NULL;
-      swdd->ReadRGBAPixels = NULL;
-   }
-
    /* use default TCL pipeline */
    {
       TNLcontext *tnl = TNL_CONTEXT(glctx);
@@ -790,6 +746,11 @@ glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
    }
 
    _mesa_enable_sw_extensions(glctx);
+   _mesa_enable_1_3_extensions(glctx);
+   _mesa_enable_1_4_extensions(glctx);
+   _mesa_enable_1_5_extensions(glctx);
+   _mesa_enable_2_0_extensions(glctx);
+   _mesa_enable_2_1_extensions(glctx);
 
    return ctx;
 }
@@ -801,13 +762,19 @@ glFBDevDestroyContext( GLFBDevContextPtr context )
    GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
 
    if (context) {
+      struct gl_context *mesaCtx = &context->glcontext;
+
+      _swsetup_DestroyContext( mesaCtx );
+      _swrast_DestroyContext( mesaCtx );
+      _tnl_DestroyContext( mesaCtx );
+      _vbo_DestroyContext( mesaCtx );
+
       if (fbdevctx == context) {
          /* destroying current context */
          _mesa_make_current(NULL, NULL, NULL);
-         _mesa_notifyDestroy(&context->glcontext);
       }
       _mesa_free_context_data(&context->glcontext);
-      _mesa_free(context);
+      free(context);
    }
 }
 
@@ -858,4 +825,4 @@ glFBDevMakeCurrent( GLFBDevContextPtr context,
    return 1;
 }
 
-#endif
+#endif /* USE_GLFBDEV_DRIVER */