/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v 1.10 2002/12/16 16:18:53 dawes Exp $ */
/**************************************************************************

Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
                                               Cedar Park, Texas.
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
on 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
ATI, PRECISION INSIGHT AND/OR THEIR 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.

**************************************************************************/

/*
 * Authors:
 *   Gareth Hughes <gareth@valinux.com>
 *
 */
#include <errno.h>

#define STANDALONE_MMIO
#include "r128_context.h"
#include "r128_state.h"
#include "r128_ioctl.h"
#include "imports.h"
#include "macros.h"

#include "swrast/swrast.h"

#include "vblank.h"
#include "mmio.h"
#include "drirenderbuffer.h"

#define R128_TIMEOUT        2048
#define R128_IDLE_RETRY       32


/* =============================================================
 * Hardware vertex buffer handling
 */

/* Get a new VB from the pool of vertex buffers in AGP space.
 */
drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa )
{
   int fd = rmesa->r128Screen->driScreen->fd;
   int index = 0;
   int size = 0;
   drmDMAReq dma;
   drmBufPtr buf = NULL;
   int to = 0;
   int ret;

   dma.context = rmesa->hHWContext;
   dma.send_count = 0;
   dma.send_list = NULL;
   dma.send_sizes = NULL;
   dma.flags = 0;
   dma.request_count = 1;
   dma.request_size = R128_BUFFER_SIZE;
   dma.request_list = &index;
   dma.request_sizes = &size;
   dma.granted_count = 0;

   while ( !buf && ( to++ < R128_TIMEOUT ) ) {
      ret = drmDMA( fd, &dma );

      if ( ret == 0 ) {
	 buf = &rmesa->r128Screen->buffers->list[index];
	 buf->used = 0;
#if ENABLE_PERF_BOXES
	 /* Bump the performance counter */
	 rmesa->c_vertexBuffers++;
#endif
	 return buf;
      }
   }

   if ( !buf ) {
      drmCommandNone( fd, DRM_R128_CCE_RESET);
      UNLOCK_HARDWARE( rmesa );
      fprintf( stderr, "Error: Could not get new VB... exiting\n" );
      exit( -1 );
   }

   return buf;
}

void r128FlushVerticesLocked( r128ContextPtr rmesa )
{
   drm_clip_rect_t *pbox = rmesa->pClipRects;
   int nbox = rmesa->numClipRects;
   drmBufPtr buffer = rmesa->vert_buf;
   int count = rmesa->num_verts;
   int prim = rmesa->hw_primitive;
   int fd = rmesa->driScreen->fd;
   drm_r128_vertex_t vertex;
   int i;

   rmesa->num_verts = 0;
   rmesa->vert_buf = NULL;

   if ( !buffer )
      return;

   if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS )
      r128EmitHwStateLocked( rmesa );

   if ( !nbox )
      count = 0;

   if ( nbox >= R128_NR_SAREA_CLIPRECTS )
      rmesa->dirty |= R128_UPLOAD_CLIPRECTS;

   if ( !count || !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) )
   {
      if ( nbox < 3 ) {
	 rmesa->sarea->nbox = 0;
      } else {
	 rmesa->sarea->nbox = nbox;
      }

      vertex.prim = prim;
      vertex.idx = buffer->idx;
      vertex.count = count;
      vertex.discard = 1;
      drmCommandWrite( fd, DRM_R128_VERTEX, &vertex, sizeof(vertex) );
   }
   else
   {
      for ( i = 0 ; i < nbox ; ) {
	 int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox );
	 drm_clip_rect_t *b = rmesa->sarea->boxes;
	 int discard = 0;

	 rmesa->sarea->nbox = nr - i;
	 for ( ; i < nr ; i++ ) {
	    *b++ = pbox[i];
	 }

	 /* Finished with the buffer?
	  */
	 if ( nr == nbox ) {
	    discard = 1;
	 }

	 rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS;

         vertex.prim = prim;
         vertex.idx = buffer->idx;
         vertex.count = count;
         vertex.discard = discard;
         drmCommandWrite( fd, DRM_R128_VERTEX, &vertex, sizeof(vertex) );
      }
   }

   rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS;
}





/* ================================================================
 * Texture uploads
 */

void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer,
			 GLint offset, GLint pitch, GLint format,
			 GLint x, GLint y, GLint width, GLint height )
{
   drm_r128_blit_t blit;
   GLint ret;

   blit.idx = buffer->idx;
   blit.offset = offset;
   blit.pitch = pitch;
   blit.format = format;
   blit.x = x;
   blit.y = y;
   blit.width = width;
   blit.height = height;

   ret = drmCommandWrite( rmesa->driFd, DRM_R128_BLIT, 
                          &blit, sizeof(blit) );

   if ( ret ) {
      UNLOCK_HARDWARE( rmesa );
      fprintf( stderr, "DRM_R128_BLIT: return = %d\n", ret );
      exit( 1 );
   }
}


/* ================================================================
 * SwapBuffers with client-side throttling
 */

static void delay( void ) {
/* Prevent an optimizing compiler from removing a spin loop */
}

#define R128_MAX_OUTSTANDING	2


/* Throttle the frame rate -- only allow one pending swap buffers
 * request at a time.
 * GH: We probably don't want a timeout here, as we can wait as
 * long as we want for a frame to complete.  If it never does, then
 * the card has locked.
 */
static int r128WaitForFrameCompletion( r128ContextPtr rmesa )
{
   unsigned char *R128MMIO = rmesa->r128Screen->mmio.map;
   int i;
   int wait = 0;

   while ( 1 ) {
      u_int32_t frame = read_MMIO_LE32( R128MMIO, R128_LAST_FRAME_REG );

      if ( rmesa->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) {
	 break;
      }

      /* Spin in place a bit so we aren't hammering the register */
      wait++;
      for ( i = 0 ; i < 1024 ; i++ ) {
	 delay();
      }
   }

   return wait;
}

/* Copy the back color buffer to the front color buffer.
 */
void r128CopyBuffer( __DRIdrawablePrivate *dPriv )
{
   r128ContextPtr rmesa;
   GLint nbox, i, ret;
   GLboolean missed_target;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;

   if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "\n********************************\n" );
      fprintf( stderr, "\n%s( %p )\n\n",
	       __FUNCTION__, (void *)rmesa->glCtx );
      fflush( stderr );
   }

   FLUSH_BATCH( rmesa );

   LOCK_HARDWARE( rmesa );

   /* Throttle the frame rate -- only allow one pending swap buffers
    * request at a time.
    */
   if ( !r128WaitForFrameCompletion( rmesa ) ) {
      rmesa->hardwareWentIdle = 1;
   } else {
      rmesa->hardwareWentIdle = 0;
   }

   UNLOCK_HARDWARE( rmesa );
   driWaitForVBlank( dPriv, &missed_target );
   LOCK_HARDWARE( rmesa );

   nbox = dPriv->numClipRects;	/* must be in locked region */

   for ( i = 0 ; i < nbox ; ) {
      GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , nbox );
      drm_clip_rect_t *box = dPriv->pClipRects;
      drm_clip_rect_t *b = rmesa->sarea->boxes;
      GLint n = 0;

      for ( ; i < nr ; i++ ) {
	 *b++ = box[i];
	 n++;
      }
      rmesa->sarea->nbox = n;

      ret = drmCommandNone( rmesa->driFd, DRM_R128_SWAP );

      if ( ret ) {
	 UNLOCK_HARDWARE( rmesa );
	 fprintf( stderr, "DRM_R128_SWAP: return = %d\n", ret );
	 exit( 1 );
      }
   }

   if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) {
      i = 0;
      do {
         ret = drmCommandNone(rmesa->driFd, DRM_R128_CCE_IDLE);
      } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
   }

   UNLOCK_HARDWARE( rmesa );

   rmesa->new_state |= R128_NEW_CONTEXT;
   rmesa->dirty |= (R128_UPLOAD_CONTEXT |
		    R128_UPLOAD_MASKS |
		    R128_UPLOAD_CLIPRECTS);

#if ENABLE_PERF_BOXES
   /* Log the performance counters if necessary */
   r128PerformanceCounters( rmesa );
#endif
}

void r128PageFlip( __DRIdrawablePrivate *dPriv )
{
   r128ContextPtr rmesa;
   GLint ret;
   GLboolean missed_target;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;

   if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "\n%s( %p ): page=%d\n\n",
	       __FUNCTION__, (void *)rmesa->glCtx, rmesa->sarea->pfCurrentPage );
   }

   FLUSH_BATCH( rmesa );

   LOCK_HARDWARE( rmesa );

   /* Throttle the frame rate -- only allow one pending swap buffers
    * request at a time.
    */
   if ( !r128WaitForFrameCompletion( rmesa ) ) {
      rmesa->hardwareWentIdle = 1;
   } else {
      rmesa->hardwareWentIdle = 0;
   }

   UNLOCK_HARDWARE( rmesa );
   driWaitForVBlank( dPriv, &missed_target );
   LOCK_HARDWARE( rmesa );

   /* The kernel will have been initialized to perform page flipping
    * on a swapbuffers ioctl.
    */
   ret = drmCommandNone( rmesa->driFd, DRM_R128_FLIP );

   UNLOCK_HARDWARE( rmesa );

   if ( ret ) {
      fprintf( stderr, "DRM_R128_FLIP: return = %d\n", ret );
      exit( 1 );
   }

   /* Get ready for drawing next frame.  Update the renderbuffers'
    * flippedOffset/Pitch fields so we draw into the right place.
    */
   driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,
                        rmesa->sarea->pfCurrentPage);

   rmesa->new_state |= R128_NEW_WINDOW;

   /* FIXME: Do we need this anymore? */
   rmesa->new_state |= R128_NEW_CONTEXT;
   rmesa->dirty |= (R128_UPLOAD_CONTEXT |
		    R128_UPLOAD_MASKS |
		    R128_UPLOAD_CLIPRECTS);

#if ENABLE_PERF_BOXES
   /* Log the performance counters if necessary */
   r128PerformanceCounters( rmesa );
#endif
}


/* ================================================================
 * Buffer clear
 */

static void r128Clear( GLcontext *ctx, GLbitfield mask )
{
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
   drm_r128_clear_t clear;
   GLuint flags = 0;
   GLint i;
   GLint ret;
   GLuint depthmask = 0;
   GLint cx, cy, cw, ch;

   if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s:\n", __FUNCTION__ );
   }

   FLUSH_BATCH( rmesa );

   /* The only state change we care about here is the RGBA colormask
    * We'll just update that state, if needed.  If we do more then
    * there's some strange side-effects that the conformance tests find.
    */
   if ( rmesa->new_state & R128_NEW_MASKS) {
      const GLuint save_state = rmesa->new_state;
      rmesa->new_state = R128_NEW_MASKS;
      r128DDUpdateHWState( ctx );
      rmesa->new_state = save_state & ~R128_NEW_MASKS;
   }

   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
      flags |= R128_FRONT;
      mask &= ~BUFFER_BIT_FRONT_LEFT;
   }

   if ( mask & BUFFER_BIT_BACK_LEFT ) {
      flags |= R128_BACK;
      mask &= ~BUFFER_BIT_BACK_LEFT;
   }

   if ( ( mask & BUFFER_BIT_DEPTH ) && ctx->Depth.Mask ) {
      flags |= R128_DEPTH;
      /* if we're at 16 bits, extra plane mask won't hurt */
      depthmask |= 0x00ffffff;
      mask &= ~BUFFER_BIT_DEPTH;
   }

   if ( mask & BUFFER_BIT_STENCIL &&
	(ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24) ) {
      flags |= R128_DEPTH;
      depthmask |= ctx->Stencil.WriteMask[0] << 24;
      mask &= ~BUFFER_BIT_STENCIL;
   }

   if ( flags ) {

      LOCK_HARDWARE( rmesa );

      /* compute region after locking: */
      cx = ctx->DrawBuffer->_Xmin;
      cy = ctx->DrawBuffer->_Ymin;
      cw = ctx->DrawBuffer->_Xmax - cx;
      ch = ctx->DrawBuffer->_Ymax - cy;

      /* Flip top to bottom */
      cx += dPriv->x;
      cy  = dPriv->y + dPriv->h - cy - ch;

      /* FIXME: Do we actually need this?
       */
      if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) {
	 r128EmitHwStateLocked( rmesa );
      }

      for ( i = 0 ; i < rmesa->numClipRects ; ) {
	 GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , rmesa->numClipRects );
	 drm_clip_rect_t *box = rmesa->pClipRects;
	 drm_clip_rect_t *b = rmesa->sarea->boxes;
	 GLint n = 0;

	 if (cw != dPriv->w || ch != dPriv->h) {
            /* clear subregion */
	    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 {
            /* clear whole window */
	    for ( ; i < nr ; i++ ) {
	       *b++ = box[i];
	       n++;
	    }
	 }

	 rmesa->sarea->nbox = n;

	 if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) {
	    fprintf( stderr,
		     "DRM_R128_CLEAR: flag 0x%x color %x depth %x nbox %d\n",
		     flags,
		     (GLuint)rmesa->ClearColor,
		     (GLuint)rmesa->ClearDepth,
		     rmesa->sarea->nbox );
	 }

         clear.flags = flags;
         clear.clear_color = rmesa->ClearColor;
         clear.clear_depth = rmesa->ClearDepth;
         clear.color_mask = rmesa->setup.plane_3d_mask_c;
         clear.depth_mask = depthmask;

         ret = drmCommandWrite( rmesa->driFd, DRM_R128_CLEAR,
                                &clear, sizeof(clear) );

	 if ( ret ) {
	    UNLOCK_HARDWARE( rmesa );
	    fprintf( stderr, "DRM_R128_CLEAR: return = %d\n", ret );
	    exit( 1 );
	 }
      }

      UNLOCK_HARDWARE( rmesa );

      rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
   }

   if ( mask )
      _swrast_Clear( ctx, mask );
}


/* ================================================================
 * Depth spans, pixels
 */

void r128WriteDepthSpanLocked( r128ContextPtr rmesa,
			       GLuint n, GLint x, GLint y,
			       const GLuint depth[],
			       const GLubyte mask[] )
{
   drm_clip_rect_t *pbox = rmesa->pClipRects;
   drm_r128_depth_t d;
   int nbox = rmesa->numClipRects;
   int fd = rmesa->driScreen->fd;
   int i;

   if ( !nbox || !n ) {
      return;
   }
   if ( nbox >= R128_NR_SAREA_CLIPRECTS ) {
      rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
   }

   if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) )
   {
      if ( nbox < 3 ) {
	 rmesa->sarea->nbox = 0;
      } else {
	 rmesa->sarea->nbox = nbox;
      }

      d.func = R128_WRITE_SPAN;
      d.n = n;
      d.x = (int*)&x;
      d.y = (int*)&y;
      d.buffer = (unsigned int *)depth;
      d.mask = (unsigned char *)mask;

      drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));

   }
   else
   {
      for (i = 0 ; i < nbox ; ) {
	 int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox );
	 drm_clip_rect_t *b = rmesa->sarea->boxes;

	 rmesa->sarea->nbox = nr - i;
	 for ( ; i < nr ; i++) {
	    *b++ = pbox[i];
	 }

	 rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS;

         d.func = R128_WRITE_SPAN;
         d.n = n;
         d.x = (int*)&x;
         d.y = (int*)&y;
         d.buffer = (unsigned int *)depth;
         d.mask = (unsigned char *)mask;

         drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
      }
   }

   rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS;
}

void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n,
				 const GLint x[], const GLint y[],
				 const GLuint depth[],
				 const GLubyte mask[] )
{
   drm_clip_rect_t *pbox = rmesa->pClipRects;
   drm_r128_depth_t d;
   int nbox = rmesa->numClipRects;
   int fd = rmesa->driScreen->fd;
   int i;

   if ( !nbox || !n ) {
      return;
   }
   if ( nbox >= R128_NR_SAREA_CLIPRECTS ) {
      rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
   }

   if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) )
   {
      if ( nbox < 3 ) {
	 rmesa->sarea->nbox = 0;
      } else {
	 rmesa->sarea->nbox = nbox;
      }

      d.func = R128_WRITE_PIXELS;
      d.n = n;
      d.x = (int*)&x;
      d.y = (int*)&y;
      d.buffer = (unsigned int *)depth;
      d.mask = (unsigned char *)mask;

      drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
   }
   else
   {
      for (i = 0 ; i < nbox ; ) {
	 int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox );
	 drm_clip_rect_t *b = rmesa->sarea->boxes;

	 rmesa->sarea->nbox = nr - i;
	 for ( ; i < nr ; i++) {
	    *b++ = pbox[i];
	 }

	 rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS;

         d.func = R128_WRITE_PIXELS;
         d.n = n;
         d.x = (int*)&x;
         d.y = (int*)&y;
         d.buffer = (unsigned int *)depth;
         d.mask = (unsigned char *)mask;

         drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
      }
   }

   rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS;
}

void r128ReadDepthSpanLocked( r128ContextPtr rmesa,
			      GLuint n, GLint x, GLint y )
{
   drm_clip_rect_t *pbox = rmesa->pClipRects;
   drm_r128_depth_t d;
   int nbox = rmesa->numClipRects;
   int fd = rmesa->driScreen->fd;
   int i;

   if ( !nbox || !n ) {
      return;
   }
   if ( nbox >= R128_NR_SAREA_CLIPRECTS ) {
      rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
   }

   if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) )
   {
      if ( nbox < 3 ) {
	 rmesa->sarea->nbox = 0;
      } else {
	 rmesa->sarea->nbox = nbox;
      }

      d.func = R128_READ_SPAN;
      d.n = n;
      d.x = (int*)&x;
      d.y = (int*)&y;
      d.buffer = NULL;
      d.mask = NULL;

      drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
   }
   else
   {
      for (i = 0 ; i < nbox ; ) {
	 int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox );
	 drm_clip_rect_t *b = rmesa->sarea->boxes;

	 rmesa->sarea->nbox = nr - i;
	 for ( ; i < nr ; i++) {
	    *b++ = pbox[i];
	 }

	 rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS;

         d.func = R128_READ_SPAN;
         d.n = n;
         d.x = (int*)&x;
         d.y = (int*)&y;
         d.buffer = NULL;
         d.mask = NULL;

         drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
      }
   }

   rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS;
}

void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n,
				const GLint x[], const GLint y[] )
{
   drm_clip_rect_t *pbox = rmesa->pClipRects;
   drm_r128_depth_t d;
   int nbox = rmesa->numClipRects;
   int fd = rmesa->driScreen->fd;
   int i;

   if ( !nbox || !n ) {
      return;
   }
   if ( nbox >= R128_NR_SAREA_CLIPRECTS ) {
      rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
   }

   if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) )
   {
      if ( nbox < 3 ) {
	 rmesa->sarea->nbox = 0;
      } else {
	 rmesa->sarea->nbox = nbox;
      }

      d.func = R128_READ_PIXELS;
      d.n = n;
      d.x = (int*)&x;
      d.y = (int*)&y;
      d.buffer = NULL;
      d.mask = NULL;

      drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
   }
   else
   {
      for (i = 0 ; i < nbox ; ) {
	 int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox );
	 drm_clip_rect_t *b = rmesa->sarea->boxes;

	 rmesa->sarea->nbox = nr - i;
	 for ( ; i < nr ; i++) {
	    *b++ = pbox[i];
	 }

	 rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS;

         d.func = R128_READ_PIXELS;
         d.n = n;
         d.x = (int*)&x;
         d.y = (int*)&y;
         d.buffer = NULL;
         d.mask = NULL;

         drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(d));
      }
   }

   rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS;
}


void r128WaitForIdleLocked( r128ContextPtr rmesa )
{
    int fd = rmesa->r128Screen->driScreen->fd;
    int to = 0;
    int ret, i;

    do {
        i = 0;
        do {
            ret = drmCommandNone( fd, DRM_R128_CCE_IDLE);
        } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
    } while ( ( ret == -EBUSY ) && ( to++ < R128_TIMEOUT ) );

    if ( ret < 0 ) {
        drmCommandNone( fd, DRM_R128_CCE_RESET);
	UNLOCK_HARDWARE( rmesa );
	fprintf( stderr, "Error: Rage 128 timed out... exiting\n" );
	exit( -1 );
    }
}

void r128InitIoctlFuncs( struct dd_function_table *functions )
{
    functions->Clear = r128Clear;
}
