Move mipmap generation functions, texture scaling functions into new
[mesa.git] / src / mesa / drivers / dri / unichrome / via_context.c
index 9879a88e57abc53c0ec740482411c3935bf6c4f4..2459336bd6675add6338b237cb838ddc8c3820fe 100644 (file)
 #include "glheader.h"
 #include "context.h"
 #include "matrix.h"
+#include "state.h"
 #include "simple_list.h"
 #include "extensions.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.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"
-#include "via_regs.h"
 
 #include <stdio.h>
 #include "macros.h"
+#include "drirenderbuffer.h"
 
-#define DRIVER_DATE    "20041215"
+#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_secondary_color
+#include "extension_helper.h"
+
+#define DRIVER_DATE    "20060710"
 
 #include "vblank.h"
 #include "utils.h"
 
-#ifdef DEBUG
 GLuint VIA_DEBUG = 0;
-#endif
-#define DMA_SIZE 2
-
-/*=* John Sheng [2003.5.31]  agp tex *=*/
-
-static GLboolean
-AllocateBuffer(viaContextPtr vmesa)
-{
-    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;
-    }
-
-    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;
-}
 
 /**
  * Return various strings for \c glGetString.
@@ -125,8 +98,8 @@ static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
         "UniChrome (K8M800)",
         "UniChrome (PM8x0/CN400)",
       };
-      const viaContext * const via = VIA_CONTEXT(ctx);
-      const unsigned id = via->viaScreen->deviceID;
+      struct via_context *vmesa = VIA_CONTEXT(ctx);
+      unsigned id = vmesa->viaScreen->deviceID;
 
       offset = driGetRendererString( buffer, 
                                     chipset_names[(id > VIA_PM800) ? 0 : id],
@@ -156,6 +129,64 @@ buffer_align( unsigned width )
 }
 
 
+static void
+viaDeleteRenderbuffer(struct gl_renderbuffer *rb)
+{
+   /* Don't free() since we're contained in via_context struct. */
+}
+
+static GLboolean
+viaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
+                       GLenum internalFormat, GLuint width, GLuint height)
+{
+   rb->Width = width;
+   rb->Height = height;
+   rb->InternalFormat = internalFormat;
+   return GL_TRUE;
+}
+
+
+static void
+viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
+{
+   const GLuint name = 0;
+
+   _mesa_init_renderbuffer(rb, name);
+
+   /* Make sure we're using a null-valued GetPointer routine */
+   assert(rb->GetPointer(NULL, rb, 0, 0) == NULL);
+
+   rb->InternalFormat = format;
+
+   if (format == GL_RGBA) {
+      /* Color */
+      rb->_BaseFormat = GL_RGBA;
+      rb->DataType = GL_UNSIGNED_BYTE;
+   }
+   else if (format == GL_DEPTH_COMPONENT16) {
+      /* Depth */
+      rb->_BaseFormat = GL_DEPTH_COMPONENT;
+      /* we always Get/Put 32-bit Z values */
+      rb->DataType = GL_UNSIGNED_INT;
+   }
+   else if (format == GL_DEPTH_COMPONENT24) {
+      /* Depth */
+      rb->_BaseFormat = GL_DEPTH_COMPONENT;
+      /* we always Get/Put 32-bit Z values */
+      rb->DataType = GL_UNSIGNED_INT;
+   }
+   else {
+      /* Stencil */
+      ASSERT(format == GL_STENCIL_INDEX8_EXT);
+      rb->_BaseFormat = GL_STENCIL_INDEX;
+      rb->DataType = GL_UNSIGNED_BYTE;
+   }
+
+   rb->Delete = viaDeleteRenderbuffer;
+   rb->AllocStorage = viaRenderbufferStorage;
+}
+
+
 /**
  * Calculate the framebuffer parameters for all buffers (front, back, depth,
  * and stencil) associated with the specified context.
@@ -167,129 +198,192 @@ buffer_align( unsigned width )
  * \sa AllocateBuffer
  */
 static GLboolean
-calculate_buffer_parameters( viaContextPtr vmesa )
+calculate_buffer_parameters( struct via_context *vmesa,
+                             struct gl_framebuffer *fb )
 {
-    const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
-    const unsigned extra = (vmesa->drawType == GLX_PBUFFER_BIT) ? 0 : 32;
-    unsigned w;
-    unsigned h;
-
-    if (vmesa->drawType == GLX_PBUFFER_BIT) {
-       w = vmesa->driDrawable->w;
-       h = vmesa->driDrawable->h;
-    }
-    else { 
-       w = vmesa->viaScreen->width;
-       h = vmesa->viaScreen->height;
+   const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
+   const unsigned extra = 32;
+   unsigned w;
+   unsigned h;
+
+   /* Normally, the renderbuffer would be added to the framebuffer just once
+    * when the framebuffer was created.  The VIA driver is a bit funny
+    * though in that the front/back/depth renderbuffers are in the per-context
+    * state!
+    * That should be fixed someday.
+    */
+
+   if (!vmesa->front.Base.InternalFormat) {
+      /* do one-time init for the renderbuffers */
+      viaInitRenderbuffer(&vmesa->front.Base, GL_RGBA);
+      viaSetSpanFunctions(&vmesa->front, &fb->Visual);
+      _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base);
+
+      if (fb->Visual.doubleBufferMode) {
+         viaInitRenderbuffer(&vmesa->back.Base, GL_RGBA);
+         viaSetSpanFunctions(&vmesa->back, &fb->Visual);
+         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base);
+      }
+
+      if (vmesa->glCtx->Visual.depthBits > 0) {
+         viaInitRenderbuffer(&vmesa->depth.Base, 
+                             (vmesa->glCtx->Visual.depthBits == 16
+                              ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24));
+         viaSetSpanFunctions(&vmesa->depth, &fb->Visual);
+         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base);
+      }
+
+      if (vmesa->glCtx->Visual.stencilBits > 0) {
+         viaInitRenderbuffer(&vmesa->stencil.Base, GL_STENCIL_INDEX8_EXT);
+         viaSetSpanFunctions(&vmesa->stencil, &fb->Visual);
+         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base);
+      }
+   }
 
-       vmesa->front.offset = 0;
-       vmesa->front.map = (char *) vmesa->driScreen->pFB;
-    }
+   assert(vmesa->front.Base.InternalFormat);
+   assert(vmesa->front.Base.AllocStorage);
+   if (fb->Visual.doubleBufferMode) {
+      assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+      assert(vmesa->front.Base.AllocStorage);
+   }
+   if (fb->Visual.depthBits) {
+      assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
+      assert(vmesa->depth.Base.AllocStorage);
+   }
 
-    vmesa->front.pitch = buffer_align( w ) << shift;
-    vmesa->front.size = vmesa->front.pitch * 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; /* bytes, not pixels */
+      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; /* bytes, not pixels */
+      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 */
 
-    vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift) 
-      + extra;
-    vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
+   /* 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 ) );
+   }
 
-    if (VIA_DEBUG) fprintf(stderr, "%s backbuffer: w = %d h = %d bpp = %d sizs = %d\n",
-                          __FUNCTION__,
-                          vmesa->back.pitch, 
-                          vmesa->driDrawable->h,
-                          8 << shift,
-                          vmesa->back.size);
 
-    /* Allocate depth-buffer */
-    if ( vmesa->hasStencil || vmesa->hasDepth ) {
-       vmesa->depth.bpp = vmesa->depthBits;
-       if (vmesa->depth.bpp == 24)
-         vmesa->depth.bpp = 32;
+   /* 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;
-    }
-    else {
-       (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
-    }
+      vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) * 
+                           (vmesa->depth.bpp/8)) + extra;
+      vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
 
-    if (VIA_DEBUG) fprintf(stderr, "%s depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
-                          __FUNCTION__,
-                          vmesa->depth.pitch,
-                          vmesa->driDrawable->h,
-                          vmesa->depth.bpp,
-                          vmesa->depth.size);
-
-    /*=* John Sheng [2003.5.31] flip *=*/
-    if( vmesa->viaScreen->width == vmesa->driDrawable->w && 
-       vmesa->viaScreen->height == vmesa->driDrawable->h ) {
-#define ALLOW_EXPERIMENTAL_PAGEFLIP 0
-#if ALLOW_EXPERIMENTAL_PAGEFLIP
-       vmesa->doPageFlip = GL_TRUE;
-#else
-       vmesa->doPageFlip = GL_FALSE;
-#endif
-       vmesa->currentPage = 0;
-       vmesa->back.pitch = vmesa->front.pitch;
-    }
+      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 (!AllocateBuffer(vmesa)) {
-       FREE(vmesa);
-       return GL_FALSE;
-    }
-    
-    return GL_TRUE;
+   /* stencil buffer is same as depth buffer */
+   vmesa->stencil.handle = vmesa->depth.handle;
+   vmesa->stencil.size = vmesa->depth.size;
+   vmesa->stencil.offset = vmesa->depth.offset;
+   vmesa->stencil.index = vmesa->depth.index;
+   vmesa->stencil.pitch = vmesa->depth.pitch;
+   vmesa->stencil.bpp = vmesa->depth.bpp;
+   vmesa->stencil.map = vmesa->depth.map;
+   vmesa->stencil.orig = vmesa->depth.orig;
+   vmesa->stencil.origMap = vmesa->depth.origMap;
+
+   if( vmesa->viaScreen->width == vmesa->driDrawable->w && 
+       vmesa->viaScreen->height == vmesa->driDrawable->h ) {
+      vmesa->doPageFlip = vmesa->allowPageFlip;
+      if (vmesa->hasBack) {
+         assert(vmesa->back.pitch == vmesa->front.pitch);
+      }
+   }
+   else
+      vmesa->doPageFlip = GL_FALSE;
+
+   return GL_TRUE;
 }
 
 
-void viaReAllocateBuffers(GLframebuffer *drawbuffer)
+void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
+                          GLuint width, GLuint height)
 {
-    GET_CURRENT_CONTEXT(ctx);
-    viaContextPtr vmesa = VIA_CONTEXT(ctx);
-
-    ctx->DrawBuffer->Width = drawbuffer->Width;
-    ctx->DrawBuffer->Height = drawbuffer->Height;
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-    ctx->DrawBuffer->Accum = 0;
-     
-    vmesa->driDrawable->w = ctx->DrawBuffer->Width;
-    vmesa->driDrawable->h = ctx->DrawBuffer->Height;
+    struct via_context *vmesa = VIA_CONTEXT(ctx);
 
-    LOCK_HARDWARE(vmesa);
-    calculate_buffer_parameters( vmesa );
-    UNLOCK_HARDWARE(vmesa);
+    calculate_buffer_parameters( vmesa, drawbuffer );
 
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+    _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
 }
 
 static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
 {
     GET_CURRENT_CONTEXT(ctx);
-    viaContextPtr vmesa = VIA_CONTEXT(ctx);       
+    struct via_context *vmesa = VIA_CONTEXT(ctx);       
     *width = vmesa->driDrawable->w;
     *height = vmesa->driDrawable->h;
 }
 
 /* Extension strings exported by the Unichrome driver.
  */
-static const char * const card_extensions[] = 
+const struct dri_extension card_extensions[] =
 {
-   "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_NV_blend_square",
-   NULL
+    { "GL_ARB_multisample",                GL_ARB_multisample_functions },
+    { "GL_ARB_multitexture",               NULL },
+    { "GL_ARB_point_parameters",           GL_ARB_point_parameters_functions },
+    { "GL_ARB_texture_env_add",            NULL },
+    { "GL_ARB_texture_env_combine",        NULL },
+/*    { "GL_ARB_texture_env_dot3",           NULL }, */
+    { "GL_ARB_texture_mirrored_repeat",    NULL },
+    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
+    { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
+    { "GL_EXT_stencil_wrap",               NULL },
+    { "GL_EXT_texture_env_combine",        NULL },
+/*    { "GL_EXT_texture_env_dot3",           NULL }, */
+    { "GL_EXT_texture_lod_bias",           NULL },
+    { "GL_NV_blend_square",                NULL },
+    { NULL,                                NULL }
 };
 
 extern const struct tnl_pipeline_stage _via_fastrender_stage;
@@ -303,7 +397,7 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
     &_tnl_texgen_stage,
     &_tnl_texture_transform_stage,
     /* REMOVE: point attenuation stage */
-#if 0
+#if 1
     &_via_fastrender_stage,     /* ADD: unclipped rastersetup-to-dma */
 #endif
     &_tnl_render_stage,
@@ -311,75 +405,67 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
 };
 
 
-static GLboolean
-AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
+static const struct dri_debug_control debug_control[] =
 {
-    GLuint *addr;
+    { "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 }
+};
 
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+
+static GLboolean
+AllocateDmaBuffer(struct via_context *vmesa)
+{
     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;
-    }   
 
-    /* Insert placeholder for a cliprect:
-     */
-    addr = (GLuint *)vmesa->dma;
-    addr[0] = HC_HEADER2;
-    addr[1] = (HC_ParaType_NotTex << 16);
-    addr[2] = HC_DUMMY;
-    addr[3] = HC_DUMMY;
-    addr[4] = HC_DUMMY;
-    addr[5] = HC_DUMMY;
-    addr[6] = HC_DUMMY;
-    addr[7] = HC_DUMMY;
-
-    vmesa->dmaLow = DMA_OFFSET;
-    vmesa->dmaAddr = (unsigned char *)vmesa->dma;
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+    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->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,
+viaCreateContext(const __GLcontextModes *visual,
                  __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 *)
@@ -387,11 +473,10 @@ 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;
     }
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
 
     /* Parse configuration files.
      */
@@ -399,9 +484,9 @@ viaCreateContext(const __GLcontextModes *mesaVis,
                         sPriv->myNum, "via");
 
     /* pick back buffer */
-    vmesa->hasBack = mesaVis->doubleBufferMode;
+    vmesa->hasBack = visual->doubleBufferMode;
 
-    switch(mesaVis->depthBits) {
+    switch(visual->depthBits) {
     case 0:                    
        vmesa->hasDepth = GL_FALSE;
        vmesa->depthBits = 0; 
@@ -409,52 +494,59 @@ viaCreateContext(const __GLcontextModes *mesaVis,
        break;
     case 16:
        vmesa->hasDepth = GL_TRUE;
-       vmesa->depthBits = mesaVis->depthBits;
+       vmesa->depthBits = visual->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->depthBits = visual->depthBits;
        vmesa->depth_max = (GLfloat) 0xffffff;
        vmesa->depth_clear_mask = 0xe << 28;
        vmesa->ClearDepth = 0xffffff00;
 
-       assert(mesaVis->haveStencilBuffer);
-       assert(mesaVis->stencilBits == 8);
+       assert(visual->haveStencilBuffer);
+       assert(visual->stencilBits == 8);
 
        vmesa->have_hw_stencil = GL_TRUE;
-       vmesa->stencilBits = mesaVis->stencilBits;
+       vmesa->stencilBits = visual->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->depthBits = visual->depthBits;
+       assert(!visual->haveStencilBuffer);
        vmesa->have_hw_stencil = GL_FALSE;
        vmesa->depth_max = (GLfloat)0xffffffff;
-       vmesa->depth_clear_mask = 0;
-       vmesa->ClearDepth = 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(visual, shareCtx, &functions,
+                                       (void*) vmesa);
     
     vmesa->shareCtx = shareCtx;
     
@@ -519,48 +611,55 @@ viaCreateContext(const __GLcontextModes *mesaVis,
     vmesa->viaScreen = viaScreen;
     vmesa->driScreen = sPriv;
     vmesa->sarea = saPriv;
-    vmesa->glBuffer = NULL;
 
-    vmesa->texHeap = mmInit(0, viaScreen->textureSize);
     vmesa->renderIndex = ~0;
+    vmesa->setupIndex = ~0;
+    vmesa->hwPrimitive = GL_POLYGON+1;
+
+    /* KW: Hardwire this.  Was previously set bogusly in
+     * viaCreateBuffer.  Needs work before PBUFFER can be used:
+     */
+    vmesa->drawType = GLX_WINDOW_BIT;
 
-    make_empty_list(&vmesa->TexObjList);
-    make_empty_list(&vmesa->SwappedOut);
 
-    vmesa->CurrentTexObj[0] = 0;
-    vmesa->CurrentTexObj[1] = 0;
-    
     _math_matrix_ctr(&vmesa->ViewportMatrix);
 
     /* Do this early, before VIA_FLUSH_DMA can be called:
      */
-    if (!AllocateDmaBuffer(mesaVis, vmesa)) {
+    if (!AllocateDmaBuffer(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);
         
-#ifdef DEBUG
     if (getenv("VIA_DEBUG"))
-       VIA_DEBUG = 1;
-    else
-       VIA_DEBUG = 0;  
-#endif 
+       VIA_DEBUG = driParseDebugString( getenv( "VIA_DEBUG" ),
+                                       debug_control );
 
     if (getenv("VIA_NO_RAST"))
        FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
 
-       
-
     /* I don't understand why this isn't working:
      */
     vmesa->vblank_flags =
@@ -569,122 +668,129 @@ viaCreateContext(const __GLcontextModes *mesaVis,
 
     /* Hack this up in its place:
      */
-    vmesa->vblank_flags = getenv("VIA_VSYNC") ? VBLANK_FLAG_SYNC : VBLANK_FLAG_NO_IRQ;
+    vmesa->vblank_flags = (getenv("VIA_VSYNC") ? 
+                          VBLANK_FLAG_SYNC : VBLANK_FLAG_NO_IRQ);
 
-    
-    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 );
+    if (getenv("VIA_PAGEFLIP"))
+       vmesa->allowPageFlip = 1;
+
+    (*dri_interface->getUST)( &vmesa->swap_ust );
 
 
-    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->regMMIOBase = (GLuint *)((unsigned long)viaScreen->reg);
+    vmesa->pnGEMode = (GLuint *)((unsigned long)viaScreen->reg + 0x4);
+    vmesa->regEngineStatus = (GLuint *)((unsigned long)viaScreen->reg + 0x400);
+    vmesa->regTranSet = (GLuint *)((unsigned long)viaScreen->reg + 0x43C);
+    vmesa->regTranSpace = (GLuint *)((unsigned long)viaScreen->reg + 0x440);
     vmesa->agpBase = viaScreen->agpBase;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "regEngineStatus = %x\n", *vmesa->regEngineStatus);
-    }
-    
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+
+
     return GL_TRUE;
 }
 
 void
 viaDestroyContext(__DRIcontextPrivate *driContextPriv)
 {
-    viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+    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 */
 
+    /* check if we're deleting the currently bound context */
+    if (vmesa == current) {
+      VIA_FLUSH_DMA(vmesa);
+      _mesa_make_current(NULL, NULL, NULL);
+    }
+
     if (vmesa) {
-       /*=* John Sheng [2003.5.31]  agp tex *=*/
-        WAIT_IDLE(vmesa);
-       if(VIA_DEBUG) fprintf(stderr, "agpFullCount = %d\n", vmesa->agpFullCount);    
+        viaWaitIdle(vmesa, GL_FALSE);
+       if (vmesa->doPageFlip) {
+          LOCK_HARDWARE(vmesa);
+          if (vmesa->pfCurrentOffset != 0) {
+             fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+             viaResetPageFlippingLocked(vmesa);
+          }
+          UNLOCK_HARDWARE(vmesa);
+       }
        
        _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;
-        FREE(vmesa);
-    }
-    
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-}
-
-void viaXMesaSetFrontClipRects(viaContextPtr vmesa)
-{
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-
-    if (!dPriv)
-       return;
+       /* release our data */
+       FreeBuffer(vmesa);
 
-    vmesa->numClipRects = dPriv->numClipRects;
-    vmesa->pClipRects = dPriv->pClipRects;
-    vmesa->drawX = dPriv->x;
-    vmesa->drawY = dPriv->y;
-    vmesa->drawW = dPriv->w;
-    vmesa->drawH = dPriv->h;
+       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));
 
-    {
-       GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-       vmesa->drawXoff = (GLuint)(((vmesa->drawX * bytePerPixel) & 0x1f) / bytePerPixel);  
+        FREE(vmesa);
     }
-
-    viaCalcViewport(vmesa->glCtx);
 }
 
-void viaXMesaSetBackClipRects(viaContextPtr vmesa)
+
+void viaXMesaWindowMoved(struct via_context *vmesa)
 {
    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+   GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
 
    if (!dPriv)
       return;
+   
+   switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
+   case BUFFER_BIT_BACK_LEFT: 
+      if (dPriv->numBackClipRects == 0) {
+        vmesa->numClipRects = dPriv->numClipRects;
+        vmesa->pClipRects = dPriv->pClipRects;
+      } 
+      else {
+        vmesa->numClipRects = dPriv->numBackClipRects;
+        vmesa->pClipRects = dPriv->pBackClipRects;
+      }
+      break;
+   case BUFFER_BIT_FRONT_LEFT:
+      vmesa->numClipRects = dPriv->numClipRects;
+      vmesa->pClipRects = dPriv->pClipRects;
+      break;
+   default:
+      vmesa->numClipRects = 0;
+      break;
+   }
 
-   /*=* John Sheng [2003.6.9] fix glxgears dirty screen */
-   vmesa->numClipRects = dPriv->numClipRects;
-   vmesa->pClipRects = dPriv->pClipRects;
-   vmesa->drawX = dPriv->x;
+   if (vmesa->drawW != dPriv->w ||
+       vmesa->drawH != dPriv->h) 
+      calculate_buffer_parameters( vmesa, vmesa->glCtx->DrawBuffer );
+
+   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->drawXoff = 0; 
-
-    viaCalcViewport(vmesa->glCtx);
-}
-
-void viaXMesaWindowMoved(viaContextPtr vmesa)
-{
+   vmesa->front.origMap = (vmesa->front.map + 
+                          vmesa->drawY * vmesa->front.pitch + 
+                          vmesa->drawX * bytePerPixel);
 
-    switch (vmesa->glCtx->Color._DrawDestMask[0]) {
-    case DD_FRONT_LEFT_BIT: 
-        viaXMesaSetFrontClipRects(vmesa);
-        break;
-    case DD_BACK_LEFT_BIT:
-        viaXMesaSetBackClipRects(vmesa);
-        break;
-    default:
-        viaXMesaSetFrontClipRects(vmesa);
-        break;
-    }
+   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)
 {
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
     return GL_TRUE;
 }
 
@@ -693,73 +799,74 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
                __DRIdrawablePrivate *driDrawPriv,
                __DRIdrawablePrivate *driReadPriv)
 {
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-  
-    if (VIA_DEBUG) {
-       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driContextPriv);
-       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driDrawPriv);    
-       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driReadPriv);
+    if (VIA_DEBUG & DEBUG_DRI) {
+       fprintf(stderr, "driContextPriv = %016lx\n", (unsigned long)driContextPriv);
+       fprintf(stderr, "driDrawPriv = %016lx\n", (unsigned long)driDrawPriv);    
+       fprintf(stderr, "driReadPriv = %016lx\n", (unsigned long)driReadPriv);
     }  
 
     if (driContextPriv) {
-        viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
+        struct via_context *vmesa = 
+          (struct via_context *)driContextPriv->driverPrivate;
        GLcontext *ctx = vmesa->glCtx;
+        struct gl_framebuffer *drawBuffer, *readBuffer;
 
-       if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", vmesa->driDrawable->w);
+        drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
+        readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
 
        if ( vmesa->driDrawable != driDrawPriv ) {
-          driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags );
+          driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags,
+                                 &vmesa->vbl_seq );
           vmesa->driDrawable = driDrawPriv;
-          if ( ! calculate_buffer_parameters( vmesa ) ) {
+          if ( ! calculate_buffer_parameters( vmesa, drawBuffer ) ) {
              return GL_FALSE;
           }
-          ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
        }
 
-        _mesa_make_current2(vmesa->glCtx,
-                            (GLframebuffer *)driDrawPriv->driverPrivate,
-                            (GLframebuffer *)driReadPriv->driverPrivate);
-       if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext);
-        viaXMesaWindowMoved(vmesa);
-
+        _mesa_make_current(vmesa->glCtx, drawBuffer, readBuffer);
 
+       ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
+          
+        viaXMesaWindowMoved(vmesa);
+       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);
+        _mesa_make_current(NULL, NULL, NULL);
     }
         
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
     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;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "%s - in\n", __FUNCTION__);  
-       fprintf(stderr, "is: %x non-contend: %x want: %x\n",
-              *(GLuint *)vmesa->driHwLock, vmesa->hHWContext, 
-              (DRM_LOCK_HELD|vmesa->hHWContext));
-    }
 
     drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
 
     DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
 
-    if (sarea->ctxOwner != me) {
-        sarea->ctxOwner = me;
-       vmesa->newState = ~0;
+    if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
+       vmesa->sarea->ctxOwner = vmesa->hHWContext;
+       vmesa->newEmitState = ~0;
+    }
+
+    if (vmesa->lastStamp != dPriv->lastStamp) {
+       viaXMesaWindowMoved(vmesa);
+       driUpdateFramebufferSize(vmesa->glCtx, dPriv);
+       vmesa->newEmitState = ~0;
+       vmesa->lastStamp = dPriv->lastStamp;
     }
 
-    viaXMesaWindowMoved(vmesa);
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+    if (vmesa->doPageFlip &&
+       vmesa->pfCurrentOffset != vmesa->sarea->pfCurrentOffset) {
+       fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+       viaResetPageFlippingLocked(vmesa);
+    }
 }
 
 
@@ -767,15 +874,17 @@ void
 viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
 {
     __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
-    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;
+
+       _mesa_notifySwapBuffers(ctx);
+
         if (ctx->Visual.doubleBufferMode) {
-            _mesa_notifySwapBuffers(ctx);
             if (vmesa->doPageFlip) {
                 viaPageFlip(dPriv);
             }
@@ -789,5 +898,4 @@ viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
     else {
         _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
     }
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
 }