merge unichrome changes from branch
[mesa.git] / src / mesa / drivers / dri / unichrome / via_context.c
index 80b573e0e51c89bbfcda87f20d8146c39e3c7cac..b4385eb50fdc200ced89b598d38811c00bf02ffd 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
+/**
+ * \file via_context.c
+ * 
+ * \author John Sheng (presumably of either VIA Technologies or S3 Graphics)
+ * \author Others at VIA Technologies?
+ * \author Others at S3 Graphics?
+ */
+
 #include "glheader.h"
 #include "context.h"
 #include "matrix.h"
+#include "state.h"
 #include "simple_list.h"
 #include "extensions.h"
 
 #include "via_tex.h"
 #include "via_span.h"
 #include "via_tris.h"
-#include "via_vb.h"
 #include "via_ioctl.h"
 #include "via_fb.h"
 
-#ifndef _SOLO
-#include <X11/Xlibint.h>
-#endif
 #include <stdio.h>
 #include "macros.h"
 
-viaContextPtr current_mesa;
+#define DRIVER_DATE    "20041215"
+
+#include "vblank.h"
+#include "utils.h"
+
 GLuint VIA_DEBUG = 0;
-GLuint DRAW_FRONT = 0;
-#define DMA_SIZE 2
-GLuint VIA_PERFORMANCE = 0;
-#ifdef PERFORMANCE_MEASURE
-GLuint busy = 0;
-GLuint idle = 0;
-hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
-#endif
-/*=* John Sheng [2003.5.31]  agp tex *=*/
-extern GLuint agpFullCount;
 
-static GLboolean
-AllocateBuffer(viaContextPtr vmesa)
+/**
+ * Return various strings for \c glGetString.
+ *
+ * \sa glGetString
+ */
+static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
 {
-    vmesa->front_base = vmesa->driScreen->pFB;
-    if (vmesa->drawType == GLX_PBUFFER_BIT) {
-        if (vmesa->front.map)
-            via_free_front_buffer(vmesa);
-        if (!via_alloc_front_buffer(vmesa))
-            return GL_FALSE;
-    }
-    
-    if (vmesa->hasBack) {
-        if (vmesa->back.map)
-            via_free_back_buffer(vmesa);
-        if (!via_alloc_back_buffer(vmesa))
-            return GL_FALSE;
-    }
+   static char buffer[128];
+   unsigned   offset;
+
+
+   switch (name) {
+   case GL_VENDOR:
+      return (GLubyte *)"VIA Technology";
+
+   case GL_RENDERER: {
+      static const char * const chipset_names[] = {
+        "UniChrome",
+        "CastleRock (CLE266)",
+        "UniChrome (KM400)",
+        "UniChrome (K8M800)",
+        "UniChrome (PM8x0/CN400)",
+      };
+      struct via_context *vmesa = VIA_CONTEXT(ctx);
+      unsigned id = vmesa->viaScreen->deviceID;
+
+      offset = driGetRendererString( buffer, 
+                                    chipset_names[(id > VIA_PM800) ? 0 : id],
+                                    DRIVER_DATE, 0 );
+      return (GLubyte *)buffer;
+   }
+
+   default:
+      return NULL;
+   }
+}
 
-    if (vmesa->hasDepth || vmesa->hasStencil) {
-        if (vmesa->depth.map)
-            via_free_depth_buffer(vmesa);
-        if (!via_alloc_depth_buffer(vmesa)) {
-            via_free_depth_buffer(vmesa);
-            return GL_FALSE;
-        }
-    }
 
-    return GL_TRUE;
+/**
+ * Calculate a width that satisfies the hardware's alignment requirements.
+ * On the Unichrome hardware, each scanline must be aligned to a multiple of
+ * 16 pixels.
+ *
+ * \param width  Minimum buffer width, in pixels.
+ * 
+ * \returns A pixel width that meets the alignment requirements.
+ */
+static __inline__ unsigned
+buffer_align( unsigned width )
+{
+    return (width + 0x0f) & ~0x0f;
 }
 
-static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
+
+/**
+ * Calculate the framebuffer parameters for all buffers (front, back, depth,
+ * and stencil) associated with the specified context.
+ * 
+ * \warning
+ * This function also calls \c AllocateBuffer to actually allocate the
+ * buffers.
+ * 
+ * \sa AllocateBuffer
+ */
+static GLboolean
+calculate_buffer_parameters( struct via_context *vmesa )
 {
-    switch (name) {
-    case GL_VENDOR:
-        return (GLubyte *)"VIA Technology";
-    case GL_RENDERER:
-        return (GLubyte *)"Mesa DRI VIA CLE266 20020221";
-    default:
-        return 0;
-    }
+   const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
+   const unsigned extra = 32;
+   unsigned w;
+   unsigned h;
+
+   /* Allocate front-buffer */
+   if (vmesa->drawType == GLX_PBUFFER_BIT) {
+      w = vmesa->driDrawable->w;
+      h = vmesa->driDrawable->h;
+
+      vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
+      vmesa->front.pitch = buffer_align( w ) << shift;
+      vmesa->front.size = vmesa->front.pitch * h;
+
+      if (vmesa->front.map)
+        via_free_draw_buffer(vmesa, &vmesa->front);
+      if (!via_alloc_draw_buffer(vmesa, &vmesa->front))
+        return GL_FALSE;
+
+   } else {
+      w = vmesa->viaScreen->width;
+      h = vmesa->viaScreen->height;
+
+      vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
+      vmesa->front.pitch = buffer_align( w ) << shift;
+      vmesa->front.size = vmesa->front.pitch * h;
+      if (getenv("ALTERNATE_SCREEN")) 
+        vmesa->front.offset = vmesa->front.size;
+      else
+       vmesa->front.offset = 0;
+      vmesa->front.map = (char *) vmesa->driScreen->pFB;
+   }
+
+
+   /* Allocate back-buffer */
+   if (vmesa->hasBack) {
+      vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel;
+      vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift);
+      vmesa->back.pitch += extra;
+      vmesa->back.pitch = MIN2(vmesa->back.pitch, vmesa->front.pitch);
+      vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
+      if (vmesa->back.map)
+        via_free_draw_buffer(vmesa, &vmesa->back);
+      if (!via_alloc_draw_buffer(vmesa, &vmesa->back))
+        return GL_FALSE;
+   }
+   else {
+      if (vmesa->back.map)
+        via_free_draw_buffer(vmesa, &vmesa->back);
+      (void) memset( &vmesa->back, 0, sizeof( vmesa->back ) );
+   }
+
+
+   /* Allocate depth-buffer */
+   if ( vmesa->hasStencil || vmesa->hasDepth ) {
+      vmesa->depth.bpp = vmesa->depthBits;
+      if (vmesa->depth.bpp == 24)
+        vmesa->depth.bpp = 32;
+
+      vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) * 
+                           (vmesa->depth.bpp/8)) + extra;
+      vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
+
+      if (vmesa->depth.map)
+        via_free_draw_buffer(vmesa, &vmesa->depth);
+      if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) {
+        return GL_FALSE;
+      }
+   }
+   else {
+      if (vmesa->depth.map)
+        via_free_draw_buffer(vmesa, &vmesa->depth);
+      (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
+   }
+
+   if( vmesa->viaScreen->width == vmesa->driDrawable->w && 
+       vmesa->viaScreen->height == vmesa->driDrawable->h ) {
+      vmesa->doPageFlip = vmesa->allowPageFlip;
+      assert(vmesa->back.pitch == vmesa->front.pitch);
+   }
+   else
+      vmesa->doPageFlip = GL_FALSE;
+
+   return GL_TRUE;
 }
 
+
 void viaReAllocateBuffers(GLframebuffer *drawbuffer)
 {
-    GLcontext *ctx;
-    viaContextPtr vmesa = current_mesa;
-    
-    ctx = vmesa->glCtx;
-    ctx->DrawBuffer->Width = drawbuffer->Width;
-    ctx->DrawBuffer->Height = drawbuffer->Height;
+    GET_CURRENT_CONTEXT(ctx);
+    struct via_context *vmesa = VIA_CONTEXT(ctx);
 
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-#endif
-    ctx->DrawBuffer->Accum = 0;
-     
-    vmesa->driDrawable->w = ctx->DrawBuffer->Width;
-    vmesa->driDrawable->h = ctx->DrawBuffer->Height;
-    LOCK_HARDWARE(vmesa);
-    
-    /* Allocate back & depth buffer */
-    {
-       int w, h, bpp;      
-       w = vmesa->driDrawable->w;
-       h = vmesa->driDrawable->h;
-       /* back buffer */
-       bpp = vmesa->viaScreen->bitsPerPixel;
-#ifdef DEBUG       
-       if (VIA_DEBUG) fprintf(stderr, "driScreen->fbBPP = %d\n", bpp);     
-#endif     
-       if (bpp == 32) {
-           w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-           vmesa->back.size = w * h * bpp / 8;
-           vmesa->back.pitch = w << 2;
-       }
-       else {
-           w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
-           vmesa->back.size = w * h * bpp / 8;
-           vmesa->back.pitch = w << 1;        
-       }
-#ifdef DEBUG
-       if (VIA_DEBUG) fprintf(stderr, "resizebuffer backbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
-                           w, h, bpp, vmesa->back.size);
-#endif
-       /* depth buffer */
-       w = vmesa->driDrawable->w;
-       if (vmesa->hasDepth && vmesa->hasStencil) {
-           w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-           vmesa->depth.size = w * h * 4;
-           vmesa->depth.pitch = w << 2;
-           vmesa->depth.bpp = 32;
-#ifdef DEBUG
-           if (VIA_DEBUG) fprintf(stderr, "depthBits = 24\n");
-           if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
-#endif
-       }
-       else if (vmesa->hasDepth) {
-           /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */
-           /*if(vmesa->viaScreen->bitsPerPixel == 32)*/
-               /*vmesa->depthBits = 16;*/
-               
-           if (vmesa->depthBits == 16) {
-               w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
-               vmesa->depth.size = w * h * 2;         
-               vmesa->depth.pitch = w << 1;
-               vmesa->depth.bpp = 16;
-#ifdef DEBUG
-               if (VIA_DEBUG) fprintf(stderr, "depthBits = 16\n");
-#endif
-           }
-           else {
-               w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-               vmesa->depth.size = w * h * 4;
-               vmesa->depth.pitch = w << 2;
-               vmesa->depth.bpp = 32;
-#ifdef DEBUG
-               if (VIA_DEBUG) fprintf(stderr, "depthBits = 32\n");
-#endif
-           }
-       }
-       else if (vmesa->hasStencil) {
-           w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-           vmesa->depth.size = w * h * 4;
-           vmesa->depth.pitch = w << 2;
-           vmesa->depth.bpp = 32;
-#ifdef DEBUG           
-           if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
-#endif
-       }
-#ifdef DEBUG
-       if (VIA_DEBUG) fprintf(stderr, "resizebuffer depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
-                                   w, h, vmesa->depth.bpp, vmesa->depth.size);
-#endif 
-       /*=* John Sheng [2003.5.31] flip *=*/
-       {
-           if(vmesa->viaScreen->width == vmesa->driDrawable->w &&
-               vmesa->viaScreen->height == vmesa->driDrawable->h) {
-               vmesa->back.pitch = vmesa->front.pitch;
-               vmesa->back.size = vmesa->front.size;
-           }
-       }
-    
-       if (!AllocateBuffer(vmesa)) {
-           FREE(vmesa);
-       }
-    }
-    UNLOCK_HARDWARE(vmesa);
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-#endif
+    _swrast_alloc_buffers( drawbuffer );
+    calculate_buffer_parameters( vmesa );
 }
-static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
 
-{      
-    /* MESA5.0 */
-    viaContextPtr vmesa = current_mesa;
+static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+{
+    GET_CURRENT_CONTEXT(ctx);
+    struct via_context *vmesa = VIA_CONTEXT(ctx);       
     *width = vmesa->driDrawable->w;
     *height = vmesa->driDrawable->h;
 }
 
-static void viaInitExtensions(GLcontext *ctx)
+/* Extension strings exported by the Unichrome driver.
+ */
+static const char * const card_extensions[] = 
 {
-    _mesa_enable_imaging_extensions(ctx);
-    _mesa_enable_extension(ctx, "GL_ARB_multitexture");
-    _mesa_enable_extension(ctx, "GL_ARB_texture_env_add");
-    _mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
-    _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap");
-    _mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias");
-    /*=* John Sheng [2003.7.18] texture combine *=*/
-    _mesa_enable_extension(ctx, "GL_ARB_texture_env_combine");
-    _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine");
-    /*=* John Sheng [2003.7.18] texture dot3 *=*/
-    _mesa_enable_extension(ctx, "GL_ARB_texture_env_dot3");
-    _mesa_enable_extension(ctx, "GL_EXT_texture_env_dot3");
-    /*=* John Sheng [2003.7.18] point parameters */
-    _mesa_enable_extension(ctx, "GL_ARB_point_parameters");
-    _mesa_enable_extension(ctx, "GL_EXT_point_parameters");
-}
+   "GL_ARB_multitexture",
+   "GL_ARB_point_parameters",
+   "GL_ARB_texture_env_add",
+   "GL_ARB_texture_env_combine",
+/*    "GL_ARB_texture_env_dot3", */
+   "GL_ARB_texture_mirrored_repeat",
+   "GL_EXT_stencil_wrap",
+   "GL_EXT_texture_env_combine",
+/*    "GL_EXT_texture_env_dot3", */
+   "GL_EXT_texture_lod_bias",
+   "GL_EXT_secondary_color",
+   "GL_EXT_fog_coord",
+   "GL_NV_blend_square",
+   NULL
+};
 
 extern const struct tnl_pipeline_stage _via_fastrender_stage;
 extern const struct tnl_pipeline_stage _via_render_stage;
@@ -259,85 +270,79 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
     /* REMOVE: point attenuation stage */
 #if 1
     &_via_fastrender_stage,     /* ADD: unclipped rastersetup-to-dma */
-    &_via_render_stage,         /* ADD: modification from _tnl_render_stage */
 #endif
     &_tnl_render_stage,
     0,
 };
 
 
+static const struct dri_debug_control debug_control[] =
+{
+    { "fall",  DEBUG_FALLBACKS },
+    { "tex",   DEBUG_TEXTURE },
+    { "ioctl", DEBUG_IOCTL },
+    { "prim",  DEBUG_PRIMS },
+    { "vert",  DEBUG_VERTS },
+    { "state", DEBUG_STATE },
+    { "verb",  DEBUG_VERBOSE },
+    { "dri",   DEBUG_DRI },
+    { "dma",   DEBUG_DMA },
+    { "san",   DEBUG_SANITY },
+    { "sync",  DEBUG_SYNC },
+    { "sleep", DEBUG_SLEEP },
+    { "pix",   DEBUG_PIXEL },
+    { "2d",    DEBUG_2D },
+    { NULL,    0 }
+};
+
+
 static GLboolean
-AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
+AllocateDmaBuffer(const GLvisual *visual, struct via_context *vmesa)
 {
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-#endif
-    if (vmesa->dma[0].map && vmesa->dma[1].map)
+    if (vmesa->dma)
         via_free_dma_buffer(vmesa);
     
-    if (!via_alloc_dma_buffer(vmesa)) {
-       if (vmesa->front.map)
-           via_free_front_buffer(vmesa);
-        if (vmesa->back.map) 
-           via_free_back_buffer(vmesa);
-        if (vmesa->depth.map)
-           via_free_depth_buffer(vmesa);
-           
+    if (!via_alloc_dma_buffer(vmesa))
         return GL_FALSE;
-    }   
-#ifdef DEBUG 
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-#endif
-    return GL_TRUE;
-}
-
-static void
-InitVertexBuffer(viaContextPtr vmesa)
-{
-    GLuint *addr;
 
-    addr = (GLuint *)vmesa->dma[0].map;
-    *addr = 0xF210F110;
-    *addr = (HC_ParaType_NotTex << 16);
-    *addr = 0xcccccccc;
-    *addr = 0xdddddddd;
-    
-    addr = (GLuint *)vmesa->dma[1].map;
-    *addr = 0xF210F110;
-    *addr = (HC_ParaType_NotTex << 16);
-    *addr = 0xcccccccc;
-    *addr = 0xdddddddd;
-
-    vmesa->dmaIndex = 0;
-    vmesa->dmaLow = DMA_OFFSET;
-    vmesa->dmaHigh = vmesa->dma[0].size;
-    vmesa->dmaAddr = (unsigned char *)vmesa->dma[0].map;
-    vmesa->dmaLastPrim = vmesa->dmaLow;
+    vmesa->dmaLow = 0;
+    vmesa->dmaCliprectAddr = ~0;
+    return GL_TRUE;
 }
 
 static void
-FreeBuffer(viaContextPtr vmesa)
+FreeBuffer(struct via_context *vmesa)
 {
-    if (vmesa->front.map)
-       via_free_front_buffer(vmesa);
+    if (vmesa->front.map && vmesa->drawType == GLX_PBUFFER_BIT)
+       via_free_draw_buffer(vmesa, &vmesa->front);
 
     if (vmesa->back.map)
-        via_free_back_buffer(vmesa);
+        via_free_draw_buffer(vmesa, &vmesa->back);
 
     if (vmesa->depth.map)
-        via_free_depth_buffer(vmesa);
+        via_free_draw_buffer(vmesa, &vmesa->depth);
 
-    if (vmesa->dma[0].map && vmesa->dma[1].map)
+    if (vmesa->breadcrumb.map)
+        via_free_draw_buffer(vmesa, &vmesa->breadcrumb);
+
+    if (vmesa->dma)
         via_free_dma_buffer(vmesa);
 }
 
+static int
+get_ust_nop( int64_t * ust )
+{
+   *ust = 1;
+   return 0;
+}
+
 GLboolean
 viaCreateContext(const __GLcontextModes *mesaVis,
                  __DRIcontextPrivate *driContextPriv,
                  void *sharedContextPrivate)
 {
     GLcontext *ctx, *shareCtx;
-    viaContextPtr vmesa;
+    struct via_context *vmesa;
     __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
     viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
     drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
@@ -345,50 +350,80 @@ viaCreateContext(const __GLcontextModes *mesaVis,
     struct dd_function_table functions;
 
     /* Allocate via context */
-    vmesa = (viaContextPtr) CALLOC_STRUCT(via_context_t);
+    vmesa = (struct via_context *) CALLOC_STRUCT(via_context);
     if (!vmesa) {
         return GL_FALSE;
     }
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
-#endif
-    current_mesa = vmesa;    
+
+    /* Parse configuration files.
+     */
+    driParseConfigFiles (&vmesa->optionCache, &viaScreen->optionCache,
+                        sPriv->myNum, "via");
+
     /* pick back buffer */
-    if (mesaVis->doubleBufferMode) {
-       vmesa->hasBack = GL_TRUE;
-    }
-    else {
-       vmesa->hasBack = GL_FALSE;
-    }
-    /* pick z buffer */        
-    if (mesaVis->haveDepthBuffer) {
-       vmesa->hasDepth = GL_TRUE;
-       vmesa->depthBits = mesaVis->depthBits;
-    }
-    else {
-       vmesa->hasDepth = GL_FALSE;
-       vmesa->depthBits = 0;
-    }
-    /* pick stencil buffer */
-    if (mesaVis->haveStencilBuffer) {
-       vmesa->hasStencil = GL_TRUE;
-       vmesa->stencilBits = mesaVis->stencilBits;
-    }
-    else {
-       vmesa->hasStencil = GL_FALSE;
-       vmesa->stencilBits = 0;
+    vmesa->hasBack = mesaVis->doubleBufferMode;
+
+    switch(mesaVis->depthBits) {
+    case 0:                    
+       vmesa->hasDepth = GL_FALSE;
+       vmesa->depthBits = 0; 
+       vmesa->depth_max = 1.0;
+       break;
+    case 16:
+       vmesa->hasDepth = GL_TRUE;
+       vmesa->depthBits = mesaVis->depthBits;
+       vmesa->have_hw_stencil = GL_FALSE;
+       vmesa->depth_max = (GLfloat)0xffff;
+       vmesa->depth_clear_mask = 0xf << 28;
+       vmesa->ClearDepth = 0xffff;
+       vmesa->polygon_offset_scale = 1.0 / vmesa->depth_max;
+       break;
+    case 24:
+       vmesa->hasDepth = GL_TRUE;
+       vmesa->depthBits = mesaVis->depthBits;
+       vmesa->depth_max = (GLfloat) 0xffffff;
+       vmesa->depth_clear_mask = 0xe << 28;
+       vmesa->ClearDepth = 0xffffff00;
+
+       assert(mesaVis->haveStencilBuffer);
+       assert(mesaVis->stencilBits == 8);
+
+       vmesa->have_hw_stencil = GL_TRUE;
+       vmesa->stencilBits = mesaVis->stencilBits;
+       vmesa->stencil_clear_mask = 0x1 << 28;
+       vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
+       break;
+    case 32:
+       vmesa->hasDepth = GL_TRUE;
+       vmesa->depthBits = mesaVis->depthBits;
+       assert(!mesaVis->haveStencilBuffer);
+       vmesa->have_hw_stencil = GL_FALSE;
+       vmesa->depth_max = (GLfloat)0xffffffff;
+       vmesa->depth_clear_mask = 0xf << 28;
+       vmesa->ClearDepth = 0xffffffff;
+       vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
+       break;
+    default:
+       assert(0); 
+       break;
     }
 
+    make_empty_list(&vmesa->freed_tex_buffers);
+    make_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]);
+    make_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]);
+    make_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]);
+
     _mesa_init_driver_functions(&functions);
     viaInitTextureFuncs(&functions);
 
     /* Allocate the Mesa context */
     if (sharedContextPrivate)
-        shareCtx = ((viaContextPtr) sharedContextPrivate)->glCtx;
+        shareCtx = ((struct via_context *) sharedContextPrivate)->glCtx;
     else
         shareCtx = NULL;
 
-    vmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, &functions, (void*) vmesa);
+    vmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, &functions,
+                                       (void*) vmesa);
     
     vmesa->shareCtx = shareCtx;
     
@@ -400,31 +435,21 @@ viaCreateContext(const __GLcontextModes *mesaVis,
 
     ctx = vmesa->glCtx;
     
-    /* check */
-    /*=* John Sheng [2003.7.2] for visual config number can't excess 8 *=*/
-    /*if (viaScreen->textureSize < 2 * 1024 * 1024) {
-        ctx->Const.MaxTextureLevels = 9;
-    }
-    else if (viaScreen->textureSize < 8 * 1024 * 1024) {
-        ctx->Const.MaxTextureLevels = 10;
-    }
-    else {
-        ctx->Const.MaxTextureLevels = 11;
-    }*/
-    ctx->Const.MaxTextureLevels = 11;
-    
+    ctx->Const.MaxTextureLevels = 10;    
     ctx->Const.MaxTextureUnits = 2;
+    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
 
     ctx->Const.MinLineWidth = 1.0;
     ctx->Const.MinLineWidthAA = 1.0;
-    ctx->Const.MaxLineWidth = 3.0;
-    ctx->Const.MaxLineWidthAA = 3.0;
+    ctx->Const.MaxLineWidth = 1.0;
+    ctx->Const.MaxLineWidthAA = 1.0;
     ctx->Const.LineWidthGranularity = 1.0;
 
     ctx->Const.MinPointSize = 1.0;
     ctx->Const.MinPointSizeAA = 1.0;
-    ctx->Const.MaxPointSize = 3.0;
-    ctx->Const.MaxPointSizeAA = 3.0;
+    ctx->Const.MaxPointSize = 1.0;
+    ctx->Const.MaxPointSizeAA = 1.0;
     ctx->Const.PointSizeGranularity = 1.0;
 
     ctx->Driver.GetBufferSize = viaBufferSize;
@@ -453,10 +478,8 @@ viaCreateContext(const __GLcontextModes *mesaVis,
     _tnl_allow_pixel_fog(ctx, GL_FALSE);
     _tnl_allow_vertex_fog(ctx, GL_TRUE);
 
-#ifndef _SOLO
-    vmesa->display = dpy;
+/*     vmesa->display = dpy; */
     vmesa->display = sPriv->display;
-#endif
     
     vmesa->hHWContext = driContextPriv->hHWContext;
     vmesa->driFd = sPriv->fd;
@@ -465,404 +488,190 @@ viaCreateContext(const __GLcontextModes *mesaVis,
     vmesa->viaScreen = viaScreen;
     vmesa->driScreen = sPriv;
     vmesa->sarea = saPriv;
-    vmesa->glBuffer = NULL;
 
-    vmesa->texHeap = mmInit(0, viaScreen->textureSize);
-    vmesa->stippleInHw = 1;
     vmesa->renderIndex = ~0;
-    vmesa->dirty = VIA_UPLOAD_ALL;
-    vmesa->uploadCliprects = GL_TRUE;
-    vmesa->needUploadAllState = 1;
+    vmesa->setupIndex = ~0;
+    vmesa->hwPrimitive = GL_POLYGON+1;
 
-    make_empty_list(&vmesa->TexObjList);
-    make_empty_list(&vmesa->SwappedOut);
+    /* KW: Hardwire this.  Was previously set bogusly in
+     * viaCreateBuffer.  Needs work before PBUFFER can be used:
+     */
+    vmesa->drawType = GLX_WINDOW_BIT;
 
-    vmesa->CurrentTexObj[0] = 0;
-    vmesa->CurrentTexObj[1] = 0;
-    
-    vmesa->dma[0].size = DMA_SIZE * 1024 * 1024;
-    vmesa->dma[1].size = DMA_SIZE * 1024 * 1024;
 
     _math_matrix_ctr(&vmesa->ViewportMatrix);
 
-    viaInitExtensions(ctx);
+    /* Do this early, before VIA_FLUSH_DMA can be called:
+     */
+    if (!AllocateDmaBuffer(mesaVis, vmesa)) {
+       fprintf(stderr ,"AllocateDmaBuffer fail\n");
+       FreeBuffer(vmesa);
+        FREE(vmesa);
+        return GL_FALSE;
+    }
+
+    /* Allocate a small piece of fb memory for synchronization:
+     */
+    vmesa->breadcrumb.bpp = 32;
+    vmesa->breadcrumb.pitch = buffer_align( 64 ) << 2;
+    vmesa->breadcrumb.size = vmesa->breadcrumb.pitch;
+
+    if (!via_alloc_draw_buffer(vmesa, &vmesa->breadcrumb)) {
+        fprintf(stderr ,"AllocateDmaBuffer fail\n");
+        FreeBuffer(vmesa);
+        FREE(vmesa);
+        return GL_FALSE;
+    }
+
+    driInitExtensions( ctx, card_extensions, GL_TRUE );
     viaInitStateFuncs(ctx);
-    viaInitTextures(ctx);
     viaInitTriFuncs(ctx);
     viaInitSpanFuncs(ctx);
     viaInitIoctlFuncs(ctx);
-    viaInitVB(ctx);
     viaInitState(ctx);
         
     if (getenv("VIA_DEBUG"))
-       VIA_DEBUG = 1;
-    else
-       VIA_DEBUG = 0;  
-       
-    if (getenv("DRAW_FRONT"))
-       DRAW_FRONT = 1;
-    else
-       DRAW_FRONT = 0; 
-       
-#ifdef PERFORMANCE_MEASURE
-    if (getenv("VIA_PERFORMANCE"))
-       VIA_PERFORMANCE = 1;
-    else
-       VIA_PERFORMANCE = 0;    
-       
-    {
-       int i, j;
-       for (i = 0; i < HASH_TABLE_SIZE; i++) {
-           for (j = 0; j < HASH_TABLE_DEPTH; j ++) {
-               hash_table[i][j].count = 0;
-               sprintf(hash_table[i][j].func, "%s", "NULL");
-           }
-       }
-    }
-#endif 
+       VIA_DEBUG = driParseDebugString( getenv( "VIA_DEBUG" ),
+                                       debug_control );
 
-    if (!AllocateDmaBuffer(mesaVis, vmesa)) {
-       fprintf(stderr ,"AllocateDmaBuffer fail\n");
-        FREE(vmesa);
-        return GL_FALSE;
+    if (getenv("VIA_NO_RAST"))
+       FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
+
+    /* I don't understand why this isn't working:
+     */
+    vmesa->vblank_flags =
+       vmesa->viaScreen->irqEnabled ?
+        driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
+
+    /* Hack this up in its place:
+     */
+    vmesa->vblank_flags = (getenv("VIA_VSYNC") ? 
+                          VBLANK_FLAG_SYNC : VBLANK_FLAG_NO_IRQ);
+
+    if (getenv("VIA_PAGEFLIP"))
+       vmesa->allowPageFlip = 1;
+   
+    vmesa->get_ust = 
+       (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
+    if ( vmesa->get_ust == NULL ) {
+       vmesa->get_ust = get_ust_nop;
     }
+    vmesa->get_ust( &vmesa->swap_ust );
+
 
-    InitVertexBuffer(vmesa);
-    
     vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
     vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4);
     vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400);
     vmesa->regTranSet = (GLuint *)((GLuint)viaScreen->reg + 0x43C);
     vmesa->regTranSpace = (GLuint *)((GLuint)viaScreen->reg + 0x440);
     vmesa->agpBase = viaScreen->agpBase;
-#ifdef DEBUG    
-    if (VIA_DEBUG) {
-       fprintf(stderr, "regEngineStatus = %x\n", *vmesa->regEngineStatus);
-    }
-    
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-#endif
-    {
-       GLboolean saam;
-       int count = 0, fbSize;
-#ifdef _SOLO
-        vmesa->saam = 0;
-#else
-       saam = XineramaIsActive(vmesa->display);
-       if (saam && vmesa->viaScreen->drixinerama) {
-           vmesa->xsi = XineramaQueryScreens(vmesa->display, &count);
-           /* Test RightOf or Down */
-           if (vmesa->xsi[0].x_org == 0 && vmesa->xsi[0].y_org == 0) {
-               if (vmesa->xsi[1].x_org == vmesa->xsi[1].width) {
-                   vmesa->saam = RightOf;
-               }
-               else {
-                   vmesa->saam = Down;
-               }
-           }
-           /* Test LeftOf or Up */
-           else if (vmesa->xsi[0].x_org == vmesa->xsi[0].width) {
-               vmesa->saam = LeftOf;
-           }
-           else if (vmesa->xsi[0].y_org == vmesa->xsi[0].height) {
-               vmesa->saam = Up;
-           }
-           else
-               vmesa->saam = 0;
-               
-                   
-           fbSize = vmesa->viaScreen->fbSize;
-       }
-       else
-           vmesa->saam = 0;
-#endif
-    }
-    
-    vmesa->pSaamRects = (drm_clip_rect_t *) malloc(sizeof(drm_clip_rect_t));    
+
     return GL_TRUE;
 }
 
 void
 viaDestroyContext(__DRIcontextPrivate *driContextPriv)
 {
-    viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
-    /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
-    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
-    viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
-#endif
+    GET_CURRENT_CONTEXT(ctx);
+    struct via_context *vmesa = 
+       (struct via_context *)driContextPriv->driverPrivate;
+    struct via_context *current = ctx ? VIA_CONTEXT(ctx) : NULL;
     assert(vmesa); /* should never be null */
-    viaFlushPrimsLocked(vmesa);
-    WAIT_IDLE
-    /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
-    /* Enable VQ */
-    if (viaScreen->VQEnable) {
-       *vmesa->regTranSet = 0x00fe0000;
-       *vmesa->regTranSet = 0x00fe0000;
-       *vmesa->regTranSpace = 0x00000006;
-       *vmesa->regTranSpace = 0x40008c0f;
-       *vmesa->regTranSpace = 0x44000000;
-       *vmesa->regTranSpace = 0x45080c04;
-       *vmesa->regTranSpace = 0x46800408;
+
+    /* check if we're deleting the currently bound context */
+    if (vmesa == current) {
+      VIA_FLUSH_DMA(vmesa);
+      _mesa_make_current2(NULL, NULL, NULL);
     }
+
     if (vmesa) {
-       /*=* John Sheng [2003.5.31] flip *=*/
-       if(vmesa->doPageFlip) {
-           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000;
-           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004;
-           WAIT_IDLE
-           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = 0;
+        viaWaitIdle(vmesa);
+       if (vmesa->doPageFlip) {
+          LOCK_HARDWARE(vmesa);
+          if (vmesa->pfCurrentOffset != 0) {
+             fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+             viaResetPageFlippingLocked(vmesa);
+          }
+          UNLOCK_HARDWARE(vmesa);
        }
-       /*=* John Sheng [2003.5.31]  agp tex *=*/
-       if(VIA_DEBUG) fprintf(stderr, "agpFullCount = %d\n", agpFullCount);    
        
        _swsetup_DestroyContext(vmesa->glCtx);
         _tnl_DestroyContext(vmesa->glCtx);
         _ac_DestroyContext(vmesa->glCtx);
         _swrast_DestroyContext(vmesa->glCtx);
-        viaFreeVB(vmesa->glCtx);
-       FreeBuffer(vmesa);
         /* free the Mesa context */
        _mesa_destroy_context(vmesa->glCtx);
-       vmesa->glCtx->DriverCtx = NULL;
+       /* release our data */
+       FreeBuffer(vmesa);
+
+       assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]));
+       assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]));
+       assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]));
+       assert (is_empty_list(&vmesa->freed_tex_buffers));
+
         FREE(vmesa);
     }
-    
-    P_M_R;
-
-#ifdef PERFORMANCE_MEASURE
-    if (VIA_PERFORMANCE) fprintf(stderr, "idle = %d\n", idle);
-    if (VIA_PERFORMANCE) fprintf(stderr, "busy = %d\n", busy);
-#endif    
-#ifdef DEBUG        
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-#endif
 }
 
-void viaXMesaSetFrontClipRects(viaContextPtr vmesa)
-{
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-
-    vmesa->numClipRects = dPriv->numClipRects;
-    vmesa->pClipRects = dPriv->pClipRects;
-    vmesa->drawX = dPriv->x;
-    vmesa->drawY = dPriv->y;
-    vmesa->drawW = dPriv->w;
-    vmesa->drawH = dPriv->h;
 
-    viaEmitDrawingRectangle(vmesa);
-    vmesa->uploadCliprects = GL_TRUE;
-}
-
-void viaXMesaSetBackClipRects(viaContextPtr vmesa)
+void viaXMesaWindowMoved(struct via_context *vmesa)
 {
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-    /*=* John Sheng [2003.6.9] fix glxgears dirty screen */
-    /*if (vmesa->saam) {*/
-           vmesa->numClipRects = dPriv->numClipRects;
-           vmesa->pClipRects = dPriv->pClipRects;
-           vmesa->drawX = dPriv->x;
-           vmesa->drawY = dPriv->y;
-           vmesa->drawW = dPriv->w;
-           vmesa->drawH = dPriv->h;
-    /*}
-    else {
-       if (dPriv->numBackClipRects == 0) {
-           vmesa->numClipRects = dPriv->numClipRects;
-           vmesa->pClipRects = dPriv->pClipRects;
-           vmesa->drawX = dPriv->x;
-           vmesa->drawY = dPriv->y;
-           vmesa->drawW = dPriv->w;
-           vmesa->drawH = dPriv->h;
-       }
-       else {
-           vmesa->numClipRects = dPriv->numBackClipRects;
-           vmesa->pClipRects = dPriv->pBackClipRects;
-           vmesa->drawX = dPriv->backX;
-           vmesa->drawY = dPriv->backY;
-           vmesa->drawW = dPriv->w;
-           vmesa->drawH = dPriv->h;
-       }
-    }*/
-    viaEmitDrawingRectangle(vmesa);
-    vmesa->uploadCliprects = GL_TRUE;
-}
-
-void viaXMesaWindowMoved(viaContextPtr vmesa)
-{
-    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-    GLuint side = 0;
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-    
-    switch (vmesa->glCtx->Color._DrawDestMask) {
-    case __GL_FRONT_BUFFER_MASK: 
-        viaXMesaSetFrontClipRects(vmesa);
-        break;
-    case __GL_BACK_BUFFER_MASK:
-        viaXMesaSetBackClipRects(vmesa);
-        break;
-    default:
-        break;
-    }
-
-#ifdef _SOLO
-    vmesa->viaScreen->fbOffset = 0;
-    vmesa->saam &= ~S1;
-    vmesa->saam |= S0;
-#else
-    side = vmesa->saam & P_MASK;
-    
-    switch (side) {
-       case RightOf:
-           /* full in screen 1 */
-           if (vmesa->drawX >= vmesa->xsi[0].width) {
-               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
-               vmesa->drawX = vmesa->drawX - vmesa->xsi[1].width;
-               vmesa->numClipRects = dPriv->numBackClipRects;
-               vmesa->pClipRects = dPriv->pBackClipRects;
-               vmesa->drawX = dPriv->backX;
-               vmesa->drawY = dPriv->backY;
-               vmesa->saam &= ~S0;
-               vmesa->saam |= S1;
-           }
-           /* full in screen 0 */
-           else if ((vmesa->drawX + vmesa->drawW) <= vmesa->xsi[0].width) {
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam &= ~S1;
-               vmesa->saam |= S0;
-           }
-           /* between screen 0 && screen 1 */
-           else {
-               vmesa->numSaamRects = dPriv->numBackClipRects;
-               vmesa->pSaamRects = dPriv->pBackClipRects;
-               vmesa->drawXSaam = dPriv->backX;
-               vmesa->drawYSaam = dPriv->backY;
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam |= S0;
-               vmesa->saam |= S1;
-           }
-           break;
-       case LeftOf:
-           /* full in screen 1 */
-           if (vmesa->drawX + vmesa->drawW <= 0) {
-               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
-               vmesa->drawX = vmesa->drawX + vmesa->xsi[1].width;
-               vmesa->numClipRects = dPriv->numBackClipRects;
-               vmesa->pClipRects = dPriv->pBackClipRects;
-               vmesa->drawX = dPriv->backX;
-               vmesa->drawY = dPriv->backY;            
-               vmesa->saam &= ~S0;
-               vmesa->saam |= S1;
-           }
-           /* full in screen 0 */
-           else if (vmesa->drawX >= 0) {
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam &= ~S1;
-               vmesa->saam |= S0;
-           }
-           /* between screen 0 && screen 1 */
-           else {
-               vmesa->numSaamRects = dPriv->numBackClipRects;
-               vmesa->pSaamRects = dPriv->pBackClipRects;
-               vmesa->drawXSaam = dPriv->backX;
-               vmesa->drawYSaam = dPriv->backY;
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam |= S0;
-               vmesa->saam |= S1;
-           }
-           break;
-       case Down :
-           /* full in screen 1 */
-           if (vmesa->drawY >= vmesa->xsi[0].height) {
-               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
-               vmesa->drawY = vmesa->drawY - vmesa->xsi[1].height;
-               vmesa->numClipRects = dPriv->numBackClipRects;
-               vmesa->pClipRects = dPriv->pBackClipRects;
-               vmesa->drawX = dPriv->backX;
-               vmesa->drawY = dPriv->backY;
-               vmesa->saam &= ~S0;
-               vmesa->saam |= S1;
-           }
-           /* full in screen 0 */
-           else if ((vmesa->drawY + vmesa->drawH) <= vmesa->xsi[0].height) {
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam &= ~S1;
-               vmesa->saam |= S0;
-           }
-           /* between screen 0 && screen 1 */
-           else {
-               vmesa->numSaamRects = dPriv->numBackClipRects;
-               vmesa->pSaamRects = dPriv->pBackClipRects;
-               vmesa->drawXSaam = dPriv->backX;
-               vmesa->drawYSaam = dPriv->backY;
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam |= S0;
-               vmesa->saam |= S1;
-           }
-           break;
-       case Up :
-           /* full in screen 1 */
-           if ((vmesa->drawY + vmesa->drawH) <= 0) {
-               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
-               vmesa->drawY = vmesa->drawY + vmesa->xsi[1].height;
-               vmesa->numClipRects = dPriv->numBackClipRects;
-               vmesa->pClipRects = dPriv->pBackClipRects;
-               vmesa->drawX = dPriv->backX;
-               vmesa->drawY = dPriv->backY;
-               vmesa->saam &= ~S0;
-               vmesa->saam |= S1;
-           }
-           /* full in screen 0 */
-           else if (vmesa->drawY >= 0) {
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam &= ~S1;
-               vmesa->saam |= S0;
-           }
-           /* between screen 0 && screen 1 */
-           else {
-               vmesa->numSaamRects = dPriv->numBackClipRects;
-               vmesa->pSaamRects = dPriv->pBackClipRects;
-               vmesa->drawXSaam = dPriv->backX;
-               vmesa->drawYSaam = dPriv->backY;
-               vmesa->viaScreen->fbOffset = 0;
-               vmesa->saam |= S0;
-               vmesa->saam |= S1;
-           }
-           break;
-       default:
-           vmesa->viaScreen->fbOffset = 0;
-    }
-#endif
-    
-    {
-       GLuint pitch, offset;
-       pitch = vmesa->front.pitch;
-       offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
-       vmesa->drawXoff = (GLuint)((offset & 0x1f) / bytePerPixel);
-       if (vmesa->saam) {
-           if (vmesa->pSaamRects) {
-               offset = vmesa->viaScreen->fbOffset + (vmesa->pSaamRects[0].y1 * pitch + 
-                   vmesa->pSaamRects[0].x1 * bytePerPixel);
-               vmesa->drawXoffSaam = (GLuint)((offset & 0x1f) / bytePerPixel);
-           }
-           else
-               vmesa->drawXoffSaam = 0;
-       }
-       else
-           vmesa->drawXoffSaam = 0;
-    }
-    
-    vmesa->glCtx->Driver.Viewport(vmesa->glCtx,0 ,0 ,0 ,0);
+   __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+   GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+
+   if (!dPriv)
+      return;
+
+   switch (vmesa->glCtx->Color._DrawDestMask[0]) {
+   case DD_FRONT_LEFT_BIT: 
+      if (dPriv->numBackClipRects == 0) {
+        vmesa->numClipRects = dPriv->numClipRects;
+        vmesa->pClipRects = dPriv->pClipRects;
+      } 
+      else {
+        vmesa->numClipRects = dPriv->numBackClipRects;
+        vmesa->pClipRects = dPriv->pBackClipRects;
+      }
+      break;
+   case DD_BACK_LEFT_BIT:
+      vmesa->numClipRects = dPriv->numClipRects;
+      vmesa->pClipRects = dPriv->pClipRects;
+      break;
+   default:
+      vmesa->numClipRects = 0;
+      break;
+   }
+
+   if (vmesa->drawW != dPriv->w ||
+       vmesa->drawH != dPriv->h) 
+      calculate_buffer_parameters( vmesa );
+
+   vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) / 
+                             bytePerPixel);  
+   vmesa->drawX = dPriv->x - vmesa->drawXoff;
+   vmesa->drawY = dPriv->y;
+   vmesa->drawW = dPriv->w;
+   vmesa->drawH = dPriv->h;
+
+   vmesa->front.orig = (vmesa->front.offset + 
+                       vmesa->drawY * vmesa->front.pitch + 
+                       vmesa->drawX * bytePerPixel);
+
+   vmesa->front.origMap = (vmesa->front.map + 
+                          vmesa->drawY * vmesa->front.pitch + 
+                          vmesa->drawX * bytePerPixel);
+
+   vmesa->back.orig = vmesa->back.offset;
+   vmesa->depth.orig = vmesa->depth.offset;   
+   vmesa->back.origMap = vmesa->back.map;
+   vmesa->depth.origMap = vmesa->depth.map;
+
+   viaCalcViewport(vmesa->glCtx);
 }
 
 GLboolean
 viaUnbindContext(__DRIcontextPrivate *driContextPriv)
 {
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-#endif
     return GL_TRUE;
 }
 
@@ -871,307 +680,83 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
                __DRIdrawablePrivate *driDrawPriv,
                __DRIdrawablePrivate *driReadPriv)
 {
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-  
-    if (VIA_DEBUG) {
+    if (VIA_DEBUG & DEBUG_DRI) {
        fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driContextPriv);
-       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driDrawPriv);    
-       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driReadPriv);
+       fprintf(stderr, "driDrawPriv = %08x\n", (GLuint)driDrawPriv);    
+       fprintf(stderr, "driReadPriv = %08x\n", (GLuint)driReadPriv);
     }  
-#endif    
-    
+
     if (driContextPriv) {
-        viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
-       current_mesa = vmesa;
-       
-       vmesa->driDrawable = driDrawPriv;
-       if (vmesa->drawType == GLX_PBUFFER_BIT) {
-           int w, h, bpp;
-           
-           w = vmesa->driDrawable->w;
-           h = vmesa->driDrawable->h;
-           bpp = vmesa->viaScreen->bitsPerPixel;
-           if (bpp == 32) {
-               w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
-               vmesa->front.size = w * h * bpp / 8;
-               vmesa->front.pitch = w << 2;
-           }
-           else {
-               w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
-               vmesa->front.size = w * h * bpp / 8;
-               vmesa->front.pitch = w << 1;           
-           }   
-       }
-       /*=* John Sheng [2003.6.20] fix resolution 720x480/720x576 front pitch error *=*/
-       else { 
-           GLuint w;
-           GLuint h;
-           GLuint bpp;
-           bpp = vmesa->viaScreen->bitsPerPixel;
-           h = vmesa->viaScreen->height;
-           w = vmesa->viaScreen->width;
-           if (bpp == 0x20) {
-               w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
-               vmesa->front.size = w * h * bpp / 8;
-               vmesa->front.pitch = w << 2;
-#ifdef DEBUG
-               if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", 32);       
-#endif
-           } 
-           else if (bpp == 0x10) {
-               w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
-               vmesa->front.size = w * h * bpp / 8;
-               vmesa->front.pitch = w << 1;           
-#ifdef DEBUG
-               if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", 16);       
-#endif
-           }
-           vmesa->front.offset = 0;
-           vmesa->front.map = (char *) vmesa->driScreen->pFB;
-           vmesa->front.size = w * h * vmesa->viaScreen->bitsPerPixel /8;
-       }
-       
-       /* Allocate back & depth buffer */
-       {
-           int w, h, bpp;
-           
-           w = vmesa->driDrawable->w;
-#ifdef DEBUG
-           if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", w);          
-#endif     
-           h = vmesa->driDrawable->h;
-           
-           /* back buffer */
-           bpp = vmesa->viaScreen->bitsPerPixel;
-#ifdef DEBUG       
-           if (VIA_DEBUG) fprintf(stderr, "driScreen->fbBPP = %d\n", bpp);         
-#endif     
-           if (bpp == 32) {
-               if (vmesa->drawType == GLX_PBUFFER_BIT)
-                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
-               else
-                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-               
-               vmesa->back.size = w * h * bpp / 8;
-               vmesa->back.pitch = w << 2;
-           }
-           else {
-               if (vmesa->drawType == GLX_PBUFFER_BIT)
-                   w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
-               else
-                   w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
-               
-               vmesa->back.size = w * h * bpp / 8;
-               vmesa->back.pitch = w << 1;            
-           }
-#ifdef DEBUG
-           if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent backbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
-                                   w, h, bpp, vmesa->back.size);
-#endif
-           /* depth buffer */
-           w = vmesa->driDrawable->w;
-
-           if (vmesa->hasDepth && vmesa->hasStencil) {
-               if (vmesa->drawType == GLX_PBUFFER_BIT)
-                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
-               else
-                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-
-               vmesa->depth.size = w * h * 4;
-               vmesa->depth.pitch = w << 2;
-               vmesa->depth.bpp = 32;
-#ifdef DEBUG
-               if (VIA_DEBUG) fprintf(stderr, "depthBits = 24\n");
-               if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
-#endif
-           }
-           else if (vmesa->hasDepth) {
-
-               /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */
-               /*if(vmesa->viaScreen->bitsPerPixel == 32)*/
-                   /*vmesa->depthBits = 16;*/
-                   
-               if (vmesa->depthBits == 16) {
-                   if (vmesa->drawType == GLX_PBUFFER_BIT)
-                       w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
-                   else
-                       w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
-
-                   vmesa->depth.size = w * h * 2;             
-                   vmesa->depth.pitch = w << 1;
-                   vmesa->depth.bpp = 16;
-#ifdef DEBUG
-                   if (VIA_DEBUG) fprintf(stderr, "depthBits = 16\n");
-#endif
-               }
-               else {
-                   if (vmesa->drawType == GLX_PBUFFER_BIT)
-                       w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
-                   else
-                       w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-
-                   vmesa->depth.size = w * h * 4;
-                   vmesa->depth.pitch = w << 2;
-                   vmesa->depth.bpp = 32;
-#ifdef DEBUG
-                   if (VIA_DEBUG) fprintf(stderr, "depthBits = 32\n");
-#endif
-               }
-           }
-           else if (vmesa->hasStencil) {
-               if (vmesa->drawType == GLX_PBUFFER_BIT)
-                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
-               else
-                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
-
-               vmesa->depth.size = w * h * 4;
-               vmesa->depth.pitch = w << 2;
-               vmesa->depth.bpp = 32;
-#ifdef DEBUG           
-               if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
-#endif
-           }
-#ifdef DEBUG
-           if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
-                                  w, h, vmesa->depth.bpp, vmesa->depth.size);
-#endif     
-           /*=* John Sheng [2003.5.31] flip *=*/
-           {
-               viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;     
-               if(vmesa->viaScreen->width == vmesa->driDrawable->w &&
-                   vmesa->viaScreen->height == vmesa->driDrawable->h) {
-                   vmesa->doPageFlip = GL_FALSE;
-                   vmesa->currentPage = 0;
-                   vmesa->back.pitch = vmesa->front.pitch;
-               }
-           }
-
-           if (!AllocateBuffer(vmesa)) {
-               FREE(vmesa);
-               return GL_FALSE;
-           }
+        struct via_context *vmesa = 
+          (struct via_context *)driContextPriv->driverPrivate;
+       GLcontext *ctx = vmesa->glCtx;
+
+       if ( vmesa->driDrawable != driDrawPriv ) {
+          driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags );
+          vmesa->driDrawable = driDrawPriv;
+          if ( ! calculate_buffer_parameters( vmesa ) ) {
+             return GL_FALSE;
+          }
+          ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
        }
+
         _mesa_make_current2(vmesa->glCtx,
                             (GLframebuffer *)driDrawPriv->driverPrivate,
                             (GLframebuffer *)driReadPriv->driverPrivate);
-#ifdef DEBUG   
-       if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext);
-#endif
+       
         viaXMesaWindowMoved(vmesa);
-        if (!vmesa->glCtx->Viewport.Width)
-            _mesa_set_viewport(vmesa->glCtx, 0, 0,
-                               driDrawPriv->w, driDrawPriv->h);
+       ctx->Driver.Scissor(vmesa->glCtx,
+                           vmesa->glCtx->Scissor.X,
+                           vmesa->glCtx->Scissor.Y,
+                           vmesa->glCtx->Scissor.Width,
+                           vmesa->glCtx->Scissor.Height);
     }
     else {
         _mesa_make_current(0,0);
     }
         
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-#endif
     return GL_TRUE;
 }
 
-void viaGetLock(viaContextPtr vmesa, GLuint flags)
+void viaGetLock(struct via_context *vmesa, GLuint flags)
 {
     __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
     __DRIscreenPrivate *sPriv = vmesa->driScreen;
-    drm_via_sarea_t *sarea = vmesa->sarea;
-    int me = vmesa->hHWContext;
-    __DRIdrawablePrivate *pdp;
-    __DRIscreenPrivate *psp;
-    pdp = dPriv;
-    psp = sPriv;
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);  
-    if (VIA_DEBUG) fprintf(stderr, "drmGetLock - in\n");
-#endif
-    drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
-
-    do {
-           DRM_UNLOCK(psp->fd, &psp->pSAREA->lock,
-                  pdp->driContextPriv->hHWContext);
-           DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-            __driUtilUpdateDrawableInfo(dPriv);
-           DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-           DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock,
-                      pdp->driContextPriv->hHWContext);
-    } while (0);
-
-    if (sarea->ctxOwner != me) {
-        vmesa->uploadCliprects = GL_TRUE;
-        sarea->ctxOwner = me;
-    }
 
-    viaXMesaWindowMoved(vmesa);
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-#endif
-}
-
-void viaLock(viaContextPtr vmesa, GLuint flags)
-{
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-    __DRIscreenPrivate *sPriv = vmesa->driScreen;
-    
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-   
-    /*=* John Sheng [2003.6.16] for xf43 */
-    if(dPriv->pStamp == NULL)
-       dPriv->pStamp = &dPriv->lastStamp;
+    drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
 
-    if (*(dPriv->pStamp) != dPriv->lastStamp || vmesa->saam) {
-       GLuint scrn;
-       scrn = vmesa->saam & S_MASK;
-       
-       DRM_SPINLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
+    DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
 
-       if (scrn == S1)
-           __driUtilUpdateDrawableInfo(dPriv);
-       else
-           DRI_VALIDATE_DRAWABLE_INFO_ONCE(dPriv);
-           
-       viaXMesaWindowMoved(vmesa);
-       DRM_SPINUNLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
+    if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
+       vmesa->sarea->ctxOwner = vmesa->hHWContext;
+       vmesa->newEmitState = ~0;
     }
 
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-    
-    return;
-}
+    if (vmesa->lastStamp != dPriv->lastStamp) {
+       viaXMesaWindowMoved(vmesa);
+       vmesa->lastStamp = dPriv->lastStamp;
+    }
 
-void viaUnLock(viaContextPtr vmesa, GLuint flags)
-{
-    drm_via_sarea_t *sarea = vmesa->sarea;
-    int me = vmesa->hHWContext;
-    
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-    if (VIA_DEBUG) fprintf(stderr, "sarea->ctxOwner = %d\n", sarea->ctxOwner);
-    if (VIA_DEBUG) fprintf(stderr, "me = %d\n", me);
-#endif    
-    if (sarea->ctxOwner == me) {
-        sarea->ctxOwner = 0;
+    if (vmesa->doPageFlip &&
+       vmesa->pfCurrentOffset != vmesa->sarea->pfCurrentOffset) {
+       fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+       viaResetPageFlippingLocked(vmesa);
     }
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-#endif
 }
 
+
 void
 viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
 {
     __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
-#endif
-    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
-        viaContextPtr vmesa;
-        GLcontext *ctx;
-       
-        vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
-        ctx = vmesa->glCtx;
+
+    if (dPriv && 
+       dPriv->driContextPriv && 
+       dPriv->driContextPriv->driverPrivate) {
+        struct via_context *vmesa = 
+          (struct via_context *)dPriv->driContextPriv->driverPrivate;
+        GLcontext *ctx = vmesa->glCtx;
+
         if (ctx->Visual.doubleBufferMode) {
             _mesa_notifySwapBuffers(ctx);
             if (vmesa->doPageFlip) {
@@ -1182,12 +767,9 @@ viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
             }
         }
        else
-           VIA_FIREVERTICES(vmesa);
+           VIA_FLUSH_DMA(vmesa);
     }
     else {
         _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
     }
-#ifdef DEBUG
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
-#endif
 }