diff options
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r-- | src/mesa/swrast/s_depth.c | 103 | ||||
-rw-r--r-- | src/mesa/swrast/s_depth.h | 10 | ||||
-rw-r--r-- | src/mesa/swrast/s_span.c | 22 |
3 files changed, 125 insertions, 10 deletions
diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index 109585748de..fc242be2aab 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -1,10 +1,8 @@ -/* $Id: s_depth.c,v 1.26 2003/03/25 02:23:45 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 5.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 Brian Paul 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"), @@ -1364,6 +1362,103 @@ _swrast_depth_test_span( GLcontext *ctx, struct sw_span *span) } +/** + * GL_EXT_depth_bounds_test extension. + * Discard fragments depending on whether the corresponding Z-buffer + * values are outside the depth bounds test range. + * Note: we test the Z buffer values, not the fragment Z values! + * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass + */ +GLboolean +_swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLdepth zMin = (GLdepth) (ctx->Depth.BoundsMin * ctx->DepthMaxF + 0.5F); + GLdepth zMax = (GLdepth) (ctx->Depth.BoundsMax * ctx->DepthMaxF + 0.5F); + GLubyte *mask = span->array->mask; + GLuint i; + GLboolean anyPass = GL_FALSE; + + if (swrast->Driver.ReadDepthPixels) { + /* read depth values from hardware Z buffer */ + GLdepth zbuffer[MAX_WIDTH]; + ASSERT(span->end <= MAX_WIDTH); + if (span->arrayMask & SPAN_XY) + (*swrast->Driver.ReadDepthPixels)(ctx, span->end, span->array->x, + span->array->y, zbuffer); + else + (*swrast->Driver.ReadDepthSpan)(ctx, span->end, span->x, span->y, + zbuffer); + for (i = 0; i < span->end; i++) { + if (mask[i]) { + if (zbuffer[i] < zMin || zbuffer[i] > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + else { + /* software Z buffer */ + if (span->arrayMask & SPAN_XY) { + if (ctx->Visual.depthBits <= 16) { + /* 16 bits / Z */ + for (i = 0; i < span->end; i++) { + if (mask[i]) { + const GLushort *zPtr = Z_ADDRESS16(ctx, span->array->x[i], + span->array->y[i]); + if (*zPtr < zMin || *zPtr > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + else { + /* 32 bits / Z */ + for (i = 0; i < span->end; i++) { + if (mask[i]) { + const GLuint *zPtr = Z_ADDRESS32(ctx, span->array->x[i], + span->array->y[i]); + if (*zPtr < zMin || *zPtr > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + } + else { + if (ctx->Visual.depthBits <= 16) { + /* 16 bits / Z */ + const GLushort *zPtr = Z_ADDRESS16(ctx, span->x, span->y); + for (i = 0; i < span->end; i++) { + if (mask[i]) { + if (zPtr[i] < zMin || zPtr[i] > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + else { + /* 32 bits / Z */ + const GLuint *zPtr = Z_ADDRESS32(ctx, span->x, span->y); + for (i = 0; i < span->end; i++) { + if (mask[i]) { + if (zPtr[i] < zMin || zPtr[i] > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; + } + } + } + } + } + return anyPass; +} + + /**********************************************************************/ /***** Read Depth Buffer *****/ diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h index 9cc8e94524a..b972a84c56f 100644 --- a/src/mesa/swrast/s_depth.h +++ b/src/mesa/swrast/s_depth.h @@ -1,10 +1,8 @@ -/* $Id: s_depth.h,v 1.8 2003/03/25 02:23:45 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 5.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 Brian Paul 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"), @@ -37,11 +35,13 @@ extern GLvoid * _swrast_zbuffer_address(GLcontext *ctx, GLint x, GLint y); - extern GLuint _swrast_depth_test_span( GLcontext *ctx, struct sw_span *span); +extern GLboolean +_swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span ); + extern void _swrast_read_depth_span( GLcontext *ctx, diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 231e549c5ae..cce69b8c439 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -792,6 +792,13 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) } } + /* Depth bounds test */ + if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) { + if (!_swrast_depth_bounds_test(ctx, span)) { + return; + } + } + #ifdef DEBUG if (span->arrayMask & SPAN_XY) { GLuint i; @@ -962,6 +969,13 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) } } + /* Depth bounds test */ + if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) { + if (!_swrast_depth_bounds_test(ctx, span)) { + return; + } + } + #ifdef DEBUG if (span->arrayMask & SPAN_XY) { GLuint i; @@ -1168,6 +1182,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) { const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint origInterpMask = span->interpMask; const GLuint origArrayMask = span->arrayMask; ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || @@ -1253,6 +1268,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) if (ctx->Stencil.Enabled) { if (!_swrast_stencil_and_ztest_span(ctx, span)) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -1262,6 +1278,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) ASSERT(span->arrayMask & SPAN_Z); /* regular depth testing */ if (!_swrast_depth_test_span(ctx, span)) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -1275,6 +1292,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) * the occlusion test. */ if (colorMask == 0x0) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -1336,11 +1354,12 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) _swrast_blend_span(ctx, span, span->array->rgba); } + /* Color component masking */ if (colorMask != 0xffffffff) { _swrast_mask_rgba_span(ctx, span, span->array->rgba); } - + /* write pixels */ if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x, @@ -1365,6 +1384,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) } } + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; } |