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.
pgpC5xSYQ55DN.pgp
Description: PGP signature