Hi,

apparently I'm the first to use a full software fallback for glClear(), as I 
ran into a few problems that the attached patch should fix:
- spantmp.h doesn't check for NULL masks
- add a WriteMonoDepthSpan function to the swrast to driver interface
- use this function to clear the depth buffer in swrast when available 
(swrast depth buffer clearing completely ignores driver functions right 
now)

I decided to take it to the next level and actually start hacking on a DRI 
driver for the R300. So far I modified the R200 driver to recognize the 
R300 family and use 100% software fallbacks in this case. I will put source 
up as soon as some rasterization is actually hardware accelerated.

One thing I noticed in the process: r200Flush() unconditionally calls 
r200EmitState(). Is this really necessary? I was assuming that glFlush() 
could be a noop when it's not preceded by any rendering commands.

cu,
Nicolai
Index: drivers/dri/common/depthtmp.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/common/depthtmp.h,v
retrieving revision 1.2
diff -u -p -r1.2 depthtmp.h
--- drivers/dri/common/depthtmp.h	6 Aug 2003 18:12:22 -0000	1.2
+++ drivers/dri/common/depthtmp.h	23 Sep 2004 23:27:25 -0000
@@ -64,6 +64,42 @@ static void TAG(WriteDepthSpan)( GLconte
    HW_WRITE_UNLOCK();
 }
 
+static void TAG(WriteMonoDepthSpan)( GLcontext *ctx,
+                                 GLuint n, GLint x, GLint y,
+				 const GLdepth depth,
+				 const GLubyte mask[] )
+{
+   HW_WRITE_LOCK()
+      {
+	 GLint x1;
+	 GLint n1;
+	 LOCAL_DEPTH_VARS;
+
+	 y = Y_FLIP( y );
+
+	 HW_CLIPLOOP()
+	    {
+	       GLint i = 0;
+	       CLIPSPAN( x, y, n, x1, n1, i );
+
+	       if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
+				   __FUNCTION__, (int)i, (int)n1, (int)x1, (uint)depth );
+
+	       if ( mask ) {
+		  for ( ; i < n1 ; i++, x1++ ) {
+		     if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
+		  }
+	       } else {
+		  for ( ; i < n1 ; i++, x1++ ) {
+		     WRITE_DEPTH( x1, y, depth );
+		  }
+	       }
+	    }
+	 HW_ENDCLIPLOOP();
+      }
+   HW_WRITE_UNLOCK();
+}
+
 static void TAG(WriteDepthPixels)( GLcontext *ctx,
 				   GLuint n,
 				   const GLint x[],
Index: drivers/dri/common/spantmp.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/common/spantmp.h,v
retrieving revision 1.2
diff -u -p -r1.2 spantmp.h
--- drivers/dri/common/spantmp.h	6 Aug 2003 18:12:22 -0000	1.2
+++ drivers/dri/common/spantmp.h	23 Sep 2004 23:27:25 -0000
@@ -123,15 +123,29 @@ static void TAG(WriteRGBAPixels)( const 
 
 	 HW_WRITE_CLIPLOOP()
 	    {
-	       for (i=0;i<n;i++)
+	       if (mask)
 	       {
-		  if (mask[i]) {
+	          for (i=0;i<n;i++)
+	          {
+		     if (mask[i]) {
+		        const int fy = Y_FLIP(y[i]);
+		        if (CLIPPIXEL(x[i],fy))
+			   WRITE_RGBA( x[i], fy,
+				       rgba[i][0], rgba[i][1],
+				       rgba[i][2], rgba[i][3] );
+		     }
+	          }
+	       }
+	       else
+	       {
+	          for (i=0;i<n;i++)
+	          {
 		     const int fy = Y_FLIP(y[i]);
 		     if (CLIPPIXEL(x[i],fy))
 			WRITE_RGBA( x[i], fy,
 				    rgba[i][0], rgba[i][1],
 				    rgba[i][2], rgba[i][3] );
-		  }
+	          }
 	       }
 	    }
 	 HW_ENDCLIPLOOP();
@@ -160,9 +174,17 @@ static void TAG(WriteMonoRGBASpan)( cons
 	    {
 	       GLint i = 0;
 	       CLIPSPAN(x,y,n,x1,n1,i);
-	       for (;n1>0;i++,x1++,n1--)
-		  if (mask[i])
+	       if (mask)
+	       {
+	          for (;n1>0;i++,x1++,n1--)
+		     if (mask[i])
+		        WRITE_PIXEL( x1, y, p );
+	       }
+	       else
+	       {
+	          for (;n1>0;i++,x1++,n1--)
 		     WRITE_PIXEL( x1, y, p );
+	       }
 	    }
 	 HW_ENDCLIPLOOP();
       }
@@ -186,12 +208,23 @@ static void TAG(WriteMonoRGBAPixels)( co
 
 	 HW_WRITE_CLIPLOOP()
 	    {
-	       for (i=0;i<n;i++)
-		  if (mask[i]) {
+	       if (mask)
+	       {
+		  for (i=0;i<n;i++)
+		     if (mask[i]) {
+			int fy = Y_FLIP(y[i]);
+			if (CLIPPIXEL( x[i], fy ))
+			   WRITE_PIXEL( x[i], fy, p );
+		     }
+	       }
+	       else
+	       {
+		  for (i=0;i<n;i++) {
 		     int fy = Y_FLIP(y[i]);
 		     if (CLIPPIXEL( x[i], fy ))
 			WRITE_PIXEL( x[i], fy, p );
 		  }
+	       }
 	    }
 	 HW_ENDCLIPLOOP();
       }
@@ -238,12 +271,23 @@ static void TAG(ReadRGBAPixels)( const G
 
 	 HW_READ_CLIPLOOP()
 	    {
-	       for (i=0;i<n;i++)
-		  if (mask[i]) {
+	       if (mask)
+	       {
+		  for (i=0;i<n;i++)
+		     if (mask[i]) {
+			int fy = Y_FLIP( y[i] );
+			if (CLIPPIXEL( x[i], fy ))
+			   READ_RGBA( rgba[i], x[i], fy );
+		     }
+	       }
+	       else
+	       {
+		  for (i=0;i<n;i++) {
 		     int fy = Y_FLIP( y[i] );
 		     if (CLIPPIXEL( x[i], fy ))
 			READ_RGBA( rgba[i], x[i], fy );
 		  }
+	       }
 	    }
 	 HW_ENDCLIPLOOP();
       }
Index: swrast/s_depth.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/swrast/s_depth.c,v
retrieving revision 1.27
diff -u -p -b -r1.27 s_depth.c
--- swrast/s_depth.c	21 Apr 2003 15:02:17 -0000	1.27
+++ swrast/s_depth.c	23 Sep 2004 23:25:40 -0000
@@ -1665,13 +1665,33 @@ _swrast_alloc_depth_buffer( GLframebuffe
 void
 _swrast_clear_depth_buffer( GLcontext *ctx )
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
    if (ctx->Visual.depthBits == 0
-       || !ctx->DrawBuffer->DepthBuffer
        || !ctx->Depth.Mask) {
       /* no depth buffer, or writing to it is disabled */
       return;
    }
 
+   if (swrast->Driver.WriteMonoDepthSpan) {
+      const GLdepth clearValue = (GLdepth)(ctx->Depth.Clear * ctx->DepthMax);
+      const GLint x = ctx->DrawBuffer->_Xmin;
+      const GLint y = ctx->DrawBuffer->_Ymin;
+      const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
+      const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+      GLint i;
+
+      for (i = 0; i < height; i++) {
+         (*swrast->Driver.WriteMonoDepthSpan)( ctx, width, x, y + i,
+                                               clearValue, NULL );
+      }
+
+      return;
+   }
+
+   if (!ctx->DrawBuffer->DepthBuffer)
+      return;
+
    /* The loops in this function have been written so the IRIX 5.3
     * C compiler can unroll them.  Hopefully other compilers can too!
     */
Index: swrast/swrast.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/swrast/swrast.h,v
retrieving revision 1.40
diff -u -p -b -r1.40 swrast.h
--- swrast/swrast.h	21 Mar 2004 17:05:05 -0000	1.40
+++ swrast/swrast.h	23 Sep 2004 23:25:41 -0000
@@ -403,6 +403,13 @@ struct swrast_device_driver {
     * depth[i] value if mask[i] is nonzero.
     */
 
+   void (*WriteMonoDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
+                               const GLdepth depth, const GLubyte mask[] );
+   /* Write a horizontal run of depth values.
+    * If mask is NULL, draw all pixels.
+    * If mask is not null, only draw pixel [i] when mask [i] is true.
+    */
+
    void (*ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
                           GLdepth depth[] );
    /* Read a horizontal span of values from the depth buffer.

Attachment: pgpC5xSYQ55DN.pgp
Description: PGP signature

Reply via email to