Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / fbdev / glfbdev.c
index 76736fe6d8c2b69056abf839da8ab7b43542c420..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"),
  * 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 "imports.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;
-   void *frontStart;
-   void *backStart;
-   size_t size;
+   size_t size;                    /* color buffer size in bytes */
    GLuint bytesPerPixel;
-   GLuint rowStride;               /* in bytes */
-   GLubyte *frontBottom;           /* pointer to last row */
-   GLubyte *backBottom;            /* pointer to last row */
-   GLubyte *curBottom;             /* = frontBottom or backBottom */
-   GLboolean mallocBackBuffer;
 };
 
-/*
- * 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;
 };
 
-
-
-#define GLFBDEV_CONTEXT(CTX)  ((GLFBDevContextPtr) (CTX))
-#define GLFBDEV_BUFFER(BUF)  ((GLFBDevBufferPtr) (BUF))
+/**
+ * Derived from Mesa's gl_renderbuffer class.
+ */
+struct GLFBDevRenderbufferRec {
+   struct gl_renderbuffer Base;
+   GLubyte *bottom;                /* pointer to last row */
+   GLuint rowStride;               /* in bytes */
+   GLboolean mallocedBuffer;
+};
 
 
 /**********************************************************************/
@@ -118,7 +122,7 @@ struct GLFBDevContextRec {
 
 
 static const GLubyte *
-get_string(GLcontext *ctx, GLenum pname)
+get_string(struct gl_context *ctx, GLenum pname)
 {
    (void) ctx;
    switch (pname) {
@@ -131,49 +135,45 @@ 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 = (GLFBDevBufferPtr) buffer;
-   *width = fbdevbuffer->var.xres_virtual;
-   *height = fbdevbuffer->var.yres_virtual;
+   *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 )
-{
-   GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx);
-   GLFBDevBufferPtr fbdevbuf = GLFBDEV_BUFFER(buffer);
-   fbdevctx->curBuffer = fbdevbuf;
-   switch (bufferBit) {
-   case DD_FRONT_LEFT_BIT:
-      fbdevbuf->curBottom = fbdevbuf->frontBottom;
-      break;
-   case DD_BACK_LEFT_BIT:
-      fbdevbuf->curBottom = fbdevbuf->backBottom;
-      break;
-   default:
-      _mesa_problem(ctx, "bad bufferBit in set_buffer()");
+   buffer = ctx->WinSysReadBuffer;
+   get_buffer_size( buffer, &newWidth, &newHeight );
+   if (buffer->Width != newWidth || buffer->Height != newHeight) {
+      _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
    }
 }
 
@@ -184,97 +184,89 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
 
 /* 24-bit BGR */
 #define NAME(PREFIX) PREFIX##_B8G8R8
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
-   const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
-   const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
+   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 3
+   GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 3
 #define INC_PIXEL_PTR(P) P += 3
-#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
-   P[0] = B;  P[1] = G;  P[2] = R
-#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
-   P[0] = B;  P[1] = G;  P[2] = R
-#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
-   R = P[2];  G = P[1];  B = P[0];  A = CHAN_MAX
+#define STORE_PIXEL(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] = CHAN_MAX
 
 #include "swrast/s_spantemp.h"
 
 
 /* 32-bit BGRA */
 #define NAME(PREFIX) PREFIX##_B8G8R8A8
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
-   const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
-   const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
+   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 4
+   GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 4
 #define INC_PIXEL_PTR(P) P += 4
-#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
-   P[0] = B;  P[1] = G;  P[2] = R;  P[3] = 255
-#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
-   P[0] = B;  P[1] = G;  P[2] = R;  P[3] = A
-#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
-   R = P[2];  G = P[1];  B = P[0];  A = P[3]
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   DST[0] = VALUE[BCOMP];  \
+   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_spantemp.h"
 
 
 /* 16-bit BGR (XXX implement dithering someday) */
 #define NAME(PREFIX) PREFIX##_B5G6R5
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
-   const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
-   const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
+   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLushort *P = (GLushort *) (fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 2)
+   GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
 #define INC_PIXEL_PTR(P) P += 1
-#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
-   *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
-#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
-   *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
-#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
-   R = ( (((*P) >> 8) & 0xf8) | (((*P) >> 11) & 0x7) ); \
-   G = ( (((*P) >> 3) & 0xfc) | (((*P) >>  5) & 0x3) ); \
-   B = ( (((*P) << 3) & 0xf8) | (((*P)      ) & 0x7) ); \
-   A = CHAN_MAX
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
+#define FETCH_PIXEL(DST, SRC) \
+   DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
+   DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >>  5) & 0x3) ); \
+   DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
+   DST[ACOMP] = CHAN_MAX
 
 #include "swrast/s_spantemp.h"
 
 
 /* 15-bit BGR (XXX implement dithering someday) */
 #define NAME(PREFIX) PREFIX##_B5G5R5
+#define RB_TYPE GLubyte
 #define SPAN_VARS \
-   const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
-   const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
+   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLushort *P = (GLushort *) (fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 2)
+   GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
 #define INC_PIXEL_PTR(P) P += 1
-#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
-   *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
-#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
-   *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
-#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
-   R = ( (((*P) >> 7) & 0xf8) | (((*P) >> 10) & 0x7) ); \
-   G = ( (((*P) >> 2) & 0xf8) | (((*P) >>  5) & 0x7) ); \
-   B = ( (((*P) << 3) & 0xf8) | (((*P)      ) & 0x7) ); \
-   A = CHAN_MAX
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
+#define FETCH_PIXEL(DST, SRC) \
+   DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
+   DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >>  5) & 0x7) ); \
+   DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
+   DST[ACOMP] = CHAN_MAX
 
 #include "swrast/s_spantemp.h"
 
 
-/* 8-bit color index */
-#define NAME(PREFIX) PREFIX##_CI8
-#define SPAN_VARS \
-   const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
-   const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X)
-#define INC_PIXEL_PTR(P) P += 1
-#define STORE_CI_PIXEL(P, CI) \
-   P[0] = CI
-#define FETCH_CI_PIXEL(CI, P) \
-   CI = P[0]
-
-#include "swrast/s_spantemp.h"
-
 /**********************************************************************/
 /* Public API functions                                               */
 /**********************************************************************/
@@ -287,46 +279,46 @@ glFBDevGetString( int str )
    case GLFBDEV_VENDOR:
       return "Mesa Project";
    case GLFBDEV_VERSION:
-      return "1.0.0";
+      return "1.0.1";
    default:
       return NULL;
    }
 }
 
 
-const void *
+GLFBDevProc
 glFBDevGetProcAddress( const char *procName )
 {
    struct name_address {
       const char *name;
-      const void *func;
+      const GLFBDevProc func;
    };
    static const struct name_address functions[] = {
-      { "glFBDevGetString", (void *) glFBDevGetString },
-      { "glFBDevGetProcAddress", (void *) glFBDevGetProcAddress },
-      { "glFBDevCreateVisual", (void *) glFBDevCreateVisual },
-      { "glFBDevDestroyVisual", (void *) glFBDevDestroyVisual },
-      { "glFBDevGetVisualAttrib", (void *) glFBDevGetVisualAttrib },
-      { "glFBDevCreateBuffer", (void *) glFBDevCreateBuffer },
-      { "glFBDevDestroyBuffer", (void *) glFBDevDestroyBuffer },
-      { "glFBDevGetBufferAttrib", (void *) glFBDevGetBufferAttrib },
-      { "glFBDevGetCurrentDrawBuffer", (void *) glFBDevGetCurrentDrawBuffer },
-      { "glFBDevGetCurrentReadBuffer", (void *) glFBDevGetCurrentReadBuffer },
-      { "glFBDevSwapBuffers", (void *) glFBDevSwapBuffers },
-      { "glFBDevCreateContext", (void *) glFBDevCreateContext },
-      { "glFBDevDestroyContext", (void *) glFBDevDestroyContext },
-      { "glFBDevGetContextAttrib", (void *) glFBDevGetContextAttrib },
-      { "glFBDevGetCurrentContext", (void *) glFBDevGetCurrentContext },
-      { "glFBDevMakeCurrent", (void *) glFBDevMakeCurrent },
+      { "glFBDevGetString", (GLFBDevProc) glFBDevGetString },
+      { "glFBDevGetProcAddress", (GLFBDevProc) glFBDevGetProcAddress },
+      { "glFBDevCreateVisual", (GLFBDevProc) glFBDevCreateVisual },
+      { "glFBDevDestroyVisual", (GLFBDevProc) glFBDevDestroyVisual },
+      { "glFBDevGetVisualAttrib", (GLFBDevProc) glFBDevGetVisualAttrib },
+      { "glFBDevCreateBuffer", (GLFBDevProc) glFBDevCreateBuffer },
+      { "glFBDevDestroyBuffer", (GLFBDevProc) glFBDevDestroyBuffer },
+      { "glFBDevGetBufferAttrib", (GLFBDevProc) glFBDevGetBufferAttrib },
+      { "glFBDevGetCurrentDrawBuffer", (GLFBDevProc) glFBDevGetCurrentDrawBuffer },
+      { "glFBDevGetCurrentReadBuffer", (GLFBDevProc) glFBDevGetCurrentReadBuffer },
+      { "glFBDevSwapBuffers", (GLFBDevProc) glFBDevSwapBuffers },
+      { "glFBDevCreateContext", (GLFBDevProc) glFBDevCreateContext },
+      { "glFBDevDestroyContext", (GLFBDevProc) glFBDevDestroyContext },
+      { "glFBDevGetContextAttrib", (GLFBDevProc) glFBDevGetContextAttrib },
+      { "glFBDevGetCurrentContext", (GLFBDevProc) glFBDevGetCurrentContext },
+      { "glFBDevMakeCurrent", (GLFBDevProc) glFBDevMakeCurrent },
       { NULL, NULL }
    };
    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;
       }
    }
-   return (const void *)_glapi_get_proc_address(procName);
+   return _glapi_get_proc_address(procName);
 }
 
 
@@ -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,19 +437,115 @@ void
 glFBDevDestroyVisual( GLFBDevVisualPtr visual )
 {
    if (visual)
-      _mesa_free(visual);
+      free(visual);
 }
 
 
 int
 glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual, int attrib)
 {
+   /* XXX unfinished */
    (void) visual;
    (void) attrib;
    return -1;
 }
 
 
+static void
+delete_renderbuffer(struct gl_renderbuffer *rb)
+{
+   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+   if (frb->mallocedBuffer) {
+      free(frb->Base.Data);
+   }
+   free(frb);
+}
+
+
+static GLboolean
+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
+    * created.  Never resized or reallocated.
+    */
+   return GL_TRUE;
+}
+
+
+static struct GLFBDevRenderbufferRec *
+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;
+      rb->Base.AllocStorage = renderbuffer_storage;
+
+      if (pixelFormat == PF_B8G8R8) {
+         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;
+      }
+      else if (pixelFormat == PF_B8G8R8A8) {
+         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;
+      }
+      else if (pixelFormat == PF_B5G6R5) {
+         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;
+      }
+      else if (pixelFormat == PF_B5G5R5) {
+         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;
+      }
+
+      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,
@@ -490,12 +553,18 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                      const GLFBDevVisualPtr visual,
                      void *frontBuffer, void *backBuffer, size_t size )
 {
+   struct GLFBDevRenderbufferRec *frontrb, *backrb;
    GLFBDevBufferPtr buf;
 
    ASSERT(visual);
    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 ||
@@ -512,46 +581,49 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
    if (!buf)
       return NULL;
 
-   _mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual,
+   /* basic framebuffer setup */
+   _mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual);
+   /* add front renderbuffer */
+   frontrb = new_glfbdev_renderbuffer(frontBuffer, visual);
+   _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
+                          &frontrb->Base);
+   /* add back renderbuffer */
+   if (visual->glvisual.doubleBufferMode) {
+      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);
+   }
+   /* add software renderbuffers */
+   _mesa_add_soft_renderbuffers(&buf->glframebuffer,
+                                GL_FALSE, /* color */
                                 visual->glvisual.haveDepthBuffer,
                                 visual->glvisual.haveStencilBuffer,
                                 visual->glvisual.haveAccumBuffer,
-                                GL_FALSE);
+                                GL_FALSE, /* alpha */
+                                GL_FALSE /* aux bufs */);
 
    buf->fix = *fixInfo;   /* struct assignment */
    buf->var = *varInfo;   /* struct assignment */
    buf->visual = visual;  /* ptr assignment */
-   buf->frontStart = frontBuffer;
    buf->size = size;
    buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
-   buf->rowStride = visual->var.xres_virtual * buf->bytesPerPixel;
-   buf->frontBottom = (GLubyte *) buf->frontStart
-                    + (visual->var.yres_virtual - 1) * buf->rowStride;
-
-   if (visual->glvisual.doubleBufferMode) {
-      if (backBuffer) {
-         buf->backStart = backBuffer;
-         buf->mallocBackBuffer = GL_FALSE;
-      }
-      else {
-         buf->backStart = _mesa_malloc(size);
-         if (!buf->backStart) {
-            _mesa_free_framebuffer_data(&buf->glframebuffer);
-            _mesa_free(buf);
-            return NULL;
-         }
-         buf->mallocBackBuffer = GL_TRUE;
-      }
-      buf->backBottom = (GLubyte *) buf->backStart
-                      + (visual->var.yres_virtual - 1) * buf->rowStride;
-      buf->curBottom = buf->backBottom;
-   }
-   else {
-      buf->backStart = NULL;
-      buf->mallocBackBuffer = GL_FALSE;
-      buf->backBottom = NULL;
-      buf->curBottom = buf->frontBottom;
-   }
 
    return buf;
 }
@@ -567,12 +639,10 @@ glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
       if (buffer == curDraw || buffer == curRead) {
          glFBDevMakeCurrent( NULL, NULL, NULL);
       }
-      if (buffer->mallocBackBuffer) {
-         _mesa_free(buffer->backStart);
+      {
+         struct gl_framebuffer *fb = &buffer->glframebuffer;
+         _mesa_reference_framebuffer(&fb, NULL);
       }
-      /* free the software depth, stencil, accum buffers */
-      _mesa_free_framebuffer_data(&buffer->glframebuffer);
-      _mesa_free(buffer);
    }
 }
 
@@ -612,6 +682,10 @@ void
 glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
 {
    GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
+   struct GLFBDevRenderbufferRec *frontrb = (struct GLFBDevRenderbufferRec *)
+      buffer->glframebuffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+   struct GLFBDevRenderbufferRec *backrb = (struct GLFBDevRenderbufferRec *)
+      buffer->glframebuffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
 
    if (!buffer || !buffer->visual->glvisual.doubleBufferMode)
       return;
@@ -622,9 +696,9 @@ glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
       _mesa_notifySwapBuffers(&fbdevctx->glcontext);
    }
 
-   ASSERT(buffer->frontStart);
-   ASSERT(buffer->backStart);
-   _mesa_memcpy(buffer->frontStart, buffer->backStart, buffer->size);
+   ASSERT(frontrb->Base.Data);
+   ASSERT(backrb->Base.Data);
+   memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
 }
 
 
@@ -632,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);
@@ -651,75 +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;
-      if (visual->pixelFormat == PF_B8G8R8) {
-         swdd->WriteRGBASpan = write_rgba_span_B8G8R8;
-         swdd->WriteRGBSpan = write_rgb_span_B8G8R8;
-         swdd->WriteMonoRGBASpan = write_monorgba_span_B8G8R8;
-         swdd->WriteRGBAPixels = write_rgba_pixels_B8G8R8;
-         swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B8G8R8;
-         swdd->ReadRGBASpan = read_rgba_span_B8G8R8;
-         swdd->ReadRGBAPixels = read_rgba_pixels_B8G8R8;
-      }
-      else if (visual->pixelFormat == PF_B8G8R8A8) {
-         swdd->WriteRGBASpan = write_rgba_span_B8G8R8A8;
-         swdd->WriteRGBSpan = write_rgb_span_B8G8R8A8;
-         swdd->WriteMonoRGBASpan = write_monorgba_span_B8G8R8A8;
-         swdd->WriteRGBAPixels = write_rgba_pixels_B8G8R8A8;
-         swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B8G8R8A8;
-         swdd->ReadRGBASpan = read_rgba_span_B8G8R8A8;
-         swdd->ReadRGBAPixels = read_rgba_pixels_B8G8R8A8;
-      }
-      else if (visual->pixelFormat == PF_B5G6R5) {
-         swdd->WriteRGBASpan = write_rgba_span_B5G6R5;
-         swdd->WriteRGBSpan = write_rgb_span_B5G6R5;
-         swdd->WriteMonoRGBASpan = write_monorgba_span_B5G6R5;
-         swdd->WriteRGBAPixels = write_rgba_pixels_B5G6R5;
-         swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B5G6R5;
-         swdd->ReadRGBASpan = read_rgba_span_B5G6R5;
-         swdd->ReadRGBAPixels = read_rgba_pixels_B5G6R5;
-      }
-      else if (visual->pixelFormat == PF_B5G5R5) {
-         swdd->WriteRGBASpan = write_rgba_span_B5G5R5;
-         swdd->WriteRGBSpan = write_rgb_span_B5G5R5;
-         swdd->WriteMonoRGBASpan = write_monorgba_span_B5G5R5;
-         swdd->WriteRGBAPixels = write_rgba_pixels_B5G5R5;
-         swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B5G5R5;
-         swdd->ReadRGBASpan = read_rgba_span_B5G5R5;
-         swdd->ReadRGBAPixels = read_rgba_pixels_B5G5R5;
-      }
-      else if (visual->pixelFormat == PF_CI8) {
-         swdd->WriteCI32Span = write_index32_span_CI8;
-         swdd->WriteCI8Span = write_index8_span_CI8;
-         swdd->WriteMonoCISpan = write_monoindex_span_CI8;
-         swdd->WriteCI32Pixels = write_index_pixels_CI8;
-         swdd->WriteMonoCIPixels = write_monoindex_pixels_CI8;
-         swdd->ReadCI32Span = read_index_span_CI8;
-         swdd->ReadCI32Pixels = read_index_pixels_CI8;
-      }
-      else {
-         _mesa_printf("bad pixelformat: %d\n", visual->pixelFormat);
-      }
-   }
-
    /* use default TCL pipeline */
    {
       TNLcontext *tnl = TNL_CONTEXT(glctx);
@@ -727,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;
 }
@@ -738,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_current2(NULL, NULL, NULL);
-         _mesa_notifyDestroy(&context->glcontext);
+         _mesa_make_current(NULL, NULL, NULL);
       }
       _mesa_free_context_data(&context->glcontext);
-      _mesa_free(context);
+      free(context);
    }
 }
 
@@ -780,19 +810,19 @@ glFBDevMakeCurrent( GLFBDevContextPtr context,
           context->visual != readBuffer->visual) {
          return 0;
       }
-      _mesa_make_current2( &context->glcontext,
-                           &drawBuffer->glframebuffer,
-                           &readBuffer->glframebuffer );
+      _mesa_make_current( &context->glcontext,
+                          &drawBuffer->glframebuffer,
+                          &readBuffer->glframebuffer );
       context->drawBuffer = drawBuffer;
       context->readBuffer = readBuffer;
       context->curBuffer = drawBuffer;
    }
    else {
       /* unbind */
-      _mesa_make_current2( NULL, NULL, NULL );
+      _mesa_make_current( NULL, NULL, NULL );
    }
 
    return 1;
 }
 
-
+#endif /* USE_GLFBDEV_DRIVER */