From e5b244ff7f984805c1bcc020342f1300f2639c71 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Apr 2003 15:02:17 +0000 Subject: Implemented GL_EXT_depth_bounds_test. --- src/mesa/main/depth.c | 32 ++++++++++++-- src/mesa/main/depth.h | 8 ++-- src/mesa/main/dlist.c | 32 ++++++++++++++ src/mesa/main/enable.c | 19 +++++++++ src/mesa/main/extensions.c | 8 ++++ src/mesa/main/get.c | 44 +++++++++++++++++++ src/mesa/main/mtypes.h | 3 ++ src/mesa/main/state.c | 4 -- src/mesa/swrast/s_depth.c | 103 +++++++++++++++++++++++++++++++++++++++++++-- src/mesa/swrast/s_depth.h | 10 ++--- src/mesa/swrast/s_span.c | 22 +++++++++- 11 files changed, 263 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index 8383bcc608..9d95500fca 100644 --- a/src/mesa/main/depth.c +++ b/src/mesa/main/depth.c @@ -1,10 +1,8 @@ -/* $Id: depth.c,v 1.31 2002/10/24 23:57:20 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"), @@ -116,3 +114,29 @@ _mesa_DepthMask( GLboolean flag ) if (ctx->Driver.DepthMask) ctx->Driver.DepthMask( ctx, flag ); } + + + +/* GL_EXT_depth_bounds_test */ +void +_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (zmin > zmax) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDepthBoundsEXT(zmin > zmax)"); + return; + } + + zmin = CLAMP(zmin, 0.0, 1.0); + zmax = CLAMP(zmax, 0.0, 1.0); + + if (ctx->Depth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax) + return; + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.BoundsMin = zmin; + ctx->Depth.BoundsMax = zmax; +} + diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h index e9c2885b7f..b90d723b38 100644 --- a/src/mesa/main/depth.h +++ b/src/mesa/main/depth.h @@ -1,10 +1,8 @@ -/* $Id: depth.h,v 1.11 2001/03/12 00:48:37 gareth Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 5.1 * - * Copyright (C) 1999-2001 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"), @@ -48,6 +46,8 @@ extern void _mesa_DepthMask( GLboolean flag ); +extern void +_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ); #endif diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index d47437face..4399385cc1 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -255,6 +255,8 @@ typedef enum { OPCODE_PROGRAM_NAMED_PARAMETER_NV, /* GL_EXT_stencil_two_side */ OPCODE_ACTIVE_STENCIL_FACE_EXT, + /* GL_EXT_depth_bounds_test */ + OPCODE_DEPTH_BOUNDS_EXT, /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, @@ -671,6 +673,8 @@ void _mesa_init_lists( void ) InstSize[OPCODE_PROGRAM_NAMED_PARAMETER_NV] = 8; /* GL_EXT_stencil_two_side */ InstSize[OPCODE_ACTIVE_STENCIL_FACE_EXT] = 2; + /* GL_EXT_depth_bounds_test */ + InstSize[OPCODE_DEPTH_BOUNDS_EXT] = 3; } init_flag = 1; } @@ -4366,6 +4370,24 @@ static void save_ActiveStencilFaceEXT( GLenum face ) } +/* GL_EXT_depth_bounds_test */ +static void save_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 2 ); + if (n) { + n[1].f = zmin; + n[2].f = zmax; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->DepthBoundsEXT)( zmin, zmax ); + } +} + + + /* KW: Compile commands * @@ -5107,6 +5129,13 @@ execute_list( GLcontext *ctx, GLuint list ) break; #endif + case OPCODE_ACTIVE_STENCIL_FACE_EXT: + (*ctx->Exec->ActiveStencilFaceEXT)(n[1].e); + break; + case OPCODE_DEPTH_BOUNDS_EXT: + (*ctx->Exec->DepthBoundsEXT)(n[1].f, n[2].f); + break; + case OPCODE_CONTINUE: n = (Node *) n[1].next; break; @@ -6493,6 +6522,9 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ) /* 268. GL_EXT_stencil_two_side */ table->ActiveStencilFaceEXT = save_ActiveStencilFaceEXT; + /* ???. GL_EXT_depth_bounds_test */ + table->DepthBoundsEXT = save_DepthBoundsEXT; + /* ARB 1. GL_ARB_multitexture */ table->ActiveTextureARB = save_ActiveTextureARB; table->ClientActiveTextureARB = exec_ClientActiveTextureARB; diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 5fe6549312..747c3f63c1 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -923,6 +923,20 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) break; #endif /* FEATURE_ARB_fragment_program */ + /* GL_EXT_depth_bounds_test */ + case GL_DEPTH_BOUNDS_TEST_EXT: + CHECK_EXTENSION(EXT_depth_bounds_test, cap); + if (state && ctx->Visual.depthBits==0) { + _mesa_warning(ctx, + "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer"); + return; + } + if (ctx->Depth.BoundsTest == state) + return; + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.BoundsTest = state; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "%s(0x%x)", state ? "glEnable" : "glDisable", cap); @@ -1319,6 +1333,11 @@ _mesa_IsEnabled( GLenum cap ) return ctx->FragmentProgram.Enabled; #endif /* FEATURE_ARB_fragment_program */ + /* GL_EXT_depth_bounds_test */ + case GL_DEPTH_BOUNDS_TEST_EXT: + CHECK_EXTENSION(EXT_depth_bounds_test); + return ctx->Depth.BoundsTest; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap); return GL_FALSE; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 59ec4c22e4..2f5bc7588f 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -81,6 +81,7 @@ static struct { { ON, "GL_EXT_clip_volume_hint", F(EXT_clip_volume_hint) }, { OFF, "GL_EXT_convolution", F(EXT_convolution) }, { ON, "GL_EXT_compiled_vertex_array", F(EXT_compiled_vertex_array) }, + { OFF, "GL_EXT_depth_bounds_test", F(EXT_depth_bounds_test) }, { OFF, "GL_EXT_fog_coord", F(EXT_fog_coord) }, { OFF, "GL_EXT_histogram", F(EXT_histogram) }, { OFF, "GL_EXT_multi_draw_arrays", F(EXT_multi_draw_arrays) }, @@ -148,6 +149,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx) { const char *extensions[] = { "GL_ARB_depth_texture", +#if FEATURE_ARB_fragment_program + "GL_ARB_fragment_program", +#endif "GL_ARB_imaging", "GL_ARB_multitexture", "GL_ARB_point_parameters", @@ -160,6 +164,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx) "GL_ARB_texture_env_crossbar", "GL_ARB_texture_env_dot3", "GL_ARB_texture_mirrored_repeat", +#if FEATURE_ARB_vertex_program + "GL_ARB_vertex_program", +#endif "GL_ATI_texture_env_combine3", "GL_ATI_texture_mirror_once", "GL_EXT_blend_color", @@ -168,6 +175,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) "GL_EXT_blend_minmax", "GL_EXT_blend_subtract", "GL_EXT_convolution", + "GL_EXT_depth_bounds_test", "GL_EXT_fog_coord", "GL_EXT_histogram", "GL_EXT_paletted_texture", diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 65c41065cf..dd1c0016a9 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1593,6 +1593,17 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) */ #endif + /* GL_EXT_depth_bounds_test */ + case GL_DEPTH_BOUNDS_TEST_EXT: + CHECK_EXTENSION_B(EXT_depth_bounds_test, pname); + params[0] = ctx->Depth.BoundsTest; + break; + case GL_DEPTH_BOUNDS_EXT: + CHECK_EXTENSION_B(EXT_depth_bounds_test, pname); + params[0] = FLOAT_TO_BOOL(ctx->Depth.BoundsMin); + params[1] = FLOAT_TO_BOOL(ctx->Depth.BoundsMax); + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); } @@ -3079,6 +3090,17 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) */ #endif + /* GL_EXT_depth_bounds_test */ + case GL_DEPTH_BOUNDS_TEST_EXT: + CHECK_EXTENSION_D(EXT_depth_bounds_test, pname); + params[0] = (GLdouble) ctx->Depth.BoundsTest; + break; + case GL_DEPTH_BOUNDS_EXT: + CHECK_EXTENSION_D(EXT_depth_bounds_test, pname); + params[0] = ctx->Depth.BoundsMin; + params[1] = ctx->Depth.BoundsMax; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev(pname=0x%x)", pname); } @@ -4541,6 +4563,17 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) */ #endif + /* GL_EXT_depth_bounds_test */ + case GL_DEPTH_BOUNDS_TEST_EXT: + CHECK_EXTENSION_F(EXT_depth_bounds_test, pname); + params[0] = (GLfloat) ctx->Depth.BoundsTest; + break; + case GL_DEPTH_BOUNDS_EXT: + CHECK_EXTENSION_F(EXT_depth_bounds_test, pname); + params[0] = ctx->Depth.BoundsMin; + params[1] = ctx->Depth.BoundsMax; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(0x%x)", pname); } @@ -6041,6 +6074,17 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) */ #endif + /* GL_EXT_depth_bounds_test */ + case GL_DEPTH_BOUNDS_TEST_EXT: + CHECK_EXTENSION_I(EXT_depth_bounds_test, pname); + params[0] = ctx->Depth.BoundsTest; + break; + case GL_DEPTH_BOUNDS_EXT: + CHECK_EXTENSION_I(EXT_depth_bounds_test, pname); + params[0] = (GLint) ctx->Depth.BoundsMin; + params[1] = (GLint) ctx->Depth.BoundsMax; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index edea218095..b906ef4269 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -397,6 +397,8 @@ struct gl_depthbuffer_attrib { GLboolean Test; /* Depth buffering enabled flag */ GLboolean Mask; /* Depth buffer writable? */ GLboolean OcclusionTest; /* GL_HP_occlusion_test */ + GLboolean BoundsTest; /* GL_EXT_depth_bounds_test */ + GLfloat BoundsMin, BoundsMax;/* GL_EXT_depth_bounds_test */ }; @@ -1466,6 +1468,7 @@ struct gl_extensions { GLboolean EXT_clip_volume_hint; GLboolean EXT_convolution; GLboolean EXT_compiled_vertex_array; + GLboolean EXT_depth_bounds_test; GLboolean EXT_fog_coord; GLboolean EXT_histogram; GLboolean EXT_multi_draw_arrays; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 96086624c9..f14c3f9d53 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,5 +1,3 @@ -/* $Id: state.c,v 1.105 2003/04/21 14:55:17 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 5.1 @@ -536,10 +534,8 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize) /* 268. GL_EXT_stencil_two_side */ exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT; -#if 0 /* ???. GL_EXT_depth_bounds_test */ exec->DepthBoundsEXT = _mesa_DepthBoundsEXT; -#endif /* ARB 1. GL_ARB_multitexture */ exec->ActiveTextureARB = _mesa_ActiveTextureARB; diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index 109585748d..fc242be2aa 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 9cc8e94524..b972a84c56 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 231e549c5a..cce69b8c43 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; } -- cgit v1.2.3