/*
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include <stdio.h>
#include <unistd.h>

#include "glheader.h"
#include "mtypes.h"
#include "macros.h"
#include "dd.h"
#include "swrast/swrast.h"

#include "mm.h"
#include "via_context.h"
#include "via_tris.h"
#include "via_ioctl.h"
#include "via_state.h"
#include "via_fb.h"
#include "via_3d_reg.h"

#include "vblank.h"
#include "drm.h"
#include "xf86drm.h"
#include <sys/ioctl.h>
#include <errno.h>


#define VIA_REG_STATUS          0x400
#define VIA_REG_GEMODE          0x004
#define VIA_REG_SRCBASE         0x030
#define VIA_REG_DSTBASE         0x034
#define VIA_REG_PITCH           0x038      
#define VIA_REG_SRCCOLORKEY     0x01C      
#define VIA_REG_KEYCONTROL      0x02C       
#define VIA_REG_SRCPOS          0x008
#define VIA_REG_DSTPOS          0x00C
#define VIA_REG_GECMD           0x000
#define VIA_REG_DIMENSION       0x010       /* width and height */
#define VIA_REG_FGCOLOR         0x018

#define VIA_GEM_8bpp            0x00000000
#define VIA_GEM_16bpp           0x00000100
#define VIA_GEM_32bpp           0x00000300
#define VIA_GEC_BLT             0x00000001
#define VIA_PITCH_ENABLE        0x80000000
#define VIA_GEC_INCX            0x00000000
#define VIA_GEC_DECY            0x00004000
#define VIA_GEC_INCY            0x00000000
#define VIA_GEC_DECX            0x00008000
#define VIA_GEC_FIXCOLOR_PAT    0x00002000


#define VIA_BLIT_CLEAR 0x00
#define VIA_BLIT_COPY 0xCC
#define VIA_BLIT_FILL 0xF0
#define VIA_BLIT_SET 0xFF

static void dump_dma( struct via_context *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 viaCheckDma(struct via_context *vmesa, GLuint bytes)
{
    VIA_FINISH_PRIM( vmesa );
    if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
	viaFlushDma(vmesa);
    }
}



#define SetReg2DAGP(nReg, nData) do {		\
    OUT_RING( ((nReg) >> 2) | 0xF0000000 );	\
    OUT_RING( nData );				\
} while (0)


static void viaBlit(struct via_context *vmesa, GLuint bpp,
		    GLuint srcBase, GLuint srcPitch, 
		    GLuint dstBase, GLuint dstPitch,
		    GLuint w, GLuint h, 
		    GLuint blitMode, 
		    GLuint color, GLuint nMask ) 
{

    GLuint dwGEMode, srcX, dstX, cmd;
    RING_VARS;

    if (VIA_DEBUG & DEBUG_2D)
       fprintf(stderr, 
	       "%s bpp %d src %x/%x dst %x/%x w %d h %d "
	       " mode: %x color: 0x%08x mask 0x%08x\n",
	       __FUNCTION__, bpp, srcBase, srcPitch, dstBase,
	       dstPitch, w,h, blitMode, color, nMask);


    if (!w || !h)
        return;

    switch (bpp) {
    case 16:
        dwGEMode = VIA_GEM_16bpp;
	srcX = (srcBase & 0x1f) >> 1;
	dstX = (dstBase & 0x1f) >> 1;
        break;
    case 32:
        dwGEMode = VIA_GEM_32bpp;
	srcX = (srcBase & 0x1f) >> 2;
	dstX = (dstBase & 0x1f) >> 2;
	break;
    default:
        return;
    }

    switch(blitMode) {
    case VIA_BLIT_FILL:
	cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
	break;
    case VIA_BLIT_COPY:
	cmd = VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
	break;
    default:
        return;
    }	

    BEGIN_RING(22);
    SetReg2DAGP( VIA_REG_GEMODE, dwGEMode);
    SetReg2DAGP( VIA_REG_FGCOLOR, color);
    SetReg2DAGP( 0x2C, nMask);
    SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~0x1f) >> 3);
    SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~0x1f) >> 3);
    SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE |
	       (srcPitch >> 3) | ((dstPitch >> 3) << 16));
    SetReg2DAGP( VIA_REG_SRCPOS, srcX);
    SetReg2DAGP( VIA_REG_DSTPOS, dstX);
    SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
    SetReg2DAGP( VIA_REG_GECMD, cmd);
    SetReg2DAGP( 0x2C, 0x00000000);
    ADVANCE_RING();
}

static void viaFillBuffer(struct via_context *vmesa,
			  struct via_renderbuffer *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 - buffer->drawX;
      int y = pbox[i].y1 - buffer->drawY;
      int w = pbox[i].x2 - pbox[i].x1;
      int h = pbox[i].y2 - pbox[i].y1;

      int offset = (buffer->offset + 
		    y * buffer->pitch + 
		    x * bytePerPixel);

      viaBlit(vmesa,
	      buffer->bpp, 
	      offset, buffer->pitch,
	      offset, buffer->pitch, 
	      w, h,
	      VIA_BLIT_FILL, pixel, mask); 
   }
}



static void viaClear(GLcontext *ctx, GLbitfield mask)
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
   struct via_renderbuffer *const vrb = 
     (struct via_renderbuffer *) dPriv->driverPrivate;
   int flag = 0;
   GLuint i = 0;
   GLuint clear_depth_mask = 0xf << 28;
   GLuint clear_depth = 0;

   VIA_FLUSH_DMA(vmesa);

   if (mask & BUFFER_BIT_FRONT_LEFT) {
      flag |= VIA_FRONT;
      mask &= ~BUFFER_BIT_FRONT_LEFT;
   }

   if (mask & BUFFER_BIT_BACK_LEFT) {
      flag |= VIA_BACK;	
      mask &= ~BUFFER_BIT_BACK_LEFT;
   }

   if (mask & BUFFER_BIT_DEPTH) {
      flag |= VIA_DEPTH;
      clear_depth = (GLuint)(ctx->Depth.Clear * vmesa->ClearDepth);
      clear_depth_mask &= ~vmesa->depth_clear_mask;
      mask &= ~BUFFER_BIT_DEPTH;
   }
    
   if (mask & BUFFER_BIT_STENCIL) {
      if (vmesa->have_hw_stencil) {
	 if ((ctx->Stencil.WriteMask[0] & 0xff) == 0xff) {
	    flag |= VIA_DEPTH;
	    clear_depth &= ~0xff;
	    clear_depth |= (ctx->Stencil.Clear & 0xff);
	    clear_depth_mask &= ~vmesa->stencil_clear_mask;
	    mask &= ~BUFFER_BIT_STENCIL;
	 }
	 else {
	    if (VIA_DEBUG & DEBUG_2D)
	       fprintf(stderr, "Clear stencil writemask %x\n", 
		       ctx->Stencil.WriteMask[0]);
	 }
      }
   }

   /* 16bpp doesn't support masked clears */
   if (vmesa->viaScreen->bytesPerPixel == 2 &&
       vmesa->ClearMask & 0xf0000000) {
      if (flag & VIA_FRONT)
         mask |= BUFFER_BIT_FRONT_LEFT;
      if (flag & VIA_BACK)
         mask |= BUFFER_BIT_BACK_LEFT;
      flag &= ~(VIA_FRONT | VIA_BACK);
   }
    
   if (flag) {
      drm_clip_rect_t *boxes, *tmp_boxes = 0;
      int nr = 0;
      GLint cx, cy, cw, ch;
      GLboolean all;

      LOCK_HARDWARE(vmesa);
	    
      /* get region after locking: */
      cx = ctx->DrawBuffer->_Xmin;
      cy = ctx->DrawBuffer->_Ymin;
      cw = ctx->DrawBuffer->_Xmax - cx;
      ch = ctx->DrawBuffer->_Ymax - cy;
      all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height);

      /* flip top to bottom */
      cy = dPriv->h - cy - ch;
      cx += vrb->drawX;
      cy += vrb->drawY;
        
      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;
	 }

	 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) {
	 viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor,
		       vmesa->ClearMask);
      } 
		
      if (flag & VIA_BACK) {
	 viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor, 
		       vmesa->ClearMask);
      }

      if (flag & VIA_DEPTH) {
	 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);
}




static void viaDoSwapBuffers(struct via_context *vmesa,
			     drm_clip_rect_t *b,
			     GLuint nbox)
{    
   GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
   struct via_renderbuffer *front = &vmesa->front;
   struct via_renderbuffer *back = &vmesa->back;
   GLuint i;
        
   for (i = 0; i < nbox; i++, b++) {        
      GLint x = b->x1 - back->drawX;
      GLint y = b->y1 - back->drawY;
      GLint w = b->x2 - b->x1;
      GLint h = b->y2 - b->y1;
	
      GLuint src = back->offset + y * back->pitch + x * bytePerPixel;
      GLuint dest = front->offset + y * front->pitch + x * bytePerPixel;

      viaBlit(vmesa, 
	      bytePerPixel << 3, 
	      src, back->pitch,
	      dest, front->pitch,
	      w, h,
	      VIA_BLIT_COPY, 0, 0); 
   }

   viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* redundant */
}


static void viaEmitBreadcrumbLocked( struct via_context *vmesa )
{
   struct via_renderbuffer *buffer = &vmesa->breadcrumb;
   GLuint value = vmesa->lastBreadcrumbWrite + 1;

   if (VIA_DEBUG & DEBUG_IOCTL) 
      fprintf(stderr, "%s %d\n", __FUNCTION__, value);

   assert(!vmesa->dmaLow);

   viaBlit(vmesa,
	   buffer->bpp, 
	   buffer->offset, buffer->pitch,
	   buffer->offset, buffer->pitch, 
	   1, 1,
	   VIA_BLIT_FILL, value, 0); 

   viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */
   vmesa->lastBreadcrumbWrite = value;
}

void viaEmitBreadcrumb( struct via_context *vmesa )
{
   LOCK_HARDWARE(vmesa);
   if (vmesa->dmaLow) 
      viaFlushDmaLocked(vmesa, 0);

   viaEmitBreadcrumbLocked( vmesa );
   UNLOCK_HARDWARE(vmesa);
}

static GLboolean viaCheckIdle( struct via_context *vmesa )
{
   if ((vmesa->regEngineStatus[0] & 0xFFFEFFFF) == 0x00020000) {
      return GL_TRUE;
   }
   return GL_FALSE;
}


GLboolean viaCheckBreadcrumb( struct via_context *vmesa, GLuint value )
{
   GLuint *buf = (GLuint *)vmesa->breadcrumb.map; 
   vmesa->lastBreadcrumbRead = *buf;

   if (VIA_DEBUG & DEBUG_IOCTL) 
      fprintf(stderr, "%s %d < %d: %d\n", __FUNCTION__, value, 
	      vmesa->lastBreadcrumbRead,
	      !VIA_GEQ_WRAP(value, vmesa->lastBreadcrumbRead));

   return !VIA_GEQ_WRAP(value, vmesa->lastBreadcrumbRead);
}

static void viaWaitBreadcrumb( struct via_context *vmesa, GLuint value )
{
   if (VIA_DEBUG & DEBUG_IOCTL) 
      fprintf(stderr, "%s %d\n", __FUNCTION__, value);

   assert(!VIA_GEQ_WRAP(value, vmesa->lastBreadcrumbWrite));

   while (!viaCheckBreadcrumb( vmesa, value )) {
      viaSwapOutWork( vmesa );
      via_release_pending_textures( vmesa );
   }
}


void viaWaitIdle( struct via_context *vmesa, GLboolean light )
{
   VIA_FLUSH_DMA(vmesa);

   if (VIA_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s lastDma %d lastBreadcrumbWrite %d\n",
	      __FUNCTION__, vmesa->lastDma, vmesa->lastBreadcrumbWrite);

   /* Need to emit a new breadcrumb?
    */
   if (vmesa->lastDma == vmesa->lastBreadcrumbWrite) {
      LOCK_HARDWARE(vmesa);
      viaEmitBreadcrumbLocked( vmesa );
      UNLOCK_HARDWARE(vmesa);
   }

   /* Need to wait?
    */
   if (VIA_GEQ_WRAP(vmesa->lastDma, vmesa->lastBreadcrumbRead)) 
      viaWaitBreadcrumb( vmesa, vmesa->lastDma );

   if (light) return;

   LOCK_HARDWARE(vmesa);
   while(!viaCheckIdle(vmesa))
      ;
   UNLOCK_HARDWARE(vmesa);
   via_release_pending_textures(vmesa);
}


void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light )
{
   if (vmesa->dmaLow) 
      viaFlushDmaLocked(vmesa, 0);

   if (VIA_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s lastDma %d lastBreadcrumbWrite %d\n",
	      __FUNCTION__, vmesa->lastDma, vmesa->lastBreadcrumbWrite);

   /* Need to emit a new breadcrumb?
    */
   if (vmesa->lastDma == vmesa->lastBreadcrumbWrite) {
      viaEmitBreadcrumbLocked( vmesa );
   }

   /* Need to wait?
    */
   if (vmesa->lastDma >= vmesa->lastBreadcrumbRead) 
      viaWaitBreadcrumb( vmesa, vmesa->lastDma );

   if (light) return;

   while(!viaCheckIdle(vmesa))
      ;

   via_release_pending_textures(vmesa);
}



/* Wait for command stream to be processed *and* the next vblank to
 * occur.  Equivalent to calling WAIT_IDLE() and then WaitVBlank,
 * except that WAIT_IDLE() will spin the CPU polling, while this is
 * IRQ driven.
 */
static void viaWaitIdleVBlank(  __DRIdrawablePrivate *dPriv, 
			       struct via_context *vmesa,
			       GLuint value )
{
   GLboolean missed_target;
   __DRIscreenPrivate *psp = dPriv->driScreenPriv;

   VIA_FLUSH_DMA(vmesa); 

   if (!value)
      return;

   do {
      if (value < vmesa->lastBreadcrumbRead ||
	  vmesa->thrashing)
	 viaSwapOutWork(vmesa);

      driWaitForVBlank( dPriv, & missed_target );
      if ( missed_target ) {
	 vmesa->swap_missed_count++;
	 (*psp->systemTime->getUST)( &vmesa->swap_missed_ust );
      }
   } 
   while (!viaCheckBreadcrumb(vmesa, value));	 

   vmesa->thrashing = 0;	/* reset flag on swap */
   vmesa->swap_count++;   
   via_release_pending_textures( vmesa );
}



static void viaDoPageFlipLocked(struct via_context *vmesa, GLuint offset)
{
   RING_VARS;

   if (VIA_DEBUG & DEBUG_2D)
      fprintf(stderr, "%s %x\n", __FUNCTION__, offset);

   if (!vmesa->nDoneFirstFlip) {
      vmesa->nDoneFirstFlip = GL_TRUE;
      BEGIN_RING(4);
      OUT_RING(HALCYON_HEADER2);
      OUT_RING(0x00fe0000);
      OUT_RING(0x0000000e);
      OUT_RING(0x0000000e);
      ADVANCE_RING();
   }

   BEGIN_RING(4);
   OUT_RING( HALCYON_HEADER2 );
   OUT_RING( 0x00fe0000 );
   OUT_RING((HC_SubA_HFBBasL << 24) | (offset & 0xFFFFF8) | 0x2);
   OUT_RING((HC_SubA_HFBDrawFirst << 24) |
	    ((offset & 0xFF000000) >> 24) | 0x0100);
   ADVANCE_RING();

   vmesa->pfCurrentOffset = vmesa->sarea->pfCurrentOffset = offset;

   viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */
}

void viaResetPageFlippingLocked(struct via_context *vmesa)
{
   if (VIA_DEBUG & DEBUG_2D)
      fprintf(stderr, "%s\n", __FUNCTION__);

   viaDoPageFlipLocked( vmesa, 0 );

   if (vmesa->front.offset != 0) {
      struct via_renderbuffer buffer_tmp;
      memcpy(&buffer_tmp, &vmesa->back, sizeof(struct via_renderbuffer));
      memcpy(&vmesa->back, &vmesa->front, sizeof(struct via_renderbuffer));
      memcpy(&vmesa->front, &buffer_tmp, sizeof(struct via_renderbuffer));
   }

   assert(vmesa->front.offset == 0);
   vmesa->doPageFlip = vmesa->allowPageFlip = 0;
}


/*
 * Copy the back buffer to the front buffer. 
 */
void viaCopyBuffer(__DRIdrawablePrivate *dPriv)
{
   struct via_context *vmesa = 
      (struct via_context *)dPriv->driContextPriv->driverPrivate;
   __DRIscreenPrivate *psp = dPriv->driScreenPriv;

   if (VIA_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, 
	      "%s: lastSwap[1] %d lastSwap[0] %d lastWrite %d lastRead %d\n",
	      __FUNCTION__,
	      vmesa->lastSwap[1], 
	      vmesa->lastSwap[0], 
	      vmesa->lastBreadcrumbWrite,
	      vmesa->lastBreadcrumbRead);

   VIA_FLUSH_DMA(vmesa);

   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
       vmesa->lastBreadcrumbWrite > 1)
      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1);
   else
      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[1]);

   LOCK_HARDWARE(vmesa);

   /* Catch and cleanup situation where we were pageflipping but have
    * stopped.
    */
   if (dPriv->numClipRects && vmesa->sarea->pfCurrentOffset != 0) {
      viaResetPageFlippingLocked(vmesa);
      UNLOCK_HARDWARE(vmesa);
      return;
   }

   viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects);
   vmesa->lastSwap[1] = vmesa->lastSwap[0];
   vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;
   viaEmitBreadcrumbLocked(vmesa);
   UNLOCK_HARDWARE(vmesa);

   (*psp->systemTime->getUST)( &vmesa->swap_ust );
}


void viaPageFlip(__DRIdrawablePrivate *dPriv)
{
    struct via_context *vmesa = 
       (struct via_context *)dPriv->driContextPriv->driverPrivate;
    struct via_renderbuffer buffer_tmp;
    __DRIscreenPrivate *psp = dPriv->driScreenPriv;

    VIA_FLUSH_DMA(vmesa);
   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
       vmesa->lastBreadcrumbWrite > 1)
      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1);
   else
      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[0]);

    LOCK_HARDWARE(vmesa);
    viaDoPageFlipLocked(vmesa, vmesa->back.offset);
    vmesa->lastSwap[1] = vmesa->lastSwap[0];
    vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;
    viaEmitBreadcrumbLocked(vmesa);
    UNLOCK_HARDWARE(vmesa);

    (*psp->systemTime->getUST)( &vmesa->swap_ust );


    /* KW: FIXME: When buffers are freed, could free frontbuffer by
     * accident:
     */
    memcpy(&buffer_tmp, &vmesa->back, sizeof(struct via_renderbuffer));
    memcpy(&vmesa->back, &vmesa->front, sizeof(struct via_renderbuffer));
    memcpy(&vmesa->front, &buffer_tmp, sizeof(struct via_renderbuffer));
}




#define VIA_CMDBUF_MAX_LAG 50000

static int fire_buffer(struct via_context *vmesa)
{
   drm_via_cmdbuffer_t bufI;
   int ret;

   bufI.buf = (char *)vmesa->dma;
   bufI.size = vmesa->dmaLow;

   if (vmesa->useAgp) {
      drm_via_cmdbuf_size_t bSiz;

      /* Do the CMDBUF_SIZE ioctl:
       */
      bSiz.func = VIA_CMDBUF_LAG;
      bSiz.wait = 1;
      bSiz.size = VIA_CMDBUF_MAX_LAG;
      do {
	 ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE, 
				   &bSiz, sizeof(bSiz));
      } while (ret == -EAGAIN);
      if (ret) {
	 UNLOCK_HARDWARE(vmesa);
	 fprintf(stderr, "%s: DRM_VIA_CMDBUF_SIZE returned %d\n",
		 __FUNCTION__, ret);
	 abort();
	 return ret;
      }

      /* Actually fire the buffer:
       */
      do {
	 ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER, 
			       &bufI, sizeof(bufI));
      } while (ret == -EAGAIN);
      if (ret) {
	 UNLOCK_HARDWARE(vmesa);
	 fprintf(stderr, "%s: DRM_VIA_CMDBUFFER returned %d\n",
		 __FUNCTION__, ret);
	 abort();
	 /* If this fails, the original code fell back to the PCI path. 
	  */
      }
      else 
	 return 0;

      /* Fall through to PCI handling?!?
       */
      viaWaitIdleLocked(vmesa, GL_FALSE);
   }
	    
   ret = drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI));
   if (ret) {
      UNLOCK_HARDWARE(vmesa);
      dump_dma(vmesa);
      fprintf(stderr, "%s: DRM_VIA_PCICMD returned %d\n", __FUNCTION__, ret); 
      abort();
   }

   return ret;
}


/* Inserts the surface addresss and active cliprects one at a time
 * into the head of the DMA buffer being flushed.  Fires the buffer
 * for each cliprect.
 */
static void via_emit_cliprect(struct via_context *vmesa,
			      drm_clip_rect_t *b) 
{
   struct via_renderbuffer *buffer = vmesa->drawBuffer;
   GLuint *vb = (GLuint *)(vmesa->dma + vmesa->dmaCliprectAddr);

   GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20 
		    ? HC_HDBFM_ARGB8888 
		    : HC_HDBFM_RGB565);

   GLuint pitch = buffer->pitch;
   GLuint offset = buffer->offset;

   if (0)
      fprintf(stderr, "emit cliprect for box %d,%d %d,%d\n", 
	      b->x1, b->y1, b->x2, 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) | (b->y1 << 12) | b->y2;
      vb[3] = (HC_SubA_HClipLR << 24) | (b->x1 << 12) | b->x2;
   }
	    
   vb[4] = (HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF);
   vb[5] = (HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000) >> 24); 

   vb[6] = (HC_SubA_HSPXYOS << 24);
   vb[7] = (HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch;
}



static int intersect_rect(drm_clip_rect_t *out,
                          drm_clip_rect_t *a,
                          drm_clip_rect_t *b)
{
    *out = *a;
    
    if (0)
       fprintf(stderr, "intersect %d,%d %d,%d and %d,%d %d,%d\n", 
	       a->x1, a->y1, a->x2, a->y2,
	       b->x1, b->y1, b->x2, b->y2);

    if (b->x1 > out->x1) out->x1 = b->x1;
    if (b->x2 < out->x2) out->x2 = b->x2;
    if (out->x1 >= out->x2) return 0;

    if (b->y1 > out->y1) out->y1 = b->y1;
    if (b->y2 < out->y2) out->y2 = b->y2;
    if (out->y1 >= out->y2) return 0;

    return 1;
}

void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags)
{
   int i;
   RING_VARS;

   if (VIA_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
      fprintf(stderr, "%s\n", __FUNCTION__);

   if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) &&
       *(GLuint *)vmesa->driHwLock != 
       (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) {
      fprintf(stderr, "%s called without lock held\n", __FUNCTION__);
      abort();
   }

   if (vmesa->dmaLow == 0) {
      return;
   }

   assert(vmesa->dmaLastPrim == 0);

   /* viaFinishPrimitive can add up to 8 bytes beyond VIA_DMA_HIGHWATER:
    */
   if (vmesa->dmaLow > VIA_DMA_HIGHWATER + 8) {
      fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow);
      abort();
   }

   switch (vmesa->dmaLow & 0x1F) {	
   case 8:
      BEGIN_RING_NOCHECK( 6 );
      OUT_RING( HC_HEADER2 );
      OUT_RING( (HC_ParaType_NotTex << 16) );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      ADVANCE_RING();
      break;
   case 16:
      BEGIN_RING_NOCHECK( 4 );
      OUT_RING( HC_HEADER2 );
      OUT_RING( (HC_ParaType_NotTex << 16) );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      ADVANCE_RING();
      break;    
   case 24:
      BEGIN_RING_NOCHECK( 10 );
      OUT_RING( HC_HEADER2 );
      OUT_RING( (HC_ParaType_NotTex << 16) );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );
      OUT_RING( HC_DUMMY );	
      ADVANCE_RING();
      break;    
   case 0:
      break;
   default:
      if (VIA_DEBUG & DEBUG_IOCTL)
	 fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n",
		 __FUNCTION__, vmesa->dmaLow);
   }

   vmesa->lastDma = vmesa->lastBreadcrumbWrite;

   if (VIA_DEBUG & DEBUG_DMA)
      dump_dma( vmesa );

   if (flags & VIA_NO_CLIPRECTS) {
      if (0) fprintf(stderr, "%s VIA_NO_CLIPRECTS\n", __FUNCTION__);
      assert(vmesa->dmaCliprectAddr == ~0);
      fire_buffer( vmesa );
   }
   else if (vmesa->dmaCliprectAddr == ~0) {
      /* Contains only state.  Could just dump the packet?
       */
      if (0) fprintf(stderr, "%s: no dmaCliprectAddr\n", __FUNCTION__);
      if (0) fire_buffer( vmesa );
   }
   else if (vmesa->numClipRects) {
      drm_clip_rect_t *pbox = vmesa->pClipRects;
      __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
      struct via_renderbuffer *const vrb = 
	(struct via_renderbuffer *) dPriv->driverPrivate;

      for (i = 0; i < vmesa->numClipRects; i++) {
	 drm_clip_rect_t b;

	 b.x1 = pbox[i].x1;
	 b.x2 = pbox[i].x2;
	 b.y1 = pbox[i].y1;
	 b.y2 = pbox[i].y2;

	 if (vmesa->scissor &&
	     !intersect_rect(&b, &b, &vmesa->scissorRect)) 
	    continue;

	 via_emit_cliprect(vmesa, &b);

	 if (fire_buffer(vmesa) != 0) {
	    dump_dma( vmesa );
	    goto done;
	 }
      }
   } else {
      if (0) fprintf(stderr, "%s: no cliprects\n", __FUNCTION__);
      UNLOCK_HARDWARE(vmesa);
      sched_yield();
      LOCK_HARDWARE(vmesa);
   }

 done:
   /* Reset vmesa vars:
    */
   vmesa->dmaLow = 0;
   vmesa->dmaCliprectAddr = ~0;
   vmesa->newEmitState = ~0;
}

void viaWrapPrimitive( struct via_context *vmesa )
{
   GLenum renderPrimitive = vmesa->renderPrimitive;
   GLenum hwPrimitive = vmesa->hwPrimitive;

   if (VIA_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__);
   
   if (vmesa->dmaLastPrim)
      viaFinishPrimitive( vmesa );
   
   viaFlushDma(vmesa);

   if (renderPrimitive != GL_POLYGON + 1)
      viaRasterPrimitive( vmesa->glCtx,
			  renderPrimitive,
			  hwPrimitive );

}

void viaFlushDma(struct via_context *vmesa)
{
   if (vmesa->dmaLow) {
      assert(!vmesa->dmaLastPrim);

      LOCK_HARDWARE(vmesa); 
      viaFlushDmaLocked(vmesa, 0);
      UNLOCK_HARDWARE(vmesa);
   }
}

static void viaFlush(GLcontext *ctx)
{
    struct via_context *vmesa = VIA_CONTEXT(ctx);
    VIA_FLUSH_DMA(vmesa);
}

static void viaFinish(GLcontext *ctx)
{
    struct via_context *vmesa = VIA_CONTEXT(ctx);
    VIA_FLUSH_DMA(vmesa);
    viaWaitIdle(vmesa, GL_FALSE);
}

static void viaClearStencil(GLcontext *ctx,  int s)
{
    return;
}

void viaInitIoctlFuncs(GLcontext *ctx)
{
    ctx->Driver.Flush = viaFlush;
    ctx->Driver.Clear = viaClear;
    ctx->Driver.Finish = viaFinish;
    ctx->Driver.ClearStencil = viaClearStencil;
}



