Simplfy clear() and swapbuffers() code.
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 29 Dec 2004 20:46:27 +0000 (20:46 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Wed, 29 Dec 2004 20:46:27 +0000 (20:46 +0000)
Fix various mishandling of cliprects.
Allow multiple primitives to be emitted to a single dma buffer, which
was largely impossible previously.
Re-enable the fast unclipped render stage.

src/mesa/drivers/dri/unichrome/via_context.c
src/mesa/drivers/dri/unichrome/via_context.h
src/mesa/drivers/dri/unichrome/via_fb.c
src/mesa/drivers/dri/unichrome/via_fb.h
src/mesa/drivers/dri/unichrome/via_ioctl.c
src/mesa/drivers/dri/unichrome/via_ioctl.h
src/mesa/drivers/dri/unichrome/via_span.c
src/mesa/drivers/dri/unichrome/via_state.c
src/mesa/drivers/dri/unichrome/via_tris.c
src/mesa/drivers/dri/unichrome/via_vb.c

index 9879a88e57abc53c0ec740482411c3935bf6c4f4..b6c2c37aeddc7e0b5d863351b336597d7a8a17bb 100644 (file)
 #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.
@@ -169,79 +137,92 @@ buffer_align( unsigned width )
 static GLboolean
 calculate_buffer_parameters( viaContextPtr vmesa )
 {
-    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;
 
-       vmesa->front.offset = 0;
-       vmesa->front.map = (char *) vmesa->driScreen->pFB;
-    }
+   /* Allocate front-buffer */
+   if (vmesa->drawType == GLX_PBUFFER_BIT) {
+      w = vmesa->driDrawable->w;
+      h = vmesa->driDrawable->h;
 
-    vmesa->front.pitch = buffer_align( w ) << shift;
-    vmesa->front.size = vmesa->front.pitch * 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;
 
-    /* Allocate back-buffer */
+   }
+   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;
+      vmesa->front.offset = 0;
+      vmesa->front.map = (char *) vmesa->driScreen->pFB;
+   }
 
-    vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift) 
-      + extra;
-    vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
 
-    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 back-buffer */
+   if (vmesa->hasBack) {
+      vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel;
+      vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift) + extra;
+      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 {
+      /* KW: mem leak if vmesa->hasBack ever changes:
+       */
+      (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;
-    }
-    else {
-       (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
-    }
+   /* 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 (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);
+      if (vmesa->depth.map)
+        via_free_draw_buffer(vmesa, &vmesa->depth);
+      if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) {
+        return GL_FALSE;
+      }
+   }
+   else {
+      /* KW: mem leak if vmesa->hasStencil/hasDepth ever changes:
+       */
+      (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
+   }
 
-    /*=* John Sheng [2003.5.31] flip *=*/
-    if( vmesa->viaScreen->width == vmesa->driDrawable->w && 
-       vmesa->viaScreen->height == vmesa->driDrawable->h ) {
+   /*=* 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;
+      vmesa->doPageFlip = GL_TRUE;
 #else
-       vmesa->doPageFlip = GL_FALSE;
+      vmesa->doPageFlip = GL_FALSE;
 #endif
-       vmesa->currentPage = 0;
-       vmesa->back.pitch = vmesa->front.pitch;
-    }
+      /* vmesa->currentPage = 0; */
+      assert(vmesa->back.pitch == vmesa->front.pitch);
+   }
+   else
+      vmesa->doPageFlip = GL_FALSE;
 
-    if (!AllocateBuffer(vmesa)) {
-       FREE(vmesa);
-       return GL_FALSE;
-    }
-    
-    return GL_TRUE;
+   return GL_TRUE;
 }
 
 
@@ -250,20 +231,8 @@ void viaReAllocateBuffers(GLframebuffer *drawbuffer)
     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;
-
-    LOCK_HARDWARE(vmesa);
+    _swrast_alloc_buffers( drawbuffer );
     calculate_buffer_parameters( vmesa );
-    UNLOCK_HARDWARE(vmesa);
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
 }
 
 static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
@@ -303,9 +272,7 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
     &_tnl_texgen_stage,
     &_tnl_texture_transform_stage,
     /* REMOVE: point attenuation stage */
-#if 0
     &_via_fastrender_stage,     /* ADD: unclipped rastersetup-to-dma */
-#endif
     &_tnl_render_stage,
     0,
 };
@@ -314,39 +281,14 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
 static GLboolean
 AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
 {
-    GLuint *addr;
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
     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;
 }
 
@@ -354,13 +296,13 @@ static void
 FreeBuffer(viaContextPtr vmesa)
 {
     if (vmesa->front.map)
-       via_free_front_buffer(vmesa);
+       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)
         via_free_dma_buffer(vmesa);
@@ -536,6 +478,7 @@ viaCreateContext(const __GLcontextModes *mesaVis,
      */
     if (!AllocateDmaBuffer(mesaVis, vmesa)) {
        fprintf(stderr ,"AllocateDmaBuffer fail\n");
+       FreeBuffer(vmesa);
         FREE(vmesa);
         return GL_FALSE;
     }
@@ -576,7 +519,7 @@ viaCreateContext(const __GLcontextModes *mesaVis,
     if ( vmesa->get_ust == NULL ) {
        vmesa->get_ust = get_ust_nop;
     }
-    (*vmesa->get_ust)( & vmesa->swap_ust );
+    vmesa->get_ust( &vmesa->swap_ust );
 
 
     vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
@@ -620,64 +563,59 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv)
     if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
 }
 
-void viaXMesaSetFrontClipRects(viaContextPtr vmesa)
-{
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-
-    if (!dPriv)
-       return;
-
-    vmesa->numClipRects = dPriv->numClipRects;
-    vmesa->pClipRects = dPriv->pClipRects;
-    vmesa->drawX = dPriv->x;
-    vmesa->drawY = dPriv->y;
-    vmesa->drawW = dPriv->w;
-    vmesa->drawH = dPriv->h;
-
-    {
-       GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-       vmesa->drawXoff = (GLuint)(((vmesa->drawX * bytePerPixel) & 0x1f) / bytePerPixel);  
-    }
-
-    viaCalcViewport(vmesa->glCtx);
-}
 
-void viaXMesaSetBackClipRects(viaContextPtr vmesa)
+void viaXMesaWindowMoved(viaContextPtr vmesa)
 {
    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+   GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
 
    if (!dPriv)
       return;
 
-   /*=* John Sheng [2003.6.9] fix glxgears dirty screen */
-   vmesa->numClipRects = dPriv->numClipRects;
-   vmesa->pClipRects = dPriv->pClipRects;
-   vmesa->drawX = dPriv->x;
+   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->drawXoff = 0; 
+   vmesa->front.origMap = (vmesa->front.map + 
+                          vmesa->drawY * vmesa->front.pitch + 
+                          vmesa->drawX * bytePerPixel);
 
-    viaCalcViewport(vmesa->glCtx);
-}
-
-void viaXMesaWindowMoved(viaContextPtr vmesa)
-{
-
-    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
@@ -736,30 +674,20 @@ void viaGetLock(viaContextPtr 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->newState = ~0;
     }
 
-    viaXMesaWindowMoved(vmesa);
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+    if (vmesa->lastStamp != dPriv->lastStamp) {
+       viaXMesaWindowMoved(vmesa);
+       vmesa->lastStamp = dPriv->lastStamp;
+    }
 }
 
 
@@ -768,7 +696,7 @@ viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
 {
     __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
     if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
-    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+    if (dPriv && dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
         viaContextPtr vmesa;
         GLcontext *ctx;
        
index 10d4777762289e951d1af36d1a81b04d9f79b10b..995e20698ec877f7206097242ff53d1d8a9eb5e4 100644 (file)
@@ -52,9 +52,12 @@ typedef struct via_texture_object_t *viaTextureObjectPtr;
 #define VIA_FALLBACK_BLEND_FUNC                0x400
 #define VIA_FALLBACK_USER_DISABLE              0x800
 
-#define VIA_DMA_BUFSIZ                  500000
+#define VIA_DMA_BUFSIZ                  5000
 #define VIA_DMA_HIGHWATER               (VIA_DMA_BUFSIZ - 256)
 
+#define VIA_NO_CLIPRECTS 0x1
+
+
 /* Use the templated vertex formats:
  */
 #define TAG(x) via##x
@@ -74,6 +77,10 @@ typedef struct {
     GLuint pitch;
     GLuint bpp;
     char *map;
+    GLuint orig;               /* The drawing origin, 
+                                * at (drawX,drawY) in screen space.
+                                */
+    char *origMap;
 } viaBuffer, *viaBufferPtr;
 
 
@@ -81,7 +88,6 @@ struct via_context_t {
     GLint refcount;   
     GLcontext *glCtx;
     GLcontext *shareCtx;
-    unsigned char* front_base;
     viaBuffer front;
     viaBuffer back;
     viaBuffer depth;
@@ -98,7 +104,7 @@ struct via_context_t {
    GLuint stencil_clear_mask;
    GLfloat depth_max;
 
-    GLuint    *dma;
+    GLubyte    *dma;
     viaRegion tex;
     
     GLuint isAGP;
@@ -127,8 +133,8 @@ struct via_context_t {
 
     /* drmBufPtr dma_buffer;
     */
-    unsigned char* dmaAddr;
     GLuint dmaLow;
+    GLuint dmaCliprectAddr;
     GLuint dmaLastPrim;
     GLboolean useAgp;
    
@@ -202,7 +208,6 @@ struct via_context_t {
     int vertexSize;
     int vertexFormat;
     GLint lastStamp;
-    GLboolean stippleInHw;
 
     GLenum TexEnvImageFmt[2];
     GLuint ClearColor;
@@ -213,16 +218,15 @@ struct via_context_t {
     GLboolean doPageFlip;
     /*=* John Sheng [2003.5.31] flip *=*/
     GLuint currentPage;
-    char *drawMap;               /* draw buffer address in virtual mem */
-    char *readMap;       
+
+    viaBuffer *drawBuffer;
+    viaBuffer *readBuffer;
     int drawX;                   /* origin of drawable in draw buffer */
     int drawY;
     
     int drawW;                  
     int drawH;
     
-    int drawPitch;
-    int readPitch;
     int drawXoff;
     GLuint numClipRects;         /* cliprects for that buffer */
     drm_clip_rect_t *pClipRects;
@@ -325,6 +329,8 @@ extern void viaXMesaWindowMoved(viaContextPtr vmesa);
 extern void viaTexCombineState(viaContextPtr vmesa,
     const struct gl_tex_env_combine_state * combine, unsigned unit );
 
+/* Via hw already adjusted for GL pixel centers:
+ */
 #define SUBPIXEL_X 0
 #define SUBPIXEL_Y 0
 
index cf4eadc58db0a0ebfaa1635144db0f1635418fcf..39d43e7278497274179f955fa12910e51cbff6e1 100644 (file)
 #include <sys/ioctl.h>
 
 GLboolean
-via_alloc_back_buffer(viaContextPtr vmesa)
+via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
 {
-    drm_via_mem_t fb;
-    unsigned char *pFB;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-    fb.context = vmesa->hHWContext;
-    fb.size = vmesa->back.size;
-    fb.type = VIDEO;
-    if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
-    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
-        return GL_FALSE;
-    
-    pFB = vmesa->driScreen->pFB;
-    
-    vmesa->back.offset = fb.offset;
-    vmesa->back.map = (char *)(fb.offset + (GLuint)pFB);
-    vmesa->back.index = fb.index;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "back offset = %08x\n", vmesa->back.offset);
-       fprintf(stderr, "back index = %d\n", vmesa->back.index);
-    }
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-    return GL_TRUE;
-}
+   drm_via_mem_t mem;
+   mem.context = vmesa->hHWContext;
+   mem.size = buf->size;
+   mem.type = VIDEO;
 
-GLboolean
-via_alloc_front_buffer(viaContextPtr vmesa)
-{
-    drm_via_mem_t fb;
-    unsigned char *pFB;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-    fb.context = vmesa->hHWContext;
-    fb.size = vmesa->back.size;
-    fb.type = VIDEO;
-    if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
-    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
-        return GL_FALSE;
+   if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &mem)) 
+      return GL_FALSE;
     
-    pFB = vmesa->driScreen->pFB;
     
-    vmesa->front.offset = fb.offset;
-    vmesa->front.map = (char *)(fb.offset + (GLuint)pFB);
-    vmesa->front.index = fb.index;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "front offset = %08x\n", vmesa->front.offset);
-       fprintf(stderr, "front index = %d\n", vmesa->front.index);
-    }
-
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
-    return GL_TRUE;
-}
-
-void
-via_free_back_buffer(viaContextPtr vmesa)
-{
-    drm_via_mem_t fb;
-
-    if (!vmesa) return;
-    fb.context = vmesa->hHWContext;
-    fb.index = vmesa->back.index;
-    fb.type = VIDEO;
-    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
-    vmesa->back.map = NULL;
+   buf->offset = mem.offset;
+   buf->map = (char *)vmesa->driScreen->pFB + mem.offset;
+   buf->index = mem.index;
+   return GL_TRUE;
 }
 
 void
-via_free_front_buffer(viaContextPtr vmesa)
+via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
 {
-    drm_via_mem_t fb;
-
-    if (!vmesa) return;
-    fb.context = vmesa->hHWContext;
-    fb.index = vmesa->front.index;
-    fb.type = VIDEO;
-    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
-    vmesa->front.map = NULL;
-}
-
-GLboolean
-via_alloc_depth_buffer(viaContextPtr vmesa)
-{
-    drm_via_mem_t fb;
-    unsigned char *pFB;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
-    fb.context = vmesa->hHWContext;
-    fb.size = vmesa->depth.size;
-    fb.type = VIDEO;
+   drm_via_mem_t mem;
 
-    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
-       return GL_FALSE;
-    }
-
-    pFB = vmesa->driScreen->pFB;
-    
-    vmesa->depth.offset = fb.offset;
-    vmesa->depth.map = (char *)(fb.offset + (GLuint)pFB);
-    vmesa->depth.index = fb.index;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "depth offset = %08x\n", vmesa->depth.offset);
-       fprintf(stderr, "depth index = %d\n", vmesa->depth.index);    
-    }  
+   if (!vmesa) return;
 
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-    return GL_TRUE;
+   mem.context = vmesa->hHWContext;
+   mem.index = buf->index;
+   mem.type = VIDEO;
+   ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &mem);
+   buf->map = NULL;
 }
 
-void
-via_free_depth_buffer(viaContextPtr vmesa)
-{
-    drm_via_mem_t fb;
-       
-    if (!vmesa) return;
-    fb.context = vmesa->hHWContext;
-    fb.index = vmesa->depth.index;
-    fb.type = VIDEO;
-    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
-    vmesa->depth.map = NULL;
-}
 
 GLboolean
 via_alloc_dma_buffer(viaContextPtr vmesa)
@@ -158,7 +69,7 @@ via_alloc_dma_buffer(viaContextPtr vmesa)
    drmVIADMAInit init;
 
    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-   vmesa->dma = (GLuint *) malloc(VIA_DMA_BUFSIZ);
+   vmesa->dma = (GLubyte *) malloc(VIA_DMA_BUFSIZ);
     
    /*
     * Check whether AGP DMA has been initialized.
index c4378c2469abf0b65353c1ff4a9cc249ff550348..23fc861459f21b0925040ed5182cadf9f23f33b2 100644 (file)
 #ifndef _VIAFB_INC
 #define _VIAFB_INC
 
-#include "mtypes.h"
-#include "swrast/swrast.h"
-extern GLboolean via_alloc_front_buffer(viaContextPtr vmesa);
-extern GLboolean via_alloc_back_buffer(viaContextPtr vmesa);
-extern void via_free_back_buffer(viaContextPtr vmesa);
-extern void via_free_front_buffer(viaContextPtr vmesa);
-extern GLboolean via_alloc_depth_buffer(viaContextPtr vmesa);
-extern void via_free_depth_buffer(viaContextPtr vmesa);
+#include "via_context.h"
+
+extern GLboolean via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf);
 extern GLboolean via_alloc_dma_buffer(viaContextPtr vmesa);
-extern void via_free_dma_buffer(viaContextPtr vmesa);
 extern GLboolean via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
-/*=* John Sheng [2003.5.31]  agp tex *=*/
 extern GLboolean via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t);
+
+extern void via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf);
+extern void via_free_dma_buffer(viaContextPtr vmesa);
 extern void via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
 #endif
index 431a26b2a94bb99ddff11a96933d5ebaef474a97..55220f18f6f2f39b085c83d0642db4f9936fe91d 100644 (file)
@@ -73,14 +73,127 @@ v * copy of this software and associated documentation files (the "Software"),
 #define VIA_BLIT_SET 0xFF
 
  
-#define DEPTH_SCALE ((1 << 16) - 1)
-
 void viaCheckDma(viaContextPtr vmesa, GLuint bytes)
 {
     VIA_FINISH_PRIM( vmesa );
     if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
-       viaFlushPrims(vmesa);
+       viaFlushDma(vmesa);
+    }
+}
+
+
+
+#define SetReg2DAGP(nReg, nData) do {          \
+    OUT_RING( ((nReg) >> 2) | 0xF0000000 );    \
+    OUT_RING( nData );                         \
+} while (0)
+
+
+static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
+                   GLuint srcPitch,GLuint dstBase,GLuint dstPitch,
+                   GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode, 
+                   GLuint color, GLuint nMask ) 
+{
+
+    GLuint dwGEMode = 0, srcY=0, srcX, dstY=0, dstX;
+    GLuint cmd;
+    RING_VARS;
+
+    if (VIA_DEBUG)
+       fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d dir %d,%d mode: %x color: 0x%08x mask 0x%08x\n",
+              __FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, xdir, ydir, blitMode, color, nMask);
+
+
+    if (!w || !h)
+        return;
+
+    srcX = srcBase & 31;
+    dstX = dstBase & 31;
+    switch (bpp) {
+    case 16:
+        dwGEMode |= VIA_GEM_16bpp;
+       srcX >>= 1;
+       dstX >>= 1;
+        break;
+    case 32:
+        dwGEMode |= VIA_GEM_32bpp;
+       srcX >>= 2;
+       dstX >>= 2;
+       break;
+    default:
+        dwGEMode |= VIA_GEM_8bpp;
+        break;
     }
+
+
+    cmd = 0; 
+
+    if (xdir < 0) {
+        cmd |= VIA_GEC_DECX;
+        srcX += (w - 1);
+        dstX += (w - 1);
+    }
+    if (ydir < 0) {
+        cmd |= VIA_GEC_DECY;
+        srcY += (h - 1);
+        dstY += (h - 1);
+    }
+
+    switch(blitMode) {
+    case VIA_BLIT_FILL:
+        BEGIN_RING((2 + 9) * 2);
+       SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
+       SetReg2DAGP( VIA_REG_FGCOLOR, color);
+       cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
+       break;
+    case VIA_BLIT_COPY:
+        BEGIN_RING((2 + 9) * 2);
+       SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
+       SetReg2DAGP( VIA_REG_KEYCONTROL, 0x0);
+       cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
+    }  
+
+    SetReg2DAGP( 0x2C, nMask);
+    SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~31) >> 3);
+    SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~31) >> 3);
+    SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE |
+              (srcPitch >> 3) | (((dstPitch) >> 3) << 16));
+    SetReg2DAGP( VIA_REG_SRCPOS, ((srcY << 16) | srcX));
+    SetReg2DAGP( VIA_REG_DSTPOS, ((dstY << 16) | dstX));
+    SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
+    SetReg2DAGP( VIA_REG_GECMD, cmd);
+    SetReg2DAGP( 0x2C, 0x00000000);
+    ADVANCE_RING();
+}
+
+static void viaFillBuffer(viaContextPtr vmesa,
+                         viaBuffer *buffer,
+                         drm_clip_rect_t *pbox,
+                         int nboxes,
+                         GLuint pixel,
+                         GLuint mask)
+{
+   GLuint bytePerPixel = buffer->bpp >> 3;
+   GLuint i;
+
+   for (i = 0; i < nboxes ; i++) {        
+      int x = pbox[i].x1 - vmesa->drawX;
+      int y = pbox[i].y1 - vmesa->drawY;
+      int w = pbox[i].x2 - pbox[i].x1;
+      int h = pbox[i].y2 - pbox[i].y1;
+
+      int offset = (buffer->orig + 
+                   y * buffer->pitch + 
+                   x * bytePerPixel);
+
+      viaBlit(vmesa,
+             buffer->bpp, 
+             offset, buffer->pitch,
+             offset, buffer->pitch, 
+             w, h,
+             0, 0, 
+             VIA_BLIT_FILL, pixel, mask); 
+   }
 }
 
 
@@ -133,73 +246,107 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
    }
     
    if (flag) {
+      drm_clip_rect_t *boxes, *tmp_boxes = 0;
+      int nr = 0;
+
       LOCK_HARDWARE(vmesa);
+           
       /* flip top to bottom */
       cy = dPriv->h - cy - ch;
-      cx += vmesa->drawX;
+      cx += vmesa->drawX + vmesa->drawXoff;
       cy += vmesa->drawY;
         
-      if (vmesa->numClipRects) {
-        int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects);
-        drm_clip_rect_t *box = vmesa->pClipRects;
-        drm_clip_rect_t *b = vmesa->sarea->boxes;
-        int n = 0;
-           
-        if (!all) {
-           for (; i < nr; i++) {
-              GLint x = box[i].x1;
-              GLint y = box[i].y1;
-              GLint w = box[i].x2 - x;
-              GLint h = box[i].y2 - y;
-
-              if (x < cx) w -= cx - x, x = cx;
-              if (y < cy) h -= cy - y, y = cy;
-              if (x + w > cx + cw) w = cx + cw - x;
-              if (y + h > cy + ch) h = cy + ch - y;
-              if (w <= 0) continue;
-              if (h <= 0) continue;
-
-              b->x1 = x;
-              b->y1 = y;
-              b->x2 = x + w;
-              b->y2 = y + h;
-              b++;
-              n++;
-           }
-        }
-        else {
-           for (; i < nr; i++) {
-              *b++ = *(drm_clip_rect_t *)&box[i];
-              n++;
-           }
+      if (!all) {
+        drm_clip_rect_t *b = vmesa->pClipRects;         
+        
+        boxes = tmp_boxes = (drm_clip_rect_t *)malloc(vmesa->numClipRects * 
+                                                      sizeof(drm_clip_rect_t)); 
+        if (!boxes) {
+           UNLOCK_HARDWARE(vmesa);
+           return;
         }
-        vmesa->sarea->nbox = n;                
 
+        for (; i < vmesa->numClipRects; i++) {
+           GLint x = b[i].x1;
+           GLint y = b[i].y1;
+           GLint w = b[i].x2 - x;
+           GLint h = b[i].y2 - y;
+
+           if (x < cx) w -= cx - x, x = cx;
+           if (y < cy) h -= cy - y, y = cy;
+           if (x + w > cx + cw) w = cx + cw - x;
+           if (y + h > cy + ch) h = cy + ch - y;
+           if (w <= 0) continue;
+           if (h <= 0) continue;
+
+           boxes[nr].x1 = x;
+           boxes[nr].y1 = y;
+           boxes[nr].x2 = x + w;
+           boxes[nr].y2 = y + h;
+           nr++;
+        }
+      }
+      else {
+        boxes = vmesa->pClipRects;
+        nr = vmesa->numClipRects;
       }
            
       if (flag & VIA_FRONT) {
-        if (vmesa->drawType == GLX_PBUFFER_BIT)
-           viaFillFrontPBuffer(vmesa);
-        else
-           viaFillFrontBuffer(vmesa);
+        viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor, 0);
       } 
                
       if (flag & VIA_BACK) {
-        viaFillBackBuffer(vmesa);
+        viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor, 0); /* FIXME: masks */
       }
 
       if (flag & VIA_DEPTH) {
-        viaFillDepthBuffer(vmesa, clear_depth, clear_depth_mask);
+        viaFillBuffer(vmesa, &vmesa->depth, boxes, nr, clear_depth, clear_depth_mask);
       }                
 
+      viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS);
       UNLOCK_HARDWARE(vmesa);
+
+      if (tmp_boxes)
+        free(tmp_boxes);
    }
    
    if (mask)
       _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
-   if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
 }
 
+
+
+
+static void viaDoSwapBuffers(viaContextPtr vmesa,
+                            drm_clip_rect_t *b,
+                            GLuint nbox)
+{    
+   GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+   viaBuffer *front = &vmesa->front;
+   viaBuffer *back = &vmesa->back;
+   GLuint i;
+        
+   for (i = 0; i < nbox; i++, b++) {        
+      GLint x = b->x1 - vmesa->drawX;
+      GLint y = b->y1 - vmesa->drawY;
+      GLint w = b->x2 - b->x1;
+      GLint h = b->y2 - b->y1;
+       
+      GLuint src = back->orig + y * back->pitch + x * bytePerPixel;
+      GLuint dest = front->orig + y * front->pitch + x * bytePerPixel;
+
+      viaBlit(vmesa, 
+             bytePerPixel << 3, 
+             src, back->pitch,
+             dest, front->pitch,
+             w, h,
+             0,0,VIA_BLIT_COPY, 0, 0); 
+   }
+}
+
+
+
+
 /*
  * Copy the back buffer to the front buffer. 
  */
@@ -207,29 +354,21 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
 {
    viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
    GLboolean missed_target;
-   int64_t ust;
 
    VIA_FLUSH_DMA(vmesa);
-
    driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target );
-
-   LOCK_HARDWARE(vmesa);
-   if (vmesa->drawType == GLX_PBUFFER_BIT) {
-      viaDoSwapPBuffers(vmesa);
-   }
-   else {
-      viaDoSwapBuffers(vmesa);
-   }
-   UNLOCK_HARDWARE(vmesa);
-
-   vmesa->swap_count++;
-   (*vmesa->get_ust)( & ust );
    if ( missed_target ) {
       vmesa->swap_missed_count++;
-      vmesa->swap_missed_ust = ust - vmesa->swap_ust;
+      vmesa->get_ust( &vmesa->swap_missed_ust );
    }
-    
-   vmesa->swap_ust = ust;
+   LOCK_HARDWARE(vmesa);
+
+   viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects);
+   viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS);
+
+   UNLOCK_HARDWARE(vmesa);
+   vmesa->swap_count++;
+   vmesa->get_ust( &vmesa->swap_ust );
 }
 
 /*
@@ -237,31 +376,17 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
  */
 void viaPageFlip(const __DRIdrawablePrivate *dPriv)
 {
-    /*=* John Sheng [2003.5.31] flip *=*/
     viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
-    GLcontext *ctx = vmesa->glCtx;
-    GLuint nBackBase;
     viaBuffer buffer_tmp;
     GLboolean missed_target;
-    int retcode;
-
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);        
-    assert(dPriv);
-    assert(dPriv->driContextPriv);
-    assert(dPriv->driContextPriv->driverPrivate);
 
 
     VIA_FLUSH_DMA(vmesa);
-
-    /* Now wait for the vblank:
-     */
-    retcode = driWaitForVBlank( dPriv, &vmesa->vbl_seq, 
-                               vmesa->vblank_flags, &missed_target );
+    driWaitForVBlank( dPriv, &vmesa->vbl_seq, vmesa->vblank_flags, &missed_target );
     if ( missed_target ) {
        vmesa->swap_missed_count++;
-       (void) (*vmesa->get_ust)( &vmesa->swap_missed_ust );
+       vmesa->get_ust( &vmesa->swap_missed_ust );
     }
-
     LOCK_HARDWARE(vmesa);
 
     {
@@ -276,49 +401,36 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
            OUT_RING(0x0000000e);
            ADVANCE_RING();
        }
-       nBackBase = (vmesa->back.offset );
 
        BEGIN_RING(4);
        OUT_RING( HALCYON_HEADER2 );
        OUT_RING( 0x00fe0000 );
-       OUT_RING((HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2);
+       OUT_RING((HC_SubA_HFBBasL << 24) | (vmesa->back.offset & 0xFFFFF8) | 0x2);
        OUT_RING((HC_SubA_HFBDrawFirst << 24) |
-                ((nBackBase & 0xFF000000) >> 24) | 0x0100);
+                ((vmesa->back.offset & 0xFF000000) >> 24) | 0x0100);
        ADVANCE_RING();
 
-       viaFlushPrimsLocked(vmesa);
     }
-    
-    UNLOCK_HARDWARE(vmesa);
 
+    viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS);    
+    UNLOCK_HARDWARE(vmesa);
     vmesa->swap_count++;
-    (void) (*vmesa->get_ust)( &vmesa->swap_ust );
-   
+    vmesa->get_ust( &vmesa->swap_ust );
+
+    /* KW: FIXME: When buffers are freed, could free frontbuffer by
+     * accident:
+     */
     memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer));
     memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer));
     memcpy(&vmesa->front, &buffer_tmp, sizeof(viaBuffer));
     
-    /* KW: BOGUS BOGUS BOGUS: The first time an app calls glDrawBuffer
-     * while pageflipping, this will blow up:  FIXME
-     */
     if(vmesa->currentPage) {
        vmesa->currentPage = 0;
-       if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
-               ctx->Driver.DrawBuffer(ctx, GL_BACK);
-       }
-       else {
-               ctx->Driver.DrawBuffer(ctx, GL_FRONT);
-       }
     }
     else {
        vmesa->currentPage = 1;
-       if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
-               ctx->Driver.DrawBuffer(ctx, GL_BACK);
-       }
-       else {
-               ctx->Driver.DrawBuffer(ctx, GL_FRONT);
-       }
     }
+
     if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
 }
 
@@ -327,13 +439,13 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
 
 #define VIA_CMDBUF_MAX_LAG 50000
 
-static int fire_buffer(viaContextPtr vmesa, drm_via_flush_sys_t *buf)
+static int fire_buffer(viaContextPtr vmesa)
 {
    drmVIACommandBuffer bufI;
    int ret;
 
-   bufI.buf = (char *) (buf->index + buf->offset);
-   bufI.size = buf->size;
+   bufI.buf = (char *)vmesa->dma;
+   bufI.size = vmesa->dmaLow;
 
    if (vmesa->useAgp) {
       drmVIACmdBufSize bSiz;
@@ -387,74 +499,40 @@ static int fire_buffer(viaContextPtr vmesa, drm_via_flush_sys_t *buf)
  * into the head of the DMA buffer being flushed.  Fires the buffer
  * for each cliprect.
  */
-static int via_flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf) 
+static void via_emit_cliprect(viaContextPtr vmesa,
+                             drm_clip_rect_t *b) 
 {
-   GLuint *vb = (GLuint *)vmesa->dmaAddr;
+   viaBuffer *buffer = vmesa->drawBuffer;
+   GLuint *vb = (GLuint *)(vmesa->dma + vmesa->dmaCliprectAddr);
+
    GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20 
                    ? HC_HDBFM_ARGB8888 
                    : HC_HDBFM_RGB565);
 
-   if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
-      GLuint offset = vmesa->back.offset;
-      GLuint pitch = vmesa->back.pitch;
+   GLuint pitch = buffer->pitch;
+   GLuint offset = buffer->orig;
 
-      vb[0] = HC_HEADER2;
-      vb[1] = HC_ParaType_NotTex << 16;
-         
-      if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
-        vb[2] = (HC_SubA_HClipTB << 24) | 0x0;
-        vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
-      }
-      else {
-        vb[2] = (HC_SubA_HClipTB << 24) | vmesa->driDrawable->h;
-        vb[3] = (HC_SubA_HClipLR << 24) | vmesa->driDrawable->w; 
-      }
-       
-      vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
-      vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); 
-      vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); 
-      vb[7] = 0xcccccccc;
+   GLuint clipL = b->x1 - vmesa->drawX;
+   GLuint clipR = b->x2 - vmesa->drawX;
+   GLuint clipT = b->y1 - vmesa->drawY;
+   GLuint clipB = b->y2 - vmesa->drawY;
+           
+   vb[0] = HC_HEADER2;
+   vb[1] = (HC_ParaType_NotTex << 16);
 
-      return fire_buffer( vmesa, buf );
+   if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+      vb[2] = (HC_SubA_HClipTB << 24) | 0x0;
+      vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
    }
    else {
-      GLuint i, ret;
-      drm_clip_rect_t *b = vmesa->sarea->boxes;
-               
-      for (i = 0; i < vmesa->sarea->nbox; i++, b++) {        
-        GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-        GLuint pitch = vmesa->front.pitch;
-        GLuint offset = (vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel)) & ~0x1f;
-
-        GLuint clipL = b->x1 + vmesa->drawXoff;
-        GLuint clipR = b->x2 + vmesa->drawXoff;
-        GLuint clipT = b->y1;
-        GLuint clipB = b->y2;
-           
-        vb[0] = HC_HEADER2;
-        vb[1] = (HC_ParaType_NotTex << 16);
-
-        if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
-           vb[2] = (HC_SubA_HClipTB << 24) | 0x0;
-           vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
-        }
-        else {
-           vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
-           vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
-        }
-           
-        vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
-        vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); 
-        vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
-        vb[7] = 0xcccccccc;
-
-        ret = fire_buffer( vmesa, buf );
-        if (ret)
-           return ret;
-      }
+      vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
+      vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
    }
-
-   return 0;
+           
+   vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+   vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); 
+   vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+   vb[7] = 0xcccccccc;
 }
 
 
@@ -476,12 +554,23 @@ static int intersect_rect(drm_clip_rect_t *out,
     return 1;
 }
 
-void viaFlushPrimsLocked(viaContextPtr vmesa)
+static void dump_dma( viaContextPtr vmesa )
+{
+   GLuint i;
+   GLuint *data = (GLuint *)vmesa->dma;
+   for (i = 0; i < vmesa->dmaLow; i += 16) {
+      fprintf(stderr, "%04x:   ", i);
+      fprintf(stderr, "%08x  ", *data++);
+      fprintf(stderr, "%08x  ", *data++);
+      fprintf(stderr, "%08x  ", *data++);
+      fprintf(stderr, "%08x\n", *data++);
+   }
+   fprintf(stderr, "******************************************\n");
+}
+
+
+void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags)
 {
-   drm_clip_rect_t *pbox = (drm_clip_rect_t *)vmesa->pClipRects;
-   int nbox = vmesa->numClipRects;
-   drm_via_sarea_t *sarea = vmesa->sarea;
-   drm_via_flush_sys_t sysCmd;
    int i;
    RING_VARS;
 
@@ -491,7 +580,7 @@ void viaFlushPrimsLocked(viaContextPtr vmesa)
       abort();
    }
 
-   if (vmesa->dmaLow == DMA_OFFSET) {
+   if (vmesa->dmaLow == 0) {
       return;
    }
 
@@ -543,94 +632,80 @@ void viaFlushPrimsLocked(viaContextPtr vmesa)
       if (VIA_DEBUG)
         fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n",
                 __FUNCTION__, vmesa->dmaLow);
-/*       abort(); */
-/*       goto done; */
    }
 
-/*    assert((vmesa->dmaLow & 0x1f) == 0); */
 
-   sysCmd.offset = 0x0;
-   sysCmd.size = vmesa->dmaLow;
-   sysCmd.index = (GLuint)vmesa->dma;
-   sysCmd.discard = 0;
-    
-   if (!nbox) {
-      sysCmd.size = 0;         /* KW: FIXME bogus if we ever start emitting partial state */
-      sarea->nbox = 0;
-      sysCmd.discard = 1;
-      via_flush_sys(vmesa, &sysCmd);
-   }
-   else {
-      for (i = 0; i < nbox; ) {
-        int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox);
-        drm_clip_rect_t *b = sarea->boxes;
+   if (VIA_DEBUG)
+      dump_dma( vmesa );
 
+   if (flags & VIA_NO_CLIPRECTS) {
+      assert(vmesa->dmaCliprectAddr == 0);
+      fire_buffer( vmesa );
+   }
+   else if (!vmesa->dmaCliprectAddr) {
+      /* Contains only state.  Could just dump the packet?
+       */
+      if (0) fprintf(stderr, "no dmaCliprectAddr\n");
+      if (0) fire_buffer( vmesa );
+   }
+   else if (vmesa->numClipRects) {
+      int ret;
+      drm_clip_rect_t *pbox = vmesa->pClipRects;
+      
+      for (i = 0; i < vmesa->numClipRects; i++) {
         if (vmesa->glCtx->Scissor.Enabled) {
-           sarea->nbox = 0;
-
-           for (; i < nr; i++) {
-              b->x1 = pbox[i].x1 - vmesa->drawX;
-              b->y1 = pbox[i].y1 - vmesa->drawY;
-              b->x2 = pbox[i].x2 - vmesa->drawX;
-              b->y2 = pbox[i].y2 - vmesa->drawY;
-              if (intersect_rect(b, b, &vmesa->scissorRect)) {
-                 sarea->nbox++;
-                 b++;
-              }
-           }
-           if (!sarea->nbox) {
-              if (nr < nbox) continue;
-              sysCmd.size = 0;
-           }
+           drm_clip_rect_t b;
+           if (!intersect_rect(&b, &pbox[i], &vmesa->scissorRect)) 
+              continue;
+           via_emit_cliprect(vmesa, &b);        
         }
         else {
-           sarea->nbox = nr - i;
-           for (; i < nr; i++, b++) {
-              b->x1 = pbox[i].x1 - vmesa->drawX;
-              b->y1 = pbox[i].y1 - vmesa->drawY;
-              b->x2 = pbox[i].x2 - vmesa->drawX;
-              b->y2 = pbox[i].y2 - vmesa->drawY;
-           }
+           via_emit_cliprect(vmesa, &pbox[i]);
         }
-
-        if (nr == nbox) {
-           sysCmd.discard = 1;
-        }
-
-        via_flush_sys(vmesa, &sysCmd);
+        
+        ret = fire_buffer(vmesa);
+        if (ret)
+           goto done;
       }
+   } else {
+      UNLOCK_HARDWARE(vmesa);
+      sched_yield();
+      LOCK_HARDWARE(vmesa);
    }
 
-   if (VIA_DEBUG) {
-      GLuint i;
-      GLuint *data = (GLuint *)vmesa->dmaAddr;
-      for (i = 0; i < vmesa->dmaLow; i += 16) {
-        fprintf(stderr, "%04x:   ", i);
-        fprintf(stderr, "%08x  ", *data++);
-        fprintf(stderr, "%08x  ", *data++);
-        fprintf(stderr, "%08x  ", *data++);
-        fprintf(stderr, "%08x\n", *data++);
-      }
-      fprintf(stderr, "******************************************\n");
-   }  
-
  done:
    /* Reset vmesa vars:
     */
-   vmesa->dmaLow = DMA_OFFSET;
-   vmesa->dmaAddr = (unsigned char *)vmesa->dma;
+   vmesa->dmaLow = 0;
+   vmesa->dmaCliprectAddr = 0;
+   viaValidateState(vmesa->glCtx);
 }
 
-void viaFlushPrims(viaContextPtr vmesa)
+void viaWrapPrimitive( viaContextPtr vmesa )
 {
-   if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+   if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__);
+   viaFinishPrimitive( vmesa );
+   
+   LOCK_HARDWARE(vmesa); 
+   viaFlushDmaLocked(vmesa, 0);
+   UNLOCK_HARDWARE(vmesa);
 
-   if (vmesa->dmaLow != DMA_OFFSET) {
-      LOCK_HARDWARE(vmesa); 
-      viaFlushPrimsLocked(vmesa);
-      UNLOCK_HARDWARE(vmesa);
+   viaRasterPrimitive( vmesa->glCtx,
+                      vmesa->renderPrimitive,
+                      vmesa->hwPrimitive );
+}
+
+void viaFlushDma(viaContextPtr vmesa)
+{
+   if (vmesa->dmaLow) {
+      if (vmesa->dmaLastPrim)
+        viaWrapPrimitive(vmesa); 
+      else {      
+        LOCK_HARDWARE(vmesa); 
+        viaFlushDmaLocked(vmesa, 0);
+        UNLOCK_HARDWARE(vmesa);
+      }
    }
-   if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
 }
 
 static void viaFlush(GLcontext *ctx)
@@ -660,315 +735,23 @@ void viaInitIoctlFuncs(GLcontext *ctx)
 }
 
 
-#define SetReg2DAGP(nReg, nData) do {          \
-    OUT_RING( ((nReg) >> 2) | 0xF0000000 );    \
-    OUT_RING( nData );                         \
-} while (0)
-
-
-static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
-                   GLuint srcPitch,GLuint dstBase,GLuint dstPitch,
-                   GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode, 
-                   GLuint color, GLuint nMask ) 
-{
-
-    GLuint dwGEMode = 0, srcY=0, srcX, dstY=0, dstX;
-    GLuint cmd;
-    RING_VARS;
-
-    if (VIA_DEBUG)
-       fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d dir %d,%d mode: %x color: 0x%08x mask 0x%08x\n",
-              __FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, xdir, ydir, blitMode, color, nMask);
-
-
-    if (!w || !h)
-        return;
-
-    srcX = srcBase & 31;
-    dstX = dstBase & 31;
-    switch (bpp) {
-    case 16:
-        dwGEMode |= VIA_GEM_16bpp;
-       srcX >>= 1;
-       dstX >>= 1;
-        break;
-    case 32:
-        dwGEMode |= VIA_GEM_32bpp;
-       srcX >>= 2;
-       dstX >>= 2;
-       break;
-    default:
-        dwGEMode |= VIA_GEM_8bpp;
-        break;
-    }
-
-
-    cmd = 0; 
-
-    if (xdir < 0) {
-        cmd |= VIA_GEC_DECX;
-        srcX += (w - 1);
-        dstX += (w - 1);
-    }
-    if (ydir < 0) {
-        cmd |= VIA_GEC_DECY;
-        srcY += (h - 1);
-        dstY += (h - 1);
-    }
-
-    switch(blitMode) {
-    case VIA_BLIT_FILL:
-        BEGIN_RING((2 + 9) * 2);
-       SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
-       SetReg2DAGP( VIA_REG_FGCOLOR, color);
-       cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
-       break;
-    case VIA_BLIT_COPY:
-        BEGIN_RING((2 + 9) * 2);
-       SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
-       SetReg2DAGP( VIA_REG_KEYCONTROL, 0x0);
-       cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
-    }  
-
-    SetReg2DAGP( 0x2C, nMask);
-    SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~31) >> 3);
-    SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~31) >> 3);
-    SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE |
-              (srcPitch >> 3) | (((dstPitch) >> 3) << 16));
-    SetReg2DAGP( VIA_REG_SRCPOS, ((srcY << 16) | srcX));
-    SetReg2DAGP( VIA_REG_DSTPOS, ((dstY << 16) | dstX));
-    SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
-    SetReg2DAGP( VIA_REG_GECMD, cmd);
-    SetReg2DAGP( 0x2C, 0x00000000);
-    ADVANCE_RING();
-}
-
-void viaFillFrontBuffer(viaContextPtr vmesa)
-{
-    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight,i; 
-    drm_clip_rect_t *b = vmesa->sarea->boxes;
-    GLuint pixel = (GLuint)vmesa->ClearColor;
-    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-    nDestPitch = vmesa->front.pitch;
-
-    for (i = 0; i < vmesa->sarea->nbox ; i++) {        
-        nDestWidth = b->x2 - b->x1;
-       nDestHeight = b->y2 - b->y1;
-       nDestBase = vmesa->viaScreen->fbOffset + 
-           (b->y1* nDestPitch + b->x1 * bytePerPixel);
-       viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
-               nDestBase , nDestPitch, nDestWidth, nDestHeight,
-               0,0,VIA_BLIT_FILL, pixel, 0x0); 
-       b++;
-    }
-
-    viaFlushPrimsLocked(vmesa);
-}
-
-void viaFillFrontPBuffer(viaContextPtr vmesa)
-{
-    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset; 
-    GLuint pixel = (GLuint)vmesa->ClearColor;
-
-    offset = vmesa->front.offset;
-    if (VIA_DEBUG) fprintf(stderr, "Fill PFront offset = %08x\n", offset);
-    nDestBase = offset;
-    nDestPitch = vmesa->front.pitch;
-
-    nDestWidth = vmesa->driDrawable->w;
-    nDestHeight = vmesa->driDrawable->h;
-
-    viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
-           nDestBase , nDestPitch, nDestWidth, nDestHeight,
-           0,0,VIA_BLIT_FILL, pixel, 0x0); 
-       
-    viaFlushPrimsLocked(vmesa);
-}
-
-void viaFillBackBuffer(viaContextPtr vmesa)
-{
-    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset; 
-    GLcontext *ctx = vmesa->glCtx;
-    GLuint pixel = (GLuint)vmesa->ClearColor;
-    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-
-    offset = vmesa->back.offset;
-    if (VIA_DEBUG) fprintf(stderr, "Fill Back offset = %08x\n", offset);
-    nDestBase = offset;
-    nDestPitch = vmesa->back.pitch;
-    
-    if (!ctx->Scissor.Enabled) {
-       nDestWidth = (vmesa->back.pitch / bytePerPixel);
-       nDestHeight = vmesa->driDrawable->h;
-       viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
-               nDestBase , nDestPitch, nDestWidth, nDestHeight,
-               0,0,VIA_BLIT_FILL, pixel, 0x0); 
-       
-    }
-    /*=* John Sheng [2003.7.18] texenv *=*/
-    else {
-       int i;
-       drm_clip_rect_t *b = vmesa->sarea->boxes;
-       for (i = 0; i < vmesa->sarea->nbox ; i++) {        
-           nDestWidth = b->x2 - b->x1;
-           nDestHeight = b->y2 - b->y1;
-           nDestBase = offset + ((b->y1 - vmesa->drawY) * nDestPitch) + 
-               (b->x1 - vmesa->drawX + vmesa->drawXoff) * bytePerPixel;
-           viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
-                   nDestBase , nDestPitch, nDestWidth, nDestHeight,
-                   0,0,VIA_BLIT_FILL, pixel, 0x0); 
-           b++;
-       }
-    }
-    if (VIA_DEBUG) {
-       fprintf(stderr," width = %08x\n", nDestWidth);  
-       fprintf(stderr," height = %08x\n", nDestHeight);        
-    }       
-}
-
-
-void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask)
-{
-    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
-
-    offset = vmesa->depth.offset;
-    if (VIA_DEBUG)
-       fprintf(stderr, "Fill Depth offset = %08x, pixel %x, mask %x\n", offset, pixel, mask);
-    nDestBase = offset;
-    nDestPitch = vmesa->depth.pitch;
-    
-    offsetX = vmesa->drawXoff;
-    nDestWidth = (vmesa->depth.pitch / vmesa->depth.bpp * 8) - offsetX;
-    nDestHeight = vmesa->driDrawable->h;
-
-    viaBlit(vmesa, vmesa->depth.bpp , nDestBase, nDestPitch,
-           nDestBase , nDestPitch, nDestWidth, nDestHeight,
-           0,0,VIA_BLIT_FILL, pixel, mask); 
-
-    
-    if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
-       viaFlushPrimsLocked(vmesa);
-    }
-}
-
-void viaDoSwapBuffers(viaContextPtr vmesa)
-{    
-    GLuint nFrontPitch;
-    GLuint nBackPitch;
-    GLuint nFrontWidth, nFrontHeight;
-    GLuint nFrontBase, nBackBase;
-    drm_clip_rect_t *b = vmesa->pClipRects;
-    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-    GLuint i;
-    
-    nFrontPitch = vmesa->front.pitch;
-    nBackPitch = vmesa->back.pitch;
-    
-    for (i = 0; i < vmesa->numClipRects; i++) {        
-
-       /* Width, Height */
-        nFrontWidth = b->x2 - b->x1;
-       nFrontHeight = b->y2 - b->y1;
-       
-       nFrontBase = vmesa->viaScreen->fbOffset + (b->y1* nFrontPitch + 
-                                                  b->x1 * bytePerPixel);
-       nBackBase = vmesa->back.offset + ((b->y1 - vmesa->drawY) * nBackPitch) + 
-           (b->x1 - vmesa->drawX + vmesa->drawXoff) * bytePerPixel;
-       
-       viaBlit(vmesa, bytePerPixel << 3 , nBackBase, nBackPitch,
-               nFrontBase , nFrontPitch, nFrontWidth, nFrontHeight,
-               0,0,VIA_BLIT_COPY, 0, 0); 
-       b++;
-    }
-
-    viaFlushPrimsLocked(vmesa);
-    if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n");
-}
-
-
-void viaDoSwapPBuffers(viaContextPtr vmesa)
-{    
-    GLuint nFrontPitch;
-    GLuint nBackPitch;
-    GLuint nFrontWidth, nFrontHeight;
-    GLuint nFrontBase, nBackBase;
-    GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
-    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
-    GLuint EngStatus = *(vmesa->pnGEMode);
-    GLuint blitMode; 
-    RING_VARS;
-
-    switch(bytePerPixel) {
-    case 4:
-       blitMode = 0x300;
-       break;
-    case 2:
-       blitMode = 0x100;
-       break;
-    default:
-       blitMode = 0x000;
-       break;
-    }
-
-    nFrontPitch = vmesa->front.pitch;
-    nBackPitch = vmesa->back.pitch;
-    
-    /* Caculate Base */
-    nFrontBase = vmesa->front.offset;
-    nBackBase = vmesa->back.offset;
-    
-    /* Width, Height */
-    nFrontWidth = nFrontPitch / bytePerPixel;
-    nFrontHeight = nBackPitch / bytePerPixel;
-    
-    /* Offset */
-    nFrontOffsetX = 0;
-    nFrontOffsetY = 0;
-    nBackOffsetX = nFrontOffsetX;
-    nBackOffsetY = nFrontOffsetY;
-
-    BEGIN_RING(8 * 2);
-    /* Restore mode */
-    SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | blitMode);
-    /* GEWD */
-    SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
-    /* GEDST */
-    SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
-    /* GESRC */
-    SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
-    /* GEDSTBASE */
-    SetReg2DAGP(0x34, (nFrontBase >> 3));
-    /* GESCRBASE */
-    SetReg2DAGP(0x30, (nBackBase >> 3));
-    /* GEPITCH */
-    SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
-                      ((nBackPitch >> 3) & 0x7FF));
-    /* BITBLT */
-    SetReg2DAGP(0x0, 0x1 | 0xCC000000);
-    ADVANCE_RING();
-
-    viaFlushPrimsLocked(vmesa);
-    if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n");
-}
-
-
 
 
 GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int line)
 {
-    if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
-       if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n", 
-                              vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
-       viaFlushPrims(vmesa);
-    }
+   if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
+      if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n", 
+                            vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
+      viaFlushDma(vmesa);
+   }
 
-    {
-        GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);
-       vmesa->dmaLow += bytes;
-       if (VIA_DEBUG && (vmesa->dmaLow & 0x4))
-          fprintf(stderr, "%s/%d: alloc 0x%x --> dmaLow 0x%x\n", func, line, bytes, vmesa->dmaLow);
-        return start;
-    }
+   {
+      GLuint *start = (GLuint *)(vmesa->dma + vmesa->dmaLow);
+      vmesa->dmaLow += bytes;
+      if (VIA_DEBUG && (vmesa->dmaLow & 0x4))
+        fprintf(stderr, "%s/%d: alloc 0x%x --> dmaLow 0x%x\n", func, line, bytes, vmesa->dmaLow);
+      return start;
+   }
 }
 
 
index 193aab8a990573458ee98cb066f2d28ae1386acf..ddb75ba6b819cd7019d422c366dbe19d53398ca1 100644 (file)
 
 
 void viaFinishPrimitive(viaContextPtr vmesa);
-void viaFlushPrims(viaContextPtr vmesa);
-void viaFlushPrimsLocked(viaContextPtr vmesa);
+void viaFlushDma(viaContextPtr vmesa);
+void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags);
 
 void viaInitIoctlFuncs(GLcontext *ctx);
 void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
 void viaPageFlip(const __DRIdrawablePrivate *dpriv);
-void viaFillFrontBuffer(viaContextPtr vmesa);
-void viaFillFrontPBuffer(viaContextPtr vmesa);
-void viaFillBackBuffer(viaContextPtr vmesa);
-void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask);
-void viaDoSwapBuffers(viaContextPtr vmesa);
-void viaDoSwapPBuffers(viaContextPtr vmesa);
 void viaCheckDma(viaContextPtr vmesa, GLuint bytes);
 
 #define VIA_FINISH_PRIM(vmesa) do {            \
@@ -50,8 +44,8 @@ void viaCheckDma(viaContextPtr vmesa, GLuint bytes);
 
 #define VIA_FLUSH_DMA(vmesa) do {              \
    VIA_FINISH_PRIM(vmesa);                     \
-   if (vmesa->dmaLow != DMA_OFFSET)            \
-      viaFlushPrims(vmesa);                    \
+   if (vmesa->dmaLow)          \
+      viaFlushDma(vmesa);                      \
 } while (0)
     
 
@@ -59,12 +53,6 @@ GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int li
 #define viaAllocDma( v, b ) viaAllocDmaFunc(v, b, __FUNCTION__, __LINE__)
 
 
-
-/* Room for the cliprect and other preamble at the head of each dma
- * buffer:   (What about buffers which only contain blits?)
- */
-#define DMA_OFFSET 32
-
 #define RING_VARS GLuint *_vb = 0, _nr, _x;
 
 #define BEGIN_RING(n) do {                             \
@@ -76,7 +64,7 @@ GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int li
 
 #define BEGIN_RING_NOCHECK(n) do {                     \
    if (_vb != 0) abort();                              \
-   _vb = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);   \
+   _vb = (GLuint *)(vmesa->dma + vmesa->dmaLow);       \
    vmesa->dmaLow += (n) * sizeof(GLuint);              \
    _nr = (n);                                          \
    _x = 0;                                             \
index 9578af3b657668c7023306318b71dd6ea5023503..4fdfec3eaa61599b35b089dea08edb0864ed2539 100644 (file)
@@ -36,9 +36,9 @@
 #define LOCAL_DEPTH_VARS                                \
     __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
     viaScreenPrivate *viaScreen = vmesa->viaScreen;     \
-    GLuint pitch = viaScreen->backPitch;                \
+    GLuint depth_pitch = vmesa->depth.pitch;                \
     GLuint height = dPriv->h;                           \
-    char *buf = (char *)(vmesa->depth.map)
+    char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8))
 
 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx &&    \
                           _y >= miny && _y < maxy)
         __DRIdrawablePrivate *dPriv = vmesa->driDrawable;                      \
         int _nc = dPriv->numClipRects;                                         \
         while (_nc--) {                                                                \
-               int minx = dPriv->pClipRects[_nc].x1 - dPriv->x;                \
-               int miny = dPriv->pClipRects[_nc].y1 - dPriv->y;                \
-               int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;                \
-               int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;        
+               int minx = dPriv->pClipRects[_nc].x1 - vmesa->drawX;            \
+               int miny = dPriv->pClipRects[_nc].y1 - vmesa->drawY;            \
+               int maxx = dPriv->pClipRects[_nc].x2 - vmesa->drawX;            \
+               int maxy = dPriv->pClipRects[_nc].y2 - vmesa->drawY;        
 
 
 #define HW_ENDCLIPLOOP()                                            \
 #define LOCAL_VARS                                                     \
     viaContextPtr vmesa = VIA_CONTEXT(ctx);             \
     __DRIdrawablePrivate *dPriv = vmesa->driDrawable;                  \
-    GLuint pitch = vmesa->drawPitch;                                   \
+    GLuint draw_pitch = vmesa->drawBuffer->pitch;                                      \
+    GLuint read_pitch = vmesa->readBuffer->pitch;                                      \
     GLuint height = dPriv->h;                                          \
-    GLushort p;                                                        \
-    char *buf, *read_buf;                                              \
-    p = 0;                                                             \
-    if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {    \
-       buf = (char *)(vmesa->drawMap);                                 \
-       read_buf = (char *)(vmesa->readMap);                            \
-    }                                                                  \
-    else {                                                             \
-       buf = (char *)(vmesa->drawMap +                                 \
-                         dPriv->x * 2 +                                \
-                         dPriv->y * pitch);                            \
-       read_buf = (char *)(vmesa->readMap +                            \
-                              dPriv->x * 2 +                           \
-                              dPriv->y * pitch);                       \
-    }
+    GLushort p = 0;                                                    \
+    char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 2); \
+    char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 2); \
+    (void) (read_pitch && draw_pitch && buf && read_buf && p);
 
 #define INIT_MONO_PIXEL(p, color)                       \
     p = PACK_COLOR_565(color[0], color[1], color[2])
     
 #define WRITE_RGBA(_x, _y, r, g, b, a)                                      \
-    *(GLushort *)(buf + _x * 2 + _y * pitch) = ((((int)r & 0xf8) << 8) |    \
+    *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = ((((int)r & 0xf8) << 8) |    \
                                                 (((int)g & 0xfc) << 3) |    \
                                                 (((int)b & 0xf8) >> 3))
 
 #define WRITE_PIXEL(_x, _y, p)                      \
-    *(GLushort *)(buf + _x * 2 + _y * pitch) = p
+    *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = p
 
 #define READ_RGBA(rgba, _x, _y)                                             \
     do {                                                                    \
-        GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * pitch);         \
+        GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * read_pitch);         \
         rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;                           \
         rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;                           \
         rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                           \
 #define LOCAL_VARS                                                     \
     viaContextPtr vmesa = VIA_CONTEXT(ctx);             \
     __DRIdrawablePrivate *dPriv = vmesa->driDrawable;                  \
-    GLuint pitch = vmesa->drawPitch;                                   \
+    GLuint draw_pitch = vmesa->drawBuffer->pitch;                                      \
+    GLuint read_pitch = vmesa->readBuffer->pitch;                                      \
     GLuint height = dPriv->h;                                          \
-    GLuint p;                                                          \
-    char *buf, *read_buf;                                              \
-    p = 0;                                                             \
-    if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {    \
-       buf = (char *)(vmesa->drawMap);                                 \
-       read_buf = (char *)(vmesa->readMap);                            \
-    }                                                                  \
-    else {                                                             \
-       buf = (char *)(vmesa->drawMap +                                 \
-                         dPriv->x * 4 +                                \
-                         dPriv->y * pitch);                            \
-       read_buf = (char *)(vmesa->readMap +                            \
-                              dPriv->x * 4 +                           \
-                              dPriv->y * pitch);                       \
-    }
+    GLuint p = 0;                                                              \
+    char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 4); \
+    char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 4); \
+    (void) (read_pitch && draw_pitch && buf && read_buf && p);
 
-#define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * pitch)
-#define GET_DST_PTR(_x, _y) (     buf + _x * 4 + _y * pitch)
+#define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * read_pitch)
+#define GET_DST_PTR(_x, _y) (     buf + _x * 4 + _y * draw_pitch)
 #define SPANTMP_PIXEL_FMT GL_BGRA
 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
 
 #define LOCAL_DEPTH_VARS                                \
     viaContextPtr vmesa = VIA_CONTEXT(ctx);             \
     __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
-    GLuint pitch = vmesa->depth.pitch;                  \
+    GLuint depth_pitch = vmesa->depth.pitch;                  \
     GLuint height = dPriv->h;                           \
     char *buf = (char *)(vmesa->depth.map)   
 
 
 
 #define WRITE_DEPTH(_x, _y, d)                      \
-    *(GLushort *)(buf + _x * 2 + _y * pitch) = d;
+    *(GLushort *)(buf + _x * 2 + _y * depth_pitch) = d;
 
 #define READ_DEPTH(d, _x, _y)                       \
-    d = *(GLushort *)(buf + _x * 2 + _y * pitch);
+    d = *(GLushort *)(buf + _x * 2 + _y * depth_pitch);
 
 #define TAG(x) via##x##_16
 #include "depthtmp.h"
 /* 32 bit depthbuffer functions.
  */
 #define WRITE_DEPTH(_x, _y, d)                      \
-    *(GLuint *)(buf + _x * 4 + _y * pitch) = d;
+    *(GLuint *)(buf + _x * 4 + _y * depth_pitch) = d;
 
 #define READ_DEPTH(d, _x, _y)                       \
-    d = *(GLuint *)(buf + _x * 4 + _y * pitch);
+    d = *(GLuint *)(buf + _x * 4 + _y * depth_pitch);
 
 #define TAG(x) via##x##_32
 #include "depthtmp.h"
 /* 24/8 bit interleaved depth/stencil functions
  */
 #define WRITE_DEPTH( _x, _y, d ) {                     \
-   GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch);        \
+   GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch);  \
    tmp &= 0x000000ff;                                  \
    tmp |= ((d)<<8);                            \
-   *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp;               \
+   *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp;         \
 }
 
 #define READ_DEPTH( d, _x, _y )                \
-   d = (*(GLuint *)(buf + (_x)*4 + (_y)*pitch)) >> 8;
+   d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8;
 
 
 #define TAG(x) via##x##_24_8
 #include "depthtmp.h"
 
 #define WRITE_STENCIL( _x, _y, d ) {                   \
-   GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch);        \
+   GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch);  \
    tmp &= 0xffffff00;                                  \
    tmp |= (d);                                 \
-   *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp;               \
+   *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp;         \
 }
 
 #define READ_STENCIL( d, _x, _y )                      \
-   d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xff;
+   d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff;
 
 #define TAG(x) via##x##_24_8
 #include "stenciltmp.h"
@@ -230,23 +210,16 @@ static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
                       GLuint bufferBit)
 {
     viaContextPtr vmesa = VIA_CONTEXT(ctx);
-    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+
     if (bufferBit == DD_FRONT_LEFT_BIT) {
-       vmesa->drawMap = (char *)vmesa->driScreen->pFB;
-        vmesa->readMap = (char *)vmesa->driScreen->pFB;
-       vmesa->drawPitch = vmesa->front.pitch;
-       vmesa->readPitch = vmesa->front.pitch;
+       vmesa->drawBuffer = vmesa->readBuffer = &vmesa->front;
     }
     else if (bufferBit == DD_BACK_LEFT_BIT) {
-       vmesa->drawMap = vmesa->back.map;
-        vmesa->readMap = vmesa->back.map;
-       vmesa->drawPitch = vmesa->back.pitch;
-       vmesa->readPitch = vmesa->back.pitch;   
+       vmesa->drawBuffer = vmesa->readBuffer = &vmesa->back;
     }
     else {
         ASSERT(0);
     }
-    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
 }
 
 /* Move locking out to get reasonable span performance.
@@ -256,7 +229,7 @@ void viaSpanRenderStart( GLcontext *ctx )
    viaContextPtr vmesa = VIA_CONTEXT(ctx);     
    VIA_FINISH_PRIM(vmesa);
    LOCK_HARDWARE(vmesa);
-   viaFlushPrimsLocked(vmesa);
+   viaFlushDmaLocked(vmesa, 0);
    WAIT_IDLE(vmesa);
 }
 
index e9f0d6682f97a6205c7251a8a04b6a78faa65bb4..ef3846106d05fecf9eb31e71306c5321e21fafd6 100644 (file)
@@ -642,21 +642,13 @@ static void viaDrawBuffer(GLcontext *ctx, GLenum mode)
     if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
     if (mode == GL_FRONT) {
         VIA_FLUSH_DMA(vmesa);
-        vmesa->drawMap = (char *)vmesa->driScreen->pFB;
-        vmesa->readMap = (char *)vmesa->driScreen->pFB;
-       vmesa->drawPitch = vmesa->front.pitch;
-       vmesa->readPitch = vmesa->front.pitch;
-        viaXMesaSetFrontClipRects(vmesa);
+       vmesa->drawBuffer = vmesa->readBuffer = &vmesa->front;
         FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
         return;
     }
     else if (mode == GL_BACK) {
         VIA_FLUSH_DMA(vmesa);
-        vmesa->drawMap = vmesa->back.map;
-        vmesa->readMap = vmesa->back.map;
-       vmesa->drawPitch = vmesa->back.pitch;
-       vmesa->readPitch = vmesa->back.pitch;   
-        viaXMesaSetBackClipRects(vmesa);
+       vmesa->drawBuffer = vmesa->readBuffer = &vmesa->back;
         FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
         return;
     }
@@ -665,6 +657,8 @@ static void viaDrawBuffer(GLcontext *ctx, GLenum mode)
         return;
     }
 
+    viaXMesaWindowMoved(vmesa);
+
    /* We want to update the s/w rast state too so that r200SetBuffer()
     * gets called.
     */
@@ -693,6 +687,10 @@ static void viaClearColor(GLcontext *ctx, const GLfloat color[4])
  */
 
 
+/* Using drawXoff like this is incorrect outside of locked regions.
+ * This hardware just isn't capable of private back buffers without
+ * glitches and/or a hefty locking scheme.
+ */
 void viaCalcViewport(GLcontext *ctx)
 {
     viaContextPtr vmesa = VIA_CONTEXT(ctx);
@@ -1550,6 +1548,8 @@ void viaValidateState( GLcontext *ctx )
         viaChooseStencilState(ctx);
     
     if (!vmesa->Fallback) {
+       viaChooseVertexState(ctx);
+       viaChooseRenderState(ctx);
        via_emit_state(vmesa);
        vmesa->newState = 0;
     }
index b936760dc3284ca68ffa69c1972b25cb4ffe50d9..4d2092f36111516dc1814e6338ab5d60075deb3a 100644 (file)
@@ -555,7 +555,7 @@ static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
 
-static void viaChooseRenderState(GLcontext *ctx)
+void viaChooseRenderState(GLcontext *ctx)
 {
     TNLcontext *tnl = TNL_CONTEXT(ctx);
     viaContextPtr vmesa = VIA_CONTEXT(ctx);
@@ -633,11 +633,6 @@ static void viaRunPipeline(GLcontext *ctx)
     
     if (vmesa->newState) {
        viaValidateState( ctx );
-
-       if (!vmesa->Fallback) {
-         viaChooseVertexState(ctx);
-         viaChooseRenderState(ctx);
-       }
     }
 
     _tnl_run_pipeline(ctx);
@@ -677,9 +672,8 @@ void viaRasterPrimitive(GLcontext *ctx,
               _mesa_lookup_enum_by_nr(hwprim));
 
     VIA_FINISH_PRIM(vmesa);
+    viaCheckDma( vmesa, 1024 );        /* Ensure no wrapping inside this function  */
 
-    vmesa->renderPrimitive = glprim;
-    
     regCmdB = vmesa->regCmdB;
 
     switch (hwprim) {
@@ -738,7 +732,24 @@ void viaRasterPrimitive(GLcontext *ctx,
         return;
     }
     
-    assert((vmesa->dmaLow & 0x4) == 0);
+/*     assert((vmesa->dmaLow & 0x4) == 0); */
+
+    if (vmesa->dmaCliprectAddr == 0) {
+       if (VIA_DEBUG) fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
+       assert(vmesa->dmaLow);
+       vmesa->dmaCliprectAddr = vmesa->dmaLow;
+       BEGIN_RING(8);
+       OUT_RING( HC_HEADER2 );    
+       OUT_RING( (HC_ParaType_NotTex << 16) );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       OUT_RING( 0xCCCCCCCC );
+       ADVANCE_RING();
+    }
+
 
     BEGIN_RING(8);
     OUT_RING( HC_HEADER2 );    
@@ -752,8 +763,10 @@ void viaRasterPrimitive(GLcontext *ctx,
     OUT_RING( vmesa->regCmdA_End );
     ADVANCE_RING();
 
+
+    vmesa->renderPrimitive = glprim;
+    vmesa->hwPrimitive = hwprim;        
     vmesa->dmaLastPrim = vmesa->dmaLow;
-    vmesa->hwPrimitive = hwprim;    
 }
 
 /* Callback for mesa:
@@ -766,36 +779,46 @@ static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
 
 void viaFinishPrimitive(viaContextPtr vmesa)
 {
-    if (!vmesa->dmaLastPrim) {
-       return;
-    }
-    else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
-       GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;    
-       RING_VARS;
-
-       /* KW: modified 0x1 to 0x4 below:
-        */
-       if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) {
-          BEGIN_RING_NOCHECK( 1 );
-          OUT_RING( cmdA );
-          ADVANCE_RING();
-       }   
-       else {      
-          BEGIN_RING_NOCHECK( 2 );
-          OUT_RING( cmdA );
-          OUT_RING( cmdA );
-          ADVANCE_RING();
-        }   
-       vmesa->dmaLastPrim = 0;
-
-       if (1 || vmesa->dmaLow > VIA_DMA_HIGHWATER)
-          viaFlushPrims( vmesa );
-    }
-    else {
-       assert(vmesa->dmaLow >= (32 + DMA_OFFSET));
-       vmesa->dmaLow -= 32;
-       vmesa->dmaLastPrim = 0;
-    }
+   if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if (!vmesa->dmaLastPrim) {
+      return;
+   }
+   else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
+      GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;    
+      RING_VARS;
+
+      /* KW: modified 0x1 to 0x4 below:
+       */
+      if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) {
+        BEGIN_RING_NOCHECK( 1 );
+        OUT_RING( cmdA );
+        ADVANCE_RING();
+      }   
+      else {      
+        BEGIN_RING_NOCHECK( 2 );
+        OUT_RING( cmdA );
+        OUT_RING( cmdA );
+        ADVANCE_RING();
+      }   
+      vmesa->dmaLastPrim = 0;
+
+      if (vmesa->dmaLow > VIA_DMA_HIGHWATER)
+        viaFlushDma( vmesa );
+   }
+   else {
+      /* Remove the primitive header:
+       */
+      vmesa->dmaLastPrim = 0;
+      vmesa->dmaLow -= 8 * sizeof(GLuint);
+
+      /* Maybe remove the cliprect as well:
+       */
+      if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) {
+        vmesa->dmaLow -= 8 * sizeof(GLuint);
+        vmesa->dmaCliprectAddr = 0;
+      }
+   }
 }
 
 
index 222a0f07ca1b28d15c2b9d892842d80308139321..0b6830a6bfb05d6958a25c1fd55f68b60a7940b9 100644 (file)
@@ -86,9 +86,11 @@ static struct {
 #define HAVE_TEX3_VERTICES  0
 #define HAVE_PTEX_VERTICES  0
 
-#define UNVIEWPORT_VARS  GLfloat h = VIA_CONTEXT(ctx)->driDrawable->h, \
-                                 depth_max = VIA_CONTEXT(ctx)->depth_max;
-#define UNVIEWPORT_X(x)  x - SUBPIXEL_X
+#define UNVIEWPORT_VARS  \
+   viaContextPtr vmesa = VIA_CONTEXT(ctx); \
+   GLfloat h = vmesa->driDrawable->h, depth_max = vmesa->depth_max, xoff = vmesa->drawXoff;
+
+#define UNVIEWPORT_X(x)  x - (SUBPIXEL_X + xoff)
 #define UNVIEWPORT_Y(y)  - y + h + SUBPIXEL_Y
 #define UNVIEWPORT_Z(z)  z * (float)depth_max