Header file clean-up:
[mesa.git] / src / mesa / drivers / osmesa / osmesa.c
index d0833be786f6f0d09e31d0dc5428a32dba749241..5efb52391b6472c9739fcce2e54905a265b47921 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: osmesa.c,v 1.46 2001/02/12 18:32:26 brianp Exp $ */
+/* $Id: osmesa.c,v 1.93 2002/10/24 23:57:23 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  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"),
 
 #include "glheader.h"
 #include "GL/osmesa.h"
+#include "buffers.h"
 #include "context.h"
 #include "colormac.h"
 #include "depth.h"
 #include "extensions.h"
+#include "imports.h"
 #include "macros.h"
 #include "matrix.h"
-#include "mem.h"
 #include "mmath.h"
 #include "mtypes.h"
+#include "texformat.h"
 #include "texstore.h"
 #include "array_cache/acache.h"
 #include "swrast/swrast.h"
@@ -55,6 +57,8 @@
 #include "swrast/s_lines.h"
 #include "swrast/s_triangle.h"
 #include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
 
 
 
@@ -108,7 +112,7 @@ static void osmesa_register_swrast_functions( GLcontext *ctx );
  *                     display lists.  NULL indicates no sharing.
  * Return:  an OSMesaContext or 0 if error
  */
-OSMesaContext GLAPIENTRY
+GLAPI OSMesaContext GLAPIENTRY
 OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
 {
    return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
@@ -122,21 +126,19 @@ OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  *
  * Create context and specify size of ancillary buffers.
  */
-OSMesaContext GLAPIENTRY
+GLAPI OSMesaContext GLAPIENTRY
 OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
                         GLint accumBits, OSMesaContext sharelist )
 {
    OSMesaContext osmesa;
    GLint rshift, gshift, bshift, ashift;
    GLint rind, gind, bind, aind;
-   GLint indexBits, redBits, greenBits, blueBits, alphaBits;
+   GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
    GLboolean rgbmode;
-   GLboolean swalpha;
    const GLuint i4 = 1;
    const GLubyte *i1 = (GLubyte *) &i4;
    const GLint little_endian = *i1;
 
-   swalpha = GL_FALSE;
    rind = gind = bind = aind = 0;
    if (format==OSMESA_COLOR_INDEX) {
       indexBits = 8;
@@ -145,10 +147,10 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
    }
    else if (format==OSMESA_RGBA) {
       indexBits = 0;
-      redBits = 8;
-      greenBits = 8;
-      blueBits = 8;
-      alphaBits = 8;
+      redBits = CHAN_BITS;
+      greenBits = CHAN_BITS;
+      blueBits = CHAN_BITS;
+      alphaBits = CHAN_BITS;
       rind = 0;
       gind = 1;
       bind = 2;
@@ -169,19 +171,19 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
    }
    else if (format==OSMESA_BGRA) {
       indexBits = 0;
-      redBits = 8;
-      greenBits = 8;
-      blueBits = 8;
-      alphaBits = 8;
-      rind = 2;
-      gind = 1;
+      redBits = CHAN_BITS;
+      greenBits = CHAN_BITS;
+      blueBits = CHAN_BITS;
+      alphaBits = CHAN_BITS;
       bind = 0;
+      gind = 1;
+      rind = 2;
       aind = 3;
       if (little_endian) {
-         ashift = 0;
-         rshift = 8;
-         gshift = 16;
-         bshift = 24;
+         bshift = 0;
+         gshift = 8;
+         rshift = 16;
+         ashift = 24;
       }
       else {
          bshift = 24;
@@ -193,19 +195,19 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
    }
    else if (format==OSMESA_ARGB) {
       indexBits = 0;
-      redBits = 8;
-      greenBits = 8;
-      blueBits = 8;
-      alphaBits = 8;
+      redBits = CHAN_BITS;
+      greenBits = CHAN_BITS;
+      blueBits = CHAN_BITS;
+      alphaBits = CHAN_BITS;
+      aind = 0;
       rind = 1;
       gind = 2;
       bind = 3;
-      aind = 0;
       if (little_endian) {
-         bshift = 0;
-         gshift = 8;
-         rshift = 16;
-         ashift = 24;
+         ashift = 0;
+         rshift = 8;
+         gshift = 16;
+         bshift = 24;
       }
       else {
          ashift = 24;
@@ -217,9 +219,9 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
    }
    else if (format==OSMESA_RGB) {
       indexBits = 0;
-      redBits = 8;
-      greenBits = 8;
-      blueBits = 8;
+      redBits = CHAN_BITS;
+      greenBits = CHAN_BITS;
+      blueBits = CHAN_BITS;
       alphaBits = 0;
       bshift = 0;
       gshift = 8;
@@ -229,13 +231,12 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
       gind = 1;
       bind = 2;
       rgbmode = GL_TRUE;
-      swalpha = GL_TRUE;
    }
    else if (format==OSMESA_BGR) {
       indexBits = 0;
-      redBits = 8;
-      greenBits = 8;
-      blueBits = 8;
+      redBits = CHAN_BITS;
+      greenBits = CHAN_BITS;
+      blueBits = CHAN_BITS;
       alphaBits = 0;
       bshift = 0;
       gshift = 8;
@@ -245,7 +246,21 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
       gind = 1;
       bind = 0;
       rgbmode = GL_TRUE;
-      swalpha = GL_TRUE;
+   }
+   else if (format==OSMESA_RGB_565) {
+      indexBits = 0;
+      redBits = 5;
+      greenBits = 6;
+      blueBits = 5;
+      alphaBits = 0;
+      rshift = 11;
+      gshift = 5;
+      bshift = 0;
+      ashift = 0;
+      rind = 0; /* not used */
+      gind = 0;
+      bind = 0;
+      rgbmode = GL_TRUE;
    }
    else {
       return NULL;
@@ -279,19 +294,22 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
                                     osmesa->gl_visual,
                                     sharelist ? &sharelist->gl_ctx
                                               : (GLcontext *) NULL,
-                                    (void *) osmesa, GL_TRUE )) {
+                                    (void *) osmesa,
+                                    GL_FALSE)) {
          _mesa_destroy_visual( osmesa->gl_visual );
          FREE(osmesa);
          return NULL;
       }
 
       _mesa_enable_sw_extensions(&(osmesa->gl_ctx));
+      _mesa_enable_1_3_extensions(&(osmesa->gl_ctx));
+      /*_mesa_enable_1_4_extensions(&(osmesa->gl_ctx));*/
 
       osmesa->gl_buffer = _mesa_create_framebuffer( osmesa->gl_visual,
-                                          osmesa->gl_visual->depthBits > 0,
-                                          osmesa->gl_visual->stencilBits > 0,
-                                          osmesa->gl_visual->accumRedBits > 0,
-                                          osmesa->gl_visual->alphaBits > 0 );
+                           (GLboolean) ( osmesa->gl_visual->depthBits > 0 ),
+                           (GLboolean) ( osmesa->gl_visual->stencilBits > 0 ),
+                           (GLboolean) ( osmesa->gl_visual->accumRedBits > 0 ),
+                           GL_FALSE /* s/w alpha */ );
 
       if (!osmesa->gl_buffer) {
          _mesa_destroy_visual( osmesa->gl_visual );
@@ -326,6 +344,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
         _tnl_CreateContext( ctx );
         _swsetup_CreateContext( ctx );
        
+        _swsetup_Wakeup( ctx );
         osmesa_register_swrast_functions( ctx );
       }
    }
@@ -340,9 +359,14 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
  *
  * Input:  ctx - the context to destroy
  */
-void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
+GLAPI void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
 {
    if (ctx) {
+      _swsetup_DestroyContext( &ctx->gl_ctx );
+      _tnl_DestroyContext( &ctx->gl_ctx );
+      _ac_DestroyContext( &ctx->gl_ctx );
+      _swrast_DestroyContext( &ctx->gl_ctx );
+
       _mesa_destroy_visual( ctx->gl_visual );
       _mesa_destroy_framebuffer( ctx->gl_buffer );
       _mesa_free_context_data( &ctx->gl_ctx );
@@ -368,6 +392,10 @@ static void compute_row_addresses( OSMesaContext ctx )
       /* RGB mode */
       bytesPerPixel = 3 * sizeof(GLchan);
    }
+   else if (ctx->format == OSMESA_RGB_565) {
+      /* 5/6/5 RGB pixel in 16 bits */
+      bytesPerPixel = 2;
+   }
    else {
       /* RGBA mode */
       bytesPerPixel = 4 * sizeof(GLchan);
@@ -401,33 +429,39 @@ static void compute_row_addresses( OSMesaContext ctx )
  * with the lower-left image pixel stored in the first array position
  * (ie. bottom-to-top).
  *
- * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
- * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
- * value.  If the context is in color indexed mode, each pixel will be
- * stored as a 1-byte value.
- *
  * If the context's viewport hasn't been initialized yet, it will now be
  * initialized to (0,0,width,height).
  *
  * Input:  ctx - the rendering context
  *         buffer - the image buffer memory
- *         type - data type for pixel components, only GL_UNSIGNED_BYTE
- *                supported now
+ *         type - data type for pixel components
+ *            Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
+ *            are supported.  But if Mesa's been compiled with CHAN_BITS==16
+ *            then type must be GL_UNSIGNED_SHORT.  And if Mesa's been build
+ *            with CHAN_BITS==32 then type must be GL_FLOAT.
  *         width, height - size of image buffer in pixels, at least 1
  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
- *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
+ *          invalid buffer address, invalid type, width<1, height<1,
  *          width>internal limit or height>internal limit.
  */
-GLboolean GLAPIENTRY
+GLAPI GLboolean GLAPIENTRY
 OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
                    GLsizei width, GLsizei height )
 {
-   if (!ctx || !buffer || type != CHAN_TYPE ||
+   if (!ctx || !buffer ||
        width < 1 || height < 1 ||
        width > MAX_WIDTH || height > MAX_HEIGHT) {
       return GL_FALSE;
    }
 
+   if (ctx->format == OSMESA_RGB_565) {
+      if (type != GL_UNSIGNED_SHORT_5_6_5)
+         return GL_FALSE;
+   }
+   else if (type != CHAN_TYPE) {
+      return GL_FALSE;
+   }
+
    osmesa_update_state( &ctx->gl_ctx, 0 );
    _mesa_make_current( &ctx->gl_ctx, ctx->gl_buffer );
 
@@ -442,19 +476,27 @@ OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
    compute_row_addresses( ctx );
 
    /* init viewport */
-   if (ctx->gl_ctx.Viewport.Width==0) {
+   if (ctx->gl_ctx.Viewport.Width == 0) {
       /* initialize viewport and scissor box to buffer size */
       _mesa_Viewport( 0, 0, width, height );
       ctx->gl_ctx.Scissor.Width = width;
       ctx->gl_ctx.Scissor.Height = height;
    }
+   else {
+      /* this will make ensure we recognize the new buffer size */
+      _mesa_ResizeBuffersMESA();
+   }
+
+   /* Added by Gerk Huisma: */
+   _tnl_MakeCurrent( &ctx->gl_ctx, ctx->gl_ctx.DrawBuffer,
+                     ctx->gl_ctx.ReadBuffer );
 
    return GL_TRUE;
 }
 
 
 
-OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
+GLAPI OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
 {
    GLcontext *ctx = _mesa_get_current_context();
    if (ctx)
@@ -465,14 +507,14 @@ OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
 
 
 
-void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
+GLAPI void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
 {
    OSMesaContext ctx = OSMesaGetCurrentContext();
 
    switch (pname) {
       case OSMESA_ROW_LENGTH:
          if (value<0) {
-            gl_error( &ctx->gl_ctx, GL_INVALID_VALUE,
+            _mesa_error( &ctx->gl_ctx, GL_INVALID_VALUE,
                       "OSMesaPixelStore(value)" );
             return;
          }
@@ -483,7 +525,7 @@ void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
          ctx->yup = value ? GL_TRUE : GL_FALSE;
          break;
       default:
-         gl_error( &ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
+         _mesa_error( &ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
          return;
    }
 
@@ -491,7 +533,7 @@ void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
 }
 
 
-void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
+GLAPI void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
 {
    OSMesaContext ctx = OSMesaGetCurrentContext();
 
@@ -506,7 +548,7 @@ void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
          *value = ctx->format;
          return;
       case OSMESA_TYPE:
-         *value = GL_UNSIGNED_BYTE;
+         *value = CHAN_TYPE;
          return;
       case OSMESA_ROW_LENGTH:
          *value = ctx->rowlength;
@@ -514,8 +556,14 @@ void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
       case OSMESA_Y_UP:
          *value = ctx->yup;
          return;
+      case OSMESA_MAX_WIDTH:
+         *value = MAX_WIDTH;
+         return;
+      case OSMESA_MAX_HEIGHT:
+         *value = MAX_HEIGHT;
+         return;
       default:
-         gl_error(&ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
+         _mesa_error(&ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
          return;
    }
 }
@@ -528,7 +576,7 @@ void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
  *          buffer - pointer to depth buffer values
  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  */
-GLboolean GLAPIENTRY
+GLAPI GLboolean GLAPIENTRY
 OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
                       GLint *bytesPerValue, void **buffer )
 {
@@ -559,7 +607,7 @@ OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
  *          buffer - pointer to color buffer values
  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  */
-GLboolean GLAPIENTRY
+GLAPI GLboolean GLAPIENTRY
 OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
                       GLint *height, GLint *format, void **buffer )
 {
@@ -579,6 +627,39 @@ OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
    }
 }
 
+
+
+struct name_address {
+   const char *Name;
+   GLvoid *Address;
+};
+
+static struct name_address functions[] = {
+   { "OSMesaCreateContext", (void *) OSMesaCreateContext },
+   { "OSMesaCreateContextExt", (void *) OSMesaCreateContextExt },
+   { "OSMesaDestroyContext", (void *) OSMesaDestroyContext },
+   { "OSMesaMakeCurrent", (void *) OSMesaMakeCurrent },
+   { "OSMesaGetCurrentContext", (void *) OSMesaGetCurrentContext },
+   { "OSMesaPixelsStore", (void *) OSMesaPixelStore },
+   { "OSMesaGetIntegerv", (void *) OSMesaGetIntegerv },
+   { "OSMesaGetDepthBuffer", (void *) OSMesaGetDepthBuffer },
+   { "OSMesaGetColorBuffer", (void *) OSMesaGetColorBuffer },
+   { "OSMesaGetProcAddress", (void *) OSMesaGetProcAddress },
+   { NULL, NULL }
+};
+
+GLAPI void * GLAPIENTRY
+OSMesaGetProcAddress( const char *funcName )
+{
+   int i;
+   for (i = 0; functions[i].Name; i++) {
+      if (strcmp(functions[i].Name, funcName) == 0)
+         return (void *) functions[i].Address;
+   }
+   return (void *) _glapi_get_proc_address(funcName);
+}
+
+
 /**********************************************************************/
 /*** Device Driver Functions                                        ***/
 /**********************************************************************/
@@ -588,6 +669,15 @@ OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
  * Useful macros:
  */
 
+#if CHAN_TYPE == GL_FLOAT
+#define PACK_RGBA(DST, R, G, B, A)     \
+do {                                   \
+   (DST)[0] = MAX2( R, 0.0F );         \
+   (DST)[1] = MAX2( G, 0.0F );         \
+   (DST)[2] = MAX2( B, 0.0F );         \
+   (DST)[3] = CLAMP(A, 0.0F, CHAN_MAXF);\
+} while (0)
+#else
 #define PACK_RGBA(DST, R, G, B, A)     \
 do {                                   \
    (DST)[osmesa->rInd] = R;            \
@@ -595,6 +685,7 @@ do {                                        \
    (DST)[osmesa->bInd] = B;            \
    (DST)[osmesa->aInd] = A;            \
 } while (0)
+#endif
 
 #define PACK_RGB(DST, R, G, B)  \
 do {                           \
@@ -610,36 +701,30 @@ do {                              \
    (DST)[2] = R;               \
 } while (0)
 
+#define PACK_RGB_565(DST, R, G, B)                                     \
+do {                                                                   \
+   (DST) = (((int) (R) << 8) & 0xf800) | (((int) (G) << 3) & 0x7e0) | ((int) (B) >> 3);\
+} while (0)
+
 
-#define UNPACK_RED(P)      ( ((GLchan *) &(P))[osmesa->rInd] )
-#define UNPACK_GREEN(P)    ( ((GLchan *) &(P))[osmesa->gInd] )
-#define UNPACK_BLUE(P)     ( ((GLchan *) &(P))[osmesa->bInd] )
-#define UNPACK_ALPHA(P)    ( ((GLchan *) &(P))[osmesa->aInd] )
+#define UNPACK_RED(P)      ( (P)[osmesa->rInd] )
+#define UNPACK_GREEN(P)    ( (P)[osmesa->gInd] )
+#define UNPACK_BLUE(P)     ( (P)[osmesa->bInd] )
+#define UNPACK_ALPHA(P)    ( (P)[osmesa->aInd] )
 
 
 #define PIXELADDR1(X,Y)  (osmesa->rowaddr[Y] + (X))
+#define PIXELADDR2(X,Y)  (osmesa->rowaddr[Y] + 2 * (X))
 #define PIXELADDR3(X,Y)  (osmesa->rowaddr[Y] + 3 * (X))
 #define PIXELADDR4(X,Y)  (osmesa->rowaddr[Y] + 4 * (X))
 
 
 
-static GLboolean set_draw_buffer( GLcontext *ctx, GLenum mode )
-{
-   (void) ctx;
-   if (mode==GL_FRONT_LEFT) {
-      return GL_TRUE;
-   }
-   else {
-      return GL_FALSE;
-   }
-}
-
-
-static void set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
+static void set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
 {
    /* separate read buffer not supported */
    ASSERT(buffer == ctx->DrawBuffer);
-   ASSERT(mode == GL_FRONT_LEFT);
+   ASSERT(bufferBit == FRONT_LEFT_BIT);
 }
 
 
@@ -681,9 +766,10 @@ static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
            }
         }
         else if (osmesa->format == OSMESA_RGB) {
-           const GLchan r = ctx->Color.ClearColor[0];
-           const GLchan g = ctx->Color.ClearColor[1];
-           const GLchan b = ctx->Color.ClearColor[2];
+            GLchan r, g, b;
+            CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
+            CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
+            CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
            if (all) {
               /* Clear whole RGB buffer */
               GLuint n = osmesa->rowlength * osmesa->height;
@@ -707,9 +793,10 @@ static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
            }
         }
         else if (osmesa->format == OSMESA_BGR) {
-           const GLchan r = ctx->Color.ClearColor[0];
-           const GLchan g = ctx->Color.ClearColor[1];
-           const GLchan b = ctx->Color.ClearColor[2];
+            GLchan r, g, b;
+            CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
+            CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
+            CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
            if (all) {
               /* Clear whole RGB buffer */
               const GLint n = osmesa->rowlength * osmesa->height;
@@ -732,15 +819,44 @@ static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
               }
            }
         }
+         else if (osmesa->format == OSMESA_RGB_565) {
+            GLushort clearPixel;
+            GLchan r, g, b;
+            CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
+            CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
+            CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
+            PACK_RGB_565(clearPixel, r, g, b);
+            if (all) {
+               /* Clear whole RGB buffer */
+              const GLuint n = osmesa->rowlength * osmesa->height;
+               GLushort *ptr2 = (GLushort *) osmesa->buffer;
+               GLuint  i;
+               for (i = 0; i < n; i++) {
+                  *ptr2 = clearPixel;
+                  ptr2++;
+               }
+            }
+            else {
+               /* clear scissored region */
+               GLint i, j;
+               for (i = 0; i < height; i++) {
+                  GLushort *ptr2 = (GLushort *) PIXELADDR2(x, (y + i));
+                  for (j = 0; j < width; j++) {
+                     *ptr2 = clearPixel;
+                     ptr2++;
+                  }
+               }
+            }
+         }
         else {
 #if CHAN_TYPE == GL_UNSIGNED_BYTE
            /* 4-byte pixel value */
            GLuint clearPixel;
            GLchan *clr = (GLchan *) &clearPixel;
-           clr[osmesa->rInd] = ctx->Color.ClearColor[0];
-           clr[osmesa->gInd] = ctx->Color.ClearColor[1];
-           clr[osmesa->bInd] = ctx->Color.ClearColor[2];
-           clr[osmesa->aInd] = ctx->Color.ClearColor[3];
+            CLAMPED_FLOAT_TO_CHAN(clr[osmesa->rInd], ctx->Color.ClearColor[0]);
+            CLAMPED_FLOAT_TO_CHAN(clr[osmesa->gInd], ctx->Color.ClearColor[1]);
+            CLAMPED_FLOAT_TO_CHAN(clr[osmesa->bInd], ctx->Color.ClearColor[2]);
+            CLAMPED_FLOAT_TO_CHAN(clr[osmesa->aInd], ctx->Color.ClearColor[3]);
            if (all) {
               /* Clear whole RGBA buffer */
               const GLuint n = osmesa->rowlength * osmesa->height;
@@ -766,10 +882,11 @@ static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
               }
            }
 #else
-           const GLchan r = ctx->Color.ClearColor[0];
-           const GLchan g = ctx->Color.ClearColor[1];
-           const GLchan b = ctx->Color.ClearColor[2];
-           const GLchan a = ctx->Color.ClearColor[3];
+            GLchan r, g, b, a;
+            CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
+            CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
+            CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
+            CLAMPED_FLOAT_TO_CHAN(a, ctx->Color.ClearColor[3]);
            if (all) {
               /* Clear whole RGBA buffer */
               const GLuint n = osmesa->rowlength * osmesa->height;
@@ -804,11 +921,16 @@ static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
 
 
 
-static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
+static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
 {
-   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
-   *width = osmesa->width;
-   *height = osmesa->height;
+   /* don't use GET_CURRENT_CONTEXT(ctx) here - it's a problem on Windows */
+   GLcontext *ctx = (GLcontext *) _glapi_get_context();
+   (void) buffer;
+   if (ctx) {
+      OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+      *width = osmesa->width;
+      *height = osmesa->height;
+   }
 }
 
 
@@ -875,13 +997,13 @@ write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
    if (mask) {
       for (i = 0; i < n; i++, p+=4) {
          if (mask[i]) {
-            PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
+            PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
          }
       }
    }
    else {
       for (i = 0; i < n; i++, p+=4) {
-         PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
+         PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
       }
    }
 }
@@ -1175,7 +1297,7 @@ read_rgba_span3( const GLcontext *ctx, GLuint n, GLint x, GLint y,
       rgba[i][RCOMP] = UNPACK_RED(p);
       rgba[i][GCOMP] = UNPACK_GREEN(p);
       rgba[i][BCOMP] = UNPACK_BLUE(p);
-      rgba[i][ACOMP] = 255;
+      rgba[i][ACOMP] = CHAN_MAX;
    }
 }
 
@@ -1192,12 +1314,151 @@ read_rgba_pixels3( const GLcontext *ctx,
          rgba[i][RCOMP] = UNPACK_RED(p);
          rgba[i][GCOMP] = UNPACK_GREEN(p);
          rgba[i][BCOMP] = UNPACK_BLUE(p);
-         rgba[i][ACOMP] = 255;
+         rgba[i][ACOMP] = CHAN_MAX;
+      }
+   }
+}
+
+
+/**********************************************************************/
+/*****                2 byte RGB pixel support funcs              *****/
+/**********************************************************************/
+
+/* Write RGBA pixels to an RGB_565 buffer. */
+static void
+write_rgba_span2( const GLcontext *ctx,
+                  GLuint n, GLint x, GLint y,
+                  CONST GLchan rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
+   GLuint i;
+   if (mask) {
+      for (i = 0; i < n; i++, ptr2++) {
+         if (mask[i]) {
+            PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+         }
+      }
+   }
+   else {
+      for (i = 0; i < n; i++, ptr2++) {
+         PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
       }
    }
 }
 
 
+/* Write RGB pixels to an RGB_565 buffer. */
+static void
+write_rgb_span2( const GLcontext *ctx,
+                 GLuint n, GLint x, GLint y,
+                 CONST GLchan rgb[][3], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
+   GLuint i;
+   if (mask) {
+      for (i = 0; i < n; i++, ptr2++) {
+         if (mask[i]) {
+            PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
+         }
+      }
+   }
+   else {
+      for (i = 0; i < n; i++, ptr2++) {
+         PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
+      }
+   }
+}
+
+
+static void
+write_monocolor_span2( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                       const GLchan color[4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLushort pixel;
+   GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
+   GLuint i;
+   PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
+   for (i = 0; i < n; i++, ptr2++) {
+      if (mask[i]) {
+         *ptr2 = pixel;
+      }
+   }
+}
+
+
+static void
+write_rgba_pixels2( const GLcontext *ctx,
+                    GLuint n, const GLint x[], const GLint y[],
+                    CONST GLchan rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLuint i;
+   for (i = 0; i < n; i++) {
+      if (mask[i]) {
+         GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
+         PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+      }
+   }
+}
+
+static void
+write_monocolor_pixels2( const GLcontext *ctx,
+                         GLuint n, const GLint x[], const GLint y[],
+                         const GLchan color[4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLuint i;
+   GLushort pixel;
+   PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
+   for (i = 0; i < n; i++) {
+      if (mask[i]) {
+         GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
+         *ptr2 = pixel;
+      }
+   }
+}
+
+static void
+read_rgba_span2( const GLcontext *ctx,
+                 GLuint n, GLint x, GLint y,
+                 GLchan rgba[][4] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLuint i;
+   const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x, y);
+   for (i = 0; i < n; i++, ptr2++) {
+      /* This should be fixed to get the low bits right */
+      rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFe;
+      rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFc;
+      rgba[i][BCOMP] = (*ptr2 << 3) & 0xFe;
+      rgba[i][ACOMP] = 0;
+   }
+}
+
+static void
+read_rgba_pixels2( const GLcontext *ctx,
+                   GLuint n, const GLint x[], const GLint y[],
+                   GLchan rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   GLuint i;
+   for (i = 0; i < n; i++) {
+      if (mask[i]) {
+         /* This should be fixed to get the low bits right */
+         const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x[i],y[i]);
+         rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFE;
+         rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFC;
+         rgba[i][BCOMP] = (*ptr2 << 3) & 0xFE;
+         rgba[i][ACOMP] = 0;
+      }
+   }
+}
+
+
+
 /**********************************************************************/
 /*****        Read/write spans/arrays of CI pixels                *****/
 /**********************************************************************/
@@ -1335,7 +1596,7 @@ static void
 flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
 {
    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
-   const GLchan *color = vert0->color;
+   const GLchan *color = vert1->color;
 
 #define INTERP_XY 1
 #define CLIP_HACK 1
@@ -1360,7 +1621,7 @@ static void
 flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
 {
    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
-   const GLchan *color = vert0->color;
+   const GLchan *color = vert1->color;
 
 #define INTERP_XY 1
 #define INTERP_Z 1
@@ -1398,15 +1659,15 @@ flat_blend_rgba_line( GLcontext *ctx,
    const GLint gshift = osmesa->gshift;
    const GLint bshift = osmesa->bshift;
    const GLint avalue = vert0->color[3];
-   const GLint msavalue = 255 - avalue;
-   const GLint rvalue = vert0->color[0]*avalue;
-   const GLint gvalue = vert0->color[1]*avalue;
-   const GLint bvalue = vert0->color[2]*avalue;
+   const GLint msavalue = CHAN_MAX - avalue;
+   const GLint rvalue = vert1->color[0]*avalue;
+   const GLint gvalue = vert1->color[1]*avalue;
+   const GLint bvalue = vert1->color[2]*avalue;
 
 #define INTERP_XY 1
 #define CLIP_HACK 1
 #define PLOT(X,Y)                                      \
-   { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);               \
+   { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);       \
      GLuint  pixel = 0;                                        \
      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
@@ -1414,6 +1675,17 @@ flat_blend_rgba_line( GLcontext *ctx,
      *ptr4 = pixel;                                    \
    }
 
+#if 0  /* XXX use this in the future */
+#define PLOT(X,Y)                                                      \
+   {                                                                   \
+      GLchan *pixel = (GLchan *) PIXELADDR4(X, Y);                     \
+      pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS;    \
+      pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS;    \
+      pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS;    \
+      pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS;    \
+   }
+#endif
+
 #ifdef WIN32
 #include "..\swrast\s_linetemp.h"
 #else
@@ -1424,6 +1696,7 @@ flat_blend_rgba_line( GLcontext *ctx,
 
 /*
  * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
+ * But don't write to Z buffer.
  * XXX update for GLchan
  */
 static void
@@ -1436,9 +1709,9 @@ flat_blend_rgba_z_line( GLcontext *ctx,
    const GLint bshift = osmesa->bshift;
    const GLint avalue = vert0->color[3];
    const GLint msavalue = 256 - avalue;
-   const GLint rvalue = vert0->color[0]*avalue;
-   const GLint gvalue = vert0->color[1]*avalue;
-   const GLint bvalue = vert0->color[2]*avalue;
+   const GLint rvalue = vert1->color[0]*avalue;
+   const GLint gvalue = vert1->color[1]*avalue;
+   const GLint bvalue = vert1->color[2]*avalue;
 
 #define INTERP_XY 1
 #define INTERP_Z 1
@@ -1454,6 +1727,17 @@ flat_blend_rgba_z_line( GLcontext *ctx,
           *ptr4 = pixel;                                               \
        }
 
+#if 0  /* XXX use this in the future */
+#define PLOT(X,Y)                                                      \
+   if (Z < *zPtr) {                                                    \
+      GLchan *pixel = (GLchan *) PIXELADDR4(X, Y);                     \
+      pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS;    \
+      pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS;    \
+      pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS;    \
+      pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS;    \
+   }
+#endif
+
 #ifdef WIN32
 #include "..\swrast\s_linetemp.h"
 #else
@@ -1476,9 +1760,9 @@ flat_blend_rgba_z_line_write( GLcontext *ctx,
    const GLint bshift = osmesa->bshift;
    const GLint avalue = vert0->color[3];
    const GLint msavalue = 256 - avalue;
-   const GLint rvalue = vert0->color[0]*avalue;
-   const GLint gvalue = vert0->color[1]*avalue;
-   const GLint bvalue = vert0->color[2]*avalue;
+   const GLint rvalue = vert1->color[0]*avalue;
+   const GLint gvalue = vert1->color[1]*avalue;
+   const GLint bvalue = vert1->color[2]*avalue;
 
 #define INTERP_XY 1
 #define INTERP_Z 1
@@ -1495,6 +1779,18 @@ flat_blend_rgba_z_line_write( GLcontext *ctx,
           *zPtr = Z;                                                   \
        }
 
+#if 0  /* XXX use this in the future */
+#define PLOT(X,Y)                                                      \
+   if (Z < *zPtr) {                                                    \
+      GLchan *pixel = (GLchan *) PIXELADDR4(X, Y);                     \
+      pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS;    \
+      pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS;    \
+      pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS;    \
+      pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS;    \
+      *zPtr = Z;                                                       \
+   }
+#endif
+
 #ifdef WIN32
 #include "..\swrast\s_linetemp.h"
 #else
@@ -1516,7 +1812,7 @@ osmesa_choose_line_function( GLcontext *ctx )
    if (CHAN_BITS != 8)                    return NULL;
    if (ctx->RenderMode != GL_RENDER)      return NULL;
    if (ctx->Line.SmoothFlag)              return NULL;
-   if (ctx->Texture._ReallyEnabled)       return NULL;
+   if (ctx->Texture._EnabledUnits)        return NULL;
    if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
    if (ctx->Line.Width != 1.0F)           return NULL;
    if (ctx->Line.StippleFlag)             return NULL;
@@ -1529,11 +1825,11 @@ osmesa_choose_line_function( GLcontext *ctx )
        && ctx->Depth.Func==GL_LESS
        && ctx->Depth.Mask==GL_TRUE
        && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
-      return flat_rgba_z_line;
+      return (swrast_line_func) flat_rgba_z_line;
    }
 
    if (swrast->_RasterMask == 0) {
-      return flat_rgba_line;
+      return (swrast_line_func) flat_rgba_line;
    }
 
    if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
@@ -1545,7 +1841,7 @@ osmesa_choose_line_function( GLcontext *ctx )
        && ctx->Color.BlendSrcA==GL_SRC_ALPHA
        && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
        && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
-      return flat_blend_rgba_z_line_write;
+      return (swrast_line_func) flat_blend_rgba_z_line_write;
    }
 
    if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
@@ -1557,7 +1853,7 @@ osmesa_choose_line_function( GLcontext *ctx )
        && ctx->Color.BlendSrcA==GL_SRC_ALPHA
        && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
        && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
-      return flat_blend_rgba_z_line;
+      return (swrast_line_func) flat_blend_rgba_z_line;
    }
 
    if (swrast->_RasterMask==BLEND_BIT
@@ -1566,10 +1862,10 @@ osmesa_choose_line_function( GLcontext *ctx )
        && ctx->Color.BlendSrcA==GL_SRC_ALPHA
        && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
        && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
-      return flat_blend_rgba_line;
+      return (swrast_line_func) flat_blend_rgba_line;
    }
 
-   return NULL;
+   return (swrast_line_func) NULL;
 }
 
 
@@ -1587,27 +1883,28 @@ static void smooth_rgba_z_triangle( GLcontext *ctx,
                                     const SWvertex *v2 )
 {
    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
-
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
-#define INNER_LOOP( LEFT, RIGHT, Y )                           \
-{                                                              \
-   GLint i, len = RIGHT-LEFT;                                  \
-   GLchan *img = PIXELADDR4(LEFT, Y);                          \
-   (void) fffog;                                               \
-   for (i = 0; i < len; i++, img += 4) {                       \
-      GLdepth z = FixedToDepth(ffz);                           \
+#define RENDER_SPAN( span )                                    \
+   GLuint i;                                                   \
+   GLchan *img = PIXELADDR4(span.x, span.y);                   \
+   for (i = 0; i < span.end; i++, img += 4) {                  \
+      const GLdepth z = FixedToDepth(span.z);                  \
       if (z < zRow[i]) {                                       \
-         PACK_RGBA(img, FixedToInt(ffr), FixedToInt(ffg),      \
-                       FixedToInt(ffb), FixedToInt(ffa));      \
+         PACK_RGBA(img, FixedToChan(span.red),                 \
+            FixedToChan(span.green), FixedToChan(span.blue),   \
+            FixedToChan(span.alpha));                          \
          zRow[i] = z;                                          \
       }                                                                \
-      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
-      ffz += fdzdx;                                            \
-   }                                                           \
-}
+      span.red += span.redStep;                                        \
+      span.green += span.greenStep;                            \
+      span.blue += span.blueStep;                              \
+      span.alpha += span.alphaStep;                            \
+      span.z += span.zStep;                                    \
+   }
+
 #ifdef WIN32
 #include "..\swrast\s_tritemp.h"
 #else
@@ -1631,23 +1928,21 @@ static void flat_rgba_z_triangle( GLcontext *ctx,
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define SETUP_CODE                                             \
    GLuint pixel;                                               \
-   PACK_RGBA((GLchan *) &pixel, v0->color[0], v0->color[1],    \
-                                v0->color[2], v0->color[3]);
-
-#define INNER_LOOP( LEFT, RIGHT, Y )                   \
-{                                                      \
-   GLint i, len = RIGHT-LEFT;                          \
-   GLuint *img = (GLuint *) PIXELADDR4(LEFT, Y);       \
-   (void) fffog;                                       \
-   for (i=0;i<len;i++) {                               \
-      GLdepth z = FixedToDepth(ffz);                   \
+   PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1],    \
+                                v2->color[2], v2->color[3]);
+
+#define RENDER_SPAN( span )                            \
+   GLuint i;                                           \
+   GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y);        \
+   for (i = 0; i < span.end; i++) {                    \
+      const GLdepth z = FixedToDepth(span.z);          \
       if (z < zRow[i]) {                               \
          img[i] = pixel;                               \
          zRow[i] = z;                                  \
       }                                                        \
-      ffz += fdzdx;                                    \
-   }                                                   \
-}
+      span.z += span.zStep;                            \
+   }
+
 #ifdef WIN32
 #include "..\swrast\s_tritemp.h"
 #else
@@ -1670,20 +1965,23 @@ osmesa_choose_triangle_function( GLcontext *ctx )
    if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
    if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
    if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
-   if (ctx->Texture._ReallyEnabled)     return (swrast_tri_func) NULL;
+   if (ctx->Texture._EnabledUnits)      return (swrast_tri_func) NULL;
    if (osmesa->format != OSMESA_RGBA &&
        osmesa->format != OSMESA_BGRA &&
        osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
+   if (ctx->Polygon.CullFlag && 
+       ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
+                                        return (swrast_tri_func) NULL;
 
    if (swrast->_RasterMask == DEPTH_BIT &&
        ctx->Depth.Func == GL_LESS &&
        ctx->Depth.Mask == GL_TRUE &&
        ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         return smooth_rgba_z_triangle;
+         return (swrast_tri_func) smooth_rgba_z_triangle;
       }
       else {
-         return flat_rgba_z_triangle;
+         return (swrast_tri_func) flat_rgba_z_triangle;
       }
    }
    return (swrast_tri_func) NULL;
@@ -1749,7 +2047,13 @@ static const GLubyte *get_string( GLcontext *ctx, GLenum name )
    (void) ctx;
    switch (name) {
       case GL_RENDERER:
+#if CHAN_BITS == 32
+         return (const GLubyte *) "Mesa OffScreen32";
+#elif CHAN_BITS == 16
+         return (const GLubyte *) "Mesa OffScreen16";
+#else
          return (const GLubyte *) "Mesa OffScreen";
+#endif
       default:
          return NULL;
    }
@@ -1759,6 +2063,8 @@ static const GLubyte *get_string( GLcontext *ctx, GLenum name )
 static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
 {
    OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
    ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
 
@@ -1769,32 +2075,18 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
 
    ctx->Driver.GetString = get_string;
    ctx->Driver.UpdateState = osmesa_update_state;
-   ctx->Driver.SetDrawBuffer = set_draw_buffer;
-   ctx->Driver.SetReadBuffer = set_read_buffer;
-   ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
+   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
    ctx->Driver.GetBufferSize = buffer_size;
 
-   ctx->Driver.RenderStart = _swsetup_RenderStart;
-   ctx->Driver.RenderFinish = _swsetup_RenderFinish;
-   ctx->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
-   ctx->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
-   ctx->Driver.PointsFunc = _swsetup_Points;
-   ctx->Driver.LineFunc = _swsetup_Line;
-   ctx->Driver.TriangleFunc = _swsetup_Triangle;
-   ctx->Driver.QuadFunc = _swsetup_Quad;
-   ctx->Driver.ResetLineStipple = _swrast_ResetLineStipple;
-   ctx->Driver.RenderInterp = _swsetup_RenderInterp;
-   ctx->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
-   ctx->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
-   ctx->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
-
    ctx->Driver.Accum = _swrast_Accum;
    ctx->Driver.Bitmap = _swrast_Bitmap;
    ctx->Driver.Clear = clear;
    ctx->Driver.CopyPixels = _swrast_CopyPixels;
    ctx->Driver.DrawPixels = _swrast_DrawPixels;
    ctx->Driver.ReadPixels = _swrast_ReadPixels;
+   ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
 
+   ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
    ctx->Driver.TexImage1D = _mesa_store_teximage1d;
    ctx->Driver.TexImage2D = _mesa_store_teximage2d;
    ctx->Driver.TexImage3D = _mesa_store_teximage3d;
@@ -1803,54 +2095,83 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
    ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
    ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
 
+   ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+   ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+   ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+   ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+   ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+   ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+
+   ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+   ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+   ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+   ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+   ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+
+   swdd->SetBuffer = set_buffer;
 
    /* RGB(A) span/pixel functions */
    if (osmesa->format == OSMESA_RGB) {
-      ctx->Driver.WriteRGBASpan = write_rgba_span_RGB;
-      ctx->Driver.WriteRGBSpan = write_rgb_span_RGB;
-      ctx->Driver.WriteMonoRGBASpan = write_monocolor_span_RGB;
-      ctx->Driver.WriteRGBAPixels = write_rgba_pixels_RGB;
-      ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels_RGB;
-      ctx->Driver.ReadRGBASpan = read_rgba_span3;
-      ctx->Driver.ReadRGBAPixels = read_rgba_pixels3;
+      swdd->WriteRGBASpan = write_rgba_span_RGB;
+      swdd->WriteRGBSpan = write_rgb_span_RGB;
+      swdd->WriteMonoRGBASpan = write_monocolor_span_RGB;
+      swdd->WriteRGBAPixels = write_rgba_pixels_RGB;
+      swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB;
+      swdd->ReadRGBASpan = read_rgba_span3;
+      swdd->ReadRGBAPixels = read_rgba_pixels3;
    }
    else if (osmesa->format == OSMESA_BGR) {
-      ctx->Driver.WriteRGBASpan = write_rgba_span_BGR;
-      ctx->Driver.WriteRGBSpan = write_rgb_span_BGR;
-      ctx->Driver.WriteMonoRGBASpan = write_monocolor_span_BGR;
-      ctx->Driver.WriteRGBAPixels = write_rgba_pixels_BGR;
-      ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels_BGR;
-      ctx->Driver.ReadRGBASpan = read_rgba_span3;
-      ctx->Driver.ReadRGBAPixels = read_rgba_pixels3;
+      swdd->WriteRGBASpan = write_rgba_span_BGR;
+      swdd->WriteRGBSpan = write_rgb_span_BGR;
+      swdd->WriteMonoRGBASpan = write_monocolor_span_BGR;
+      swdd->WriteRGBAPixels = write_rgba_pixels_BGR;
+      swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR;
+      swdd->ReadRGBASpan = read_rgba_span3;
+      swdd->ReadRGBAPixels = read_rgba_pixels3;
+   }
+   else if (osmesa->format == OSMESA_RGB_565) {
+      swdd->WriteRGBASpan = write_rgba_span2;
+      swdd->WriteRGBSpan = write_rgb_span2;
+      swdd->WriteMonoRGBASpan = write_monocolor_span2;
+      swdd->WriteRGBAPixels = write_rgba_pixels2;
+      swdd->WriteMonoRGBAPixels = write_monocolor_pixels2;
+      swdd->ReadRGBASpan = read_rgba_span2;
+      swdd->ReadRGBAPixels = read_rgba_pixels2;
    }
    else {
-      /* 4 bytes / pixel in frame buffer */
-      ctx->Driver.WriteRGBSpan = write_rgb_span;
-      ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
-      ctx->Driver.WriteMonoRGBASpan = write_monocolor_span;
-      ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels;
+      /* 4 GLchan / pixel in frame buffer */
+      swdd->WriteRGBSpan = write_rgb_span;
+      swdd->WriteRGBAPixels = write_rgba_pixels;
+      swdd->WriteMonoRGBASpan = write_monocolor_span;
+      swdd->WriteMonoRGBAPixels = write_monocolor_pixels;
       if (osmesa->format == OSMESA_RGBA &&
           CHAN_TYPE == GL_UNSIGNED_BYTE &&
           RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) {
          /* special, fast case */
-         ctx->Driver.WriteRGBASpan = write_rgba_span_rgba;
-         ctx->Driver.ReadRGBASpan = read_rgba_span_rgba;
+         swdd->WriteRGBASpan = write_rgba_span_rgba;
+         swdd->ReadRGBASpan = read_rgba_span_rgba;
       }
       else {
-         ctx->Driver.WriteRGBASpan = write_rgba_span;
-         ctx->Driver.ReadRGBASpan = read_rgba_span;
+         swdd->WriteRGBASpan = write_rgba_span;
+         swdd->ReadRGBASpan = read_rgba_span;
       }
-      ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
+      swdd->ReadRGBAPixels = read_rgba_pixels;
    }
 
    /* CI span/pixel functions */
-   ctx->Driver.WriteCI32Span = write_index32_span;
-   ctx->Driver.WriteCI8Span = write_index8_span;
-   ctx->Driver.WriteMonoCISpan = write_monoindex_span;
-   ctx->Driver.WriteCI32Pixels = write_index_pixels;
-   ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels;
-   ctx->Driver.ReadCI32Span = read_index_span;
-   ctx->Driver.ReadCI32Pixels = read_index_pixels;
+   swdd->WriteCI32Span = write_index32_span;
+   swdd->WriteCI8Span = write_index8_span;
+   swdd->WriteMonoCISpan = write_monoindex_span;
+   swdd->WriteCI32Pixels = write_index_pixels;
+   swdd->WriteMonoCIPixels = write_monoindex_pixels;
+   swdd->ReadCI32Span = read_index_span;
+   swdd->ReadCI32Pixels = read_index_pixels;
+
+   tnl->Driver.RunPipeline = _tnl_run_pipeline;
 
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );