| |
| /* |
| * Notes: |
| * 1. These functions plug into the gl_renderbuffer structure. |
| * 2. The 'values' parameter always points to GLuint values, regardless of |
| * the actual Z buffer depth. |
| */ |
| |
| |
| #include "spantmp_common.h" |
| |
| #ifndef DBG |
| #define DBG 0 |
| #endif |
| |
| #ifndef HAVE_HW_DEPTH_SPANS |
| #define HAVE_HW_DEPTH_SPANS 0 |
| #endif |
| |
| #ifndef HAVE_HW_DEPTH_PIXELS |
| #define HAVE_HW_DEPTH_PIXELS 0 |
| #endif |
| |
| static void TAG(WriteDepthSpan)( GLcontext *ctx, |
| struct gl_renderbuffer *rb, |
| GLuint n, GLint x, GLint y, |
| const void *values, |
| const GLubyte mask[] ) |
| { |
| HW_WRITE_LOCK() |
| { |
| const VALUE_TYPE *depth = (const VALUE_TYPE *) values; |
| GLint x1; |
| GLint n1; |
| LOCAL_DEPTH_VARS; |
| |
| y = Y_FLIP( y ); |
| |
| #if HAVE_HW_DEPTH_SPANS |
| (void) x1; (void) n1; |
| |
| if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n", |
| (int)n, (int)x ); |
| |
| WRITE_DEPTH_SPAN(); |
| #else |
| HW_CLIPLOOP() |
| { |
| GLint i = 0; |
| CLIPSPAN( x, y, n, x1, n1, i ); |
| |
| if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n", |
| (int)i, (int)n1, (int)x1, mask ); |
| |
| if ( mask ) { |
| for ( ; n1>0 ; i++, x1++, n1-- ) { |
| if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] ); |
| } |
| } else { |
| for ( ; n1>0 ; i++, x1++, n1-- ) { |
| WRITE_DEPTH( x1, y, depth[i] ); |
| } |
| } |
| } |
| HW_ENDCLIPLOOP(); |
| #endif |
| } |
| HW_WRITE_UNLOCK(); |
| } |
| |
| |
| #if HAVE_HW_DEPTH_SPANS |
| /* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */ |
| static void |
| TAG(WriteMonoDepthSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, |
| GLuint n, GLint x, GLint y, |
| const void *value, const GLubyte mask[] ) |
| { |
| const GLuint depthVal = *((GLuint *) value); |
| GLuint depths[MAX_WIDTH]; |
| GLuint i; |
| for (i = 0; i < n; i++) |
| depths[i] = depthVal; |
| TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask); |
| } |
| #else |
| static void TAG(WriteMonoDepthSpan)( GLcontext *ctx, |
| struct gl_renderbuffer *rb, |
| GLuint n, GLint x, GLint y, |
| const void *value, |
| const GLubyte mask[] ) |
| { |
| HW_WRITE_LOCK() |
| { |
| const GLuint depth = *((GLuint *) value); |
| 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, (GLuint)depth ); |
| |
| if ( mask ) { |
| for ( ; n1>0 ; i++, x1++, n1-- ) { |
| if ( mask[i] ) WRITE_DEPTH( x1, y, depth ); |
| } |
| } else { |
| for ( ; n1>0 ; x1++, n1-- ) { |
| WRITE_DEPTH( x1, y, depth ); |
| } |
| } |
| } |
| HW_ENDCLIPLOOP(); |
| } |
| HW_WRITE_UNLOCK(); |
| } |
| #endif |
| |
| |
| static void TAG(WriteDepthPixels)( GLcontext *ctx, |
| struct gl_renderbuffer *rb, |
| GLuint n, |
| const GLint x[], |
| const GLint y[], |
| const void *values, |
| const GLubyte mask[] ) |
| { |
| HW_WRITE_LOCK() |
| { |
| const VALUE_TYPE *depth = (const VALUE_TYPE *) values; |
| GLuint i; |
| LOCAL_DEPTH_VARS; |
| |
| if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" ); |
| |
| #if HAVE_HW_DEPTH_PIXELS |
| (void) i; |
| |
| WRITE_DEPTH_PIXELS(); |
| #else |
| HW_CLIPLOOP() |
| { |
| if ( mask ) { |
| for ( i = 0 ; i < n ; i++ ) { |
| if ( mask[i] ) { |
| const int fy = Y_FLIP( y[i] ); |
| if ( CLIPPIXEL( x[i], fy ) ) |
| WRITE_DEPTH( x[i], fy, depth[i] ); |
| } |
| } |
| } |
| else { |
| for ( i = 0 ; i < n ; i++ ) { |
| const int fy = Y_FLIP( y[i] ); |
| if ( CLIPPIXEL( x[i], fy ) ) |
| WRITE_DEPTH( x[i], fy, depth[i] ); |
| } |
| } |
| } |
| HW_ENDCLIPLOOP(); |
| #endif |
| } |
| HW_WRITE_UNLOCK(); |
| } |
| |
| |
| /* Read depth spans and pixels |
| */ |
| static void TAG(ReadDepthSpan)( GLcontext *ctx, |
| struct gl_renderbuffer *rb, |
| GLuint n, GLint x, GLint y, |
| void *values ) |
| { |
| HW_READ_LOCK() |
| { |
| VALUE_TYPE *depth = (VALUE_TYPE *) values; |
| GLint x1, n1; |
| LOCAL_DEPTH_VARS; |
| |
| y = Y_FLIP( y ); |
| |
| if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" ); |
| |
| #if HAVE_HW_DEPTH_SPANS |
| (void) x1; (void) n1; |
| |
| READ_DEPTH_SPAN(); |
| #else |
| HW_CLIPLOOP() |
| { |
| GLint i = 0; |
| CLIPSPAN( x, y, n, x1, n1, i ); |
| for ( ; n1>0 ; i++, n1-- ) { |
| READ_DEPTH( depth[i], x+i, y ); |
| } |
| } |
| HW_ENDCLIPLOOP(); |
| #endif |
| } |
| HW_READ_UNLOCK(); |
| } |
| |
| static void TAG(ReadDepthPixels)( GLcontext *ctx, |
| struct gl_renderbuffer *rb, |
| GLuint n, |
| const GLint x[], const GLint y[], |
| void *values ) |
| { |
| HW_READ_LOCK() |
| { |
| VALUE_TYPE *depth = (VALUE_TYPE *) values; |
| GLuint i; |
| LOCAL_DEPTH_VARS; |
| |
| if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" ); |
| |
| #if HAVE_HW_DEPTH_PIXELS |
| (void) i; |
| |
| READ_DEPTH_PIXELS(); |
| #else |
| HW_CLIPLOOP() |
| { |
| for ( i = 0 ; i < n ;i++ ) { |
| int fy = Y_FLIP( y[i] ); |
| if ( CLIPPIXEL( x[i], fy ) ) |
| READ_DEPTH( depth[i], x[i], fy ); |
| } |
| } |
| HW_ENDCLIPLOOP(); |
| #endif |
| } |
| HW_READ_UNLOCK(); |
| } |
| |
| |
| /** |
| * Initialize the given renderbuffer's span routines to point to |
| * the depth/z functions we generated above. |
| */ |
| static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb) |
| { |
| rb->GetRow = TAG(ReadDepthSpan); |
| rb->GetValues = TAG(ReadDepthPixels); |
| rb->PutRow = TAG(WriteDepthSpan); |
| rb->PutRowRGB = NULL; |
| rb->PutMonoRow = TAG(WriteMonoDepthSpan); |
| rb->PutValues = TAG(WriteDepthPixels); |
| rb->PutMonoValues = NULL; |
| } |
| |
| |
| #if HAVE_HW_DEPTH_SPANS |
| #undef WRITE_DEPTH_SPAN |
| #undef WRITE_DEPTH_PIXELS |
| #undef READ_DEPTH_SPAN |
| #undef READ_DEPTH_PIXELS |
| #else |
| #undef WRITE_DEPTH |
| #undef READ_DEPTH |
| #endif |
| #undef TAG |
| #undef VALUE_TYPE |