diff options
author | Brian Paul <[email protected]> | 1999-12-10 19:09:21 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 1999-12-10 19:09:21 +0000 |
commit | 5c3bee503999fbc0d7c65462ff62f9e38fe40e33 (patch) | |
tree | 0c6d7bf09b9dbd5a50eb79cb1e1e29cd35d8edb3 | |
parent | f5abeebf491f8f8d0ae57d602fb3166b52b475b6 (diff) |
changes in hardware depth buffer support
-rw-r--r-- | src/mesa/main/context.c | 71 | ||||
-rw-r--r-- | src/mesa/main/context.h | 8 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 46 | ||||
-rw-r--r-- | src/mesa/main/depth.c | 672 | ||||
-rw-r--r-- | src/mesa/main/depth.h | 63 | ||||
-rw-r--r-- | src/mesa/main/stencil.c | 12 |
6 files changed, 512 insertions, 360 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 69d0a0320de..0d756de63e9 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.26 1999/12/04 21:23:17 brianp Exp $ */ +/* $Id: context.c,v 1.27 1999/12/10 19:09:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1277,10 +1277,11 @@ GLcontext *gl_create_context( GLvisual *visual, /* Fill in some driver defaults now. */ +#if 0 ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer; ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float; ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int; - +#endif #ifdef PROFILE init_timings( ctx ); @@ -1427,18 +1428,47 @@ void gl_destroy_context( GLcontext *ctx ) * encapsulates the depth, stencil and accum buffers and related * parameters. * Input: visual - a GLvisual pointer + * softwareDepth - create/use a software depth buffer? + * softwareStencil - create/use a software stencil buffer? + * softwareAccum - create/use a software accum buffer? + * softwareAlpha - create/use a software alpha buffer? + * Return: pointer to new GLframebuffer struct or NULL if error. */ -GLframebuffer *gl_create_framebuffer( GLvisual *visual ) +GLframebuffer *gl_create_framebuffer( GLvisual *visual, + GLboolean softwareDepth, + GLboolean softwareStencil, + GLboolean softwareAccum, + GLboolean softwareAlpha ) { GLframebuffer *buffer; - buffer = (GLframebuffer *) CALLOC( sizeof(GLframebuffer) ); + buffer = CALLOC_STRUCT(gl_frame_buffer); if (!buffer) { return NULL; } + /* sanity checks */ + if (softwareDepth ) { + assert(visual->DepthBits > 0); + } + if (softwareStencil) { + assert(visual->StencilBits > 0); + } + if (softwareAccum) { + assert(visual->RGBAflag); + assert(visual->AccumBits > 0); + } + if (softwareAlpha) { + assert(visual->RGBAflag); + assert(visual->AlphaBits > 0); + } + buffer->Visual = visual; + buffer->UseSoftwareDepthBuffer = softwareDepth; + buffer->UseSoftwareStencilBuffer = softwareStencil; + buffer->UseSoftwareAccumBuffer = softwareAccum; + buffer->UseSoftwareAlphaBuffers = softwareAlpha; return buffer; } @@ -1694,15 +1724,15 @@ _mesa_ResizeBuffersMESA( void ) ctx->DrawBuffer->Height = buf_height; /* Reallocate other buffers if needed. */ - if (ctx->Visual->DepthBits>0) { + if (ctx->DrawBuffer->UseSoftwareDepthBuffer) { /* reallocate depth buffer */ - (*ctx->Driver.AllocDepthBuffer)( ctx ); + gl_alloc_depth_buffer( ctx ); } - if (ctx->Visual->StencilBits>0) { + if (ctx->DrawBuffer->UseSoftwareStencilBuffer) { /* reallocate stencil buffer */ gl_alloc_stencil_buffer( ctx ); } - if (ctx->Visual->AccumBits>0) { + if (ctx->DrawBuffer->UseSoftwareAccumBuffer) { /* reallocate accum buffer */ gl_alloc_accum_buffer( ctx ); } @@ -2197,31 +2227,6 @@ void gl_update_state( GLcontext *ctx ) ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1; } } - - /* The driver isn't managing the depth buffer. - */ - if (ctx->Driver.AllocDepthBuffer == gl_alloc_depth_buffer) - { - if (ctx->Depth.Mask) { - switch (ctx->Depth.Func) { - case GL_LESS: - ctx->Driver.DepthTestSpan = gl_depth_test_span_less; - ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less; - break; - case GL_GREATER: - ctx->Driver.DepthTestSpan = gl_depth_test_span_greater; - ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater; - break; - default: - ctx->Driver.DepthTestSpan = gl_depth_test_span_generic; - ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic; - } - } - else { - ctx->Driver.DepthTestSpan = gl_depth_test_span_generic; - ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic; - } - } } if (ctx->NewState & NEW_LIGHTING) { diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index df510afb3f6..32dd613c140 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -1,4 +1,4 @@ -/* $Id: context.h,v 1.4 1999/11/24 18:48:31 brianp Exp $ */ +/* $Id: context.h,v 1.5 1999/12/10 19:09:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -97,7 +97,11 @@ extern void gl_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask); * It bundles up the depth buffer, stencil buffer and accum buffers into a * single entity. */ -extern GLframebuffer *gl_create_framebuffer( GLvisual *visual ); +extern GLframebuffer *gl_create_framebuffer( GLvisual *visual, + GLboolean softwareDepth, + GLboolean softwareStencil, + GLboolean softwareAccum, + GLboolean softwareAlpha ); extern void gl_destroy_framebuffer( GLframebuffer *buffer ); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 904fa4849db..7a6d65437d7 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.7 1999/12/10 16:14:40 brianp Exp $ */ +/* $Id: dd.h,v 1.8 1999/12/10 19:09:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -393,42 +393,40 @@ struct dd_function_table { *** Either ALL or NONE of these functions must be implemented! ***/ - void (*AllocDepthBuffer)( GLcontext *ctx ); - /* - * Called when the depth buffer must be allocated or possibly resized. + void (*WriteDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth depth[], const GLubyte mask[] ); + /* Write a horizontal span of values into the depth buffer. Only write + * depth[i] value if mask[i] is nonzero. */ - GLuint (*DepthTestSpan)( GLcontext *ctx, - GLuint n, GLint x, GLint y, const GLdepth z[], - GLubyte mask[] ); - void (*DepthTestPixels)( GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); - /* - * Apply the depth buffer test to an span/array of pixels and return - * an updated pixel mask. This function is not used when accelerated - * point, line, polygon functions are used. + void (*ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLdepth depth[] ); + /* Read a horizontal span of values from the depth buffer. */ - void (*ReadDepthSpanFloat)( GLcontext *ctx, - GLuint n, GLint x, GLint y, GLfloat depth[]); - void (*ReadDepthSpanInt)( GLcontext *ctx, - GLuint n, GLint x, GLint y, GLdepth depth[] ); - /* - * Return depth values as integers for glReadPixels. - * Floats should be returned in the range [0,1]. - * Ints (GLdepth) values should be in the range [0,MAXDEPTH]. + + void (*WriteDepthPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth depth[], const GLubyte mask[] ); + /* Write an array of randomly positioned depth values into the + * depth buffer. Only write depth[i] value if mask[i] is nonzero. + */ + + void (*ReadDepthPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLdepth depth[] ); + /* Read an array of randomly positioned depth values from the depth buffer. */ + /*** *** For supporting hardware stencil buffers: *** Either ALL or NONE of these functions must be implemented! ***/ void (*WriteStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLstencil stencil[], - const GLubyte mask[] ); + const GLstencil stencil[], const GLubyte mask[] ); /* Write a horizontal span of stencil values into the stencil buffer. * If mask is NULL, write all stencil values. * Else, only write stencil[i] if mask[i] is non-zero. diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index 746b8188ba8..b2fa94757e3 100644 --- a/src/mesa/main/depth.c +++ b/src/mesa/main/depth.c @@ -1,4 +1,4 @@ -/* $Id: depth.c,v 1.10 1999/11/24 18:48:31 brianp Exp $ */ +/* $Id: depth.c,v 1.11 1999/12/10 19:09:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -24,6 +24,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #ifdef PC_HEADER #include "all.h" #else @@ -32,6 +33,7 @@ #include "enums.h" #include "depth.h" #include "mem.h" +#include "pb.h" #include "types.h" #endif @@ -128,28 +130,16 @@ _mesa_DepthMask( GLboolean flag ) /* - * Depth test horizontal spans of fragments. These functions are called - * via ctx->Driver.depth_test_span only. - * - * Input: n - number of pixels in the span - * x, y - location of leftmost pixel in span in window coords - * z - array [n] of integer depth values - * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw) - * Return: number of pixels which passed depth test - */ - - -/* - * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). + * Do depth test for an array of fragments. This is used both for + * software and hardware Z buffers. + * Input: zbuffer - array of z values in the zbuffer + * z - array of fragment z values + * Return: number of fragments which pass the test. */ -GLuint gl_depth_test_span_generic( GLcontext* ctx, - GLuint n, GLint x, GLint y, - const GLdepth z[], - GLubyte mask[] ) +static GLuint +depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLdepth zbuffer[], const GLdepth z[], GLubyte mask[] ) { - GLdepth *zptr = Z_ADDRESS( ctx, x, y ); - GLubyte *m = mask; - GLuint i; GLuint passed = 0; /* switch cases ordered from most frequent to less frequent */ @@ -157,30 +147,32 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_LESS: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0; i<n; i++,zptr++,m++) { - if (*m) { - if (z[i] < *zptr) { + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] < zbuffer[i]) { /* pass */ - *zptr = z[i]; + zbuffer[i] = z[i]; passed++; } else { /* fail */ - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0; i<n; i++,zptr++,m++) { - if (*m) { - if (z[i] < *zptr) { + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] < zbuffer[i]) { /* pass */ passed++; } else { - *m = 0; + mask[i] = 0; } } } @@ -189,28 +181,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_LEQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] <= *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] <= zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] <= *zptr) { + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] <= zbuffer[i]) { /* pass */ passed++; } else { - *m = 0; + mask[i] = 0; } } } @@ -219,28 +213,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_GEQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] >= *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] >= zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] >= *zptr) { + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] >= zbuffer[i]) { /* pass */ passed++; } else { - *m = 0; + mask[i] = 0; } } } @@ -249,28 +245,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_GREATER: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] > *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] > zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] > *zptr) { + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] > zbuffer[i]) { /* pass */ passed++; } else { - *m = 0; + mask[i] = 0; } } } @@ -279,28 +277,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_NOTEQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] != *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] != zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] != *zptr) { + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] != zbuffer[i]) { /* pass */ passed++; } else { - *m = 0; + mask[i] = 0; } } } @@ -309,28 +309,30 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_EQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] == *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] == zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m =0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] == *zptr) { + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + if (z[i] == zbuffer[i]) { /* pass */ passed++; } else { - *m =0; + mask[i] = 0; } } } @@ -339,9 +341,10 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, case GL_ALWAYS: if (ctx->Depth.Mask) { /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - *zptr = z[i]; + GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + zbuffer[i] = z[i]; passed++; } } @@ -352,13 +355,11 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, } break; case GL_NEVER: - for (i=0;i<n;i++) { - mask[i] = 0; - } + MEMSET(mask, 0, n * sizeof(GLubyte)); break; default: - gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic"); - } /*switch*/ + gl_problem(ctx, "Bad depth func in depth_test_span"); + } return passed; } @@ -366,93 +367,57 @@ GLuint gl_depth_test_span_generic( GLcontext* ctx, /* - * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE). + * Apply depth test to span of fragments. Hardware or software z buffer. */ -GLuint gl_depth_test_span_less( GLcontext* ctx, - GLuint n, GLint x, GLint y, const GLdepth z[], - GLubyte mask[] ) +GLuint +gl_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], GLubyte mask[] ) { - GLdepth *zptr = Z_ADDRESS( ctx, x, y ); - GLuint i; - GLuint passed = 0; + GLdepth zbuffer[MAX_WIDTH]; + GLdepth *zptr; + GLuint passed; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] < zptr[i]) { - /* pass */ - zptr[i] = z[i]; - passed++; - } - else { - /* fail */ - mask[i] = 0; - } - } + if (ctx->Driver.ReadDepthSpan) { + /* read depth values out of hardware Z buffer */ + (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer); + zptr = zbuffer; + } + else { + /* test against software depth buffer values */ + zptr = Z_ADDRESS( ctx, x, y ); } - return passed; -} - -/* - * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE). - */ -GLuint gl_depth_test_span_greater( GLcontext* ctx, - GLuint n, GLint x, GLint y, - const GLdepth z[], - GLubyte mask[] ) -{ - GLdepth *zptr = Z_ADDRESS( ctx, x, y ); - GLuint i; - GLuint passed = 0; + passed = depth_test_span( ctx, n, x, y, zptr, z, mask ); - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] > zptr[i]) { - /* pass */ - zptr[i] = z[i]; - passed++; - } - else { - /* fail */ - mask[i] = 0; - } - } + if (ctx->Driver.WriteDepthSpan) { + /* write updated depth values into hardware Z buffer */ + assert(zptr == zbuffer); + (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask); } + return passed; } -/* - * Depth test an array of randomly positioned fragments. - */ - - -#define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \ - GLint width = ctx->Buffer->Width; - -#define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) ) - - /* - * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). + * Do depth testing for an array of fragments using software Z buffer. */ -void gl_depth_test_pixels_generic( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) +static void +software_depth_test_pixels( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ) { - register GLdepth *zptr; - register GLuint i; - /* switch cases ordered from most frequent to less frequent */ switch (ctx->Depth.Func) { case GL_LESS: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] < *zptr) { /* pass */ *zptr = z[i]; @@ -466,9 +431,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, } else { /* Don't update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] < *zptr) { /* pass */ } @@ -483,9 +449,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, case GL_LEQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] <= *zptr) { /* pass */ *zptr = z[i]; @@ -499,9 +466,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, } else { /* Don't update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] <= *zptr) { /* pass */ } @@ -516,9 +484,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, case GL_GEQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] >= *zptr) { /* pass */ *zptr = z[i]; @@ -532,9 +501,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, } else { /* Don't update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] >= *zptr) { /* pass */ } @@ -549,9 +519,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, case GL_GREATER: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] > *zptr) { /* pass */ *zptr = z[i]; @@ -565,9 +536,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, } else { /* Don't update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] > *zptr) { /* pass */ } @@ -582,9 +554,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, case GL_NOTEQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] != *zptr) { /* pass */ *zptr = z[i]; @@ -598,9 +571,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, } else { /* Don't update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] != *zptr) { /* pass */ } @@ -615,9 +589,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, case GL_EQUAL: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] == *zptr) { /* pass */ *zptr = z[i]; @@ -631,9 +606,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, } else { /* Don't update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); if (z[i] == *zptr) { /* pass */ } @@ -648,9 +624,10 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, case GL_ALWAYS: if (ctx->Depth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); + GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]); *zptr = z[i]; } } @@ -661,71 +638,274 @@ void gl_depth_test_pixels_generic( GLcontext* ctx, break; case GL_NEVER: /* depth test never passes */ - for (i=0;i<n;i++) { - mask[i] = 0; - } + MEMSET(mask, 0, n * sizeof(GLubyte)); break; default: - gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic"); - } /*switch*/ + gl_problem(ctx, "Bad depth func in software_depth_test_pixels"); + } } /* - * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ). + * Do depth testing for an array of pixels using hardware Z buffer. + * Input/output: zbuffer - array of depth values from Z buffer + * Input: z - array of fragment z values. */ -void gl_depth_test_pixels_less( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) +static void +hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[], + const GLdepth z[], GLubyte mask[] ) { - GLdepth *zptr; - GLuint i; - - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); - if (z[i] < *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } + /* switch cases ordered from most frequent to less frequent */ + switch (ctx->Depth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] < zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] < zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_LEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] <= zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] <= zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] >= zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] >= zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] > zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] > zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] != zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] != zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_EQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] == zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + if (z[i] == zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_ALWAYS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i<n; i++) { + if (mask[i]) { + zbuffer[i] = z[i]; + } + } + } + else { + /* Don't update Z buffer or mask */ + } + break; + case GL_NEVER: + /* depth test never passes */ + MEMSET(mask, 0, n * sizeof(GLubyte)); + break; + default: + gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels"); } } -/* - * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ). - */ -void gl_depth_test_pixels_greater( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) + +void gl_depth_test_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ) { - GLdepth *zptr; - GLuint i; - - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(ctx,x[i],y[i]); - if (z[i] > *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } + if (ctx->Driver.ReadDepthPixels) { + /* read depth values from hardware Z buffer */ + GLdepth zbuffer[PB_SIZE]; + (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer); + + hardware_depth_test_pixels( ctx, n, zbuffer, z, mask ); + + /* update hardware Z buffer with new values */ + assert(ctx->Driver.WriteDepthPixels); + (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, z, mask ); + } + else { + /* software depth testing */ + software_depth_test_pixels(ctx, n, x, y, z, mask); } } + /**********************************************************************/ /***** Read Depth Buffer *****/ /**********************************************************************/ @@ -733,7 +913,7 @@ void gl_depth_test_pixels_greater( GLcontext* ctx, /* * Return a span of depth values from the depth buffer as floats in [0,1]. - * This function is only called through Driver.read_depth_span_float() + * This is used for both hardware and software depth buffers. * Input: n - how many pixels * x,y - location of first pixel * Output: depth - the array of depth values @@ -741,46 +921,29 @@ void gl_depth_test_pixels_greater( GLcontext* ctx, void gl_read_depth_span_float( GLcontext* ctx, GLuint n, GLint x, GLint y, GLfloat depth[] ) { - GLdepth *zptr; - GLfloat scale; - GLuint i; - - scale = 1.0F / DEPTH_SCALE; + const GLfloat scale = 1.0F / DEPTH_SCALE; if (ctx->DrawBuffer->Depth) { - zptr = Z_ADDRESS( ctx, x, y ); - for (i=0;i<n;i++) { + /* read from software depth buffer */ + const GLdepth *zptr = Z_ADDRESS( ctx, x, y ); + GLuint i; + for (i = 0; i < n; i++) { depth[i] = (GLfloat) zptr[i] * scale; } } - else { - for (i=0;i<n;i++) { - depth[i] = 0.0F; + else if (ctx->Driver.ReadDepthSpan) { + /* read from hardware depth buffer */ + GLdepth d[MAX_WIDTH]; + GLuint i; + assert(n <= MAX_WIDTH); + (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d ); + for (i = 0; i < n; i++) { + depth[i] = d[i] * scale; } } -} - - -/* - * Return a span of depth values from the depth buffer as integers in - * [0,MAX_DEPTH]. - * This function is only called through Driver.read_depth_span_int() - * Input: n - how many pixels - * x,y - location of first pixel - * Output: depth - the array of depth values - */ -void gl_read_depth_span_int( GLcontext* ctx, - GLuint n, GLint x, GLint y, GLdepth depth[] ) -{ - if (ctx->DrawBuffer->Depth) { - GLdepth *zptr = Z_ADDRESS( ctx, x, y ); - MEMCPY( depth, zptr, n * sizeof(GLdepth) ); - } else { - GLuint i; - for (i=0;i<n;i++) { - depth[i] = 0; - } + /* no depth buffer */ + MEMSET(depth, 0, n * sizeof(GLfloat)); } } @@ -800,20 +963,22 @@ void gl_read_depth_span_int( GLcontext* ctx, void gl_alloc_depth_buffer( GLcontext* ctx ) { /* deallocate current depth buffer if present */ - if (ctx->DrawBuffer->Depth) { - FREE(ctx->DrawBuffer->Depth); - ctx->DrawBuffer->Depth = NULL; - } + if (ctx->DrawBuffer->UseSoftwareDepthBuffer) { + if (ctx->DrawBuffer->Depth) { + FREE(ctx->DrawBuffer->Depth); + ctx->DrawBuffer->Depth = NULL; + } - /* allocate new depth buffer, but don't initialize it */ - ctx->DrawBuffer->Depth = (GLdepth *) MALLOC( ctx->DrawBuffer->Width - * ctx->DrawBuffer->Height - * sizeof(GLdepth) ); - if (!ctx->DrawBuffer->Depth) { - /* out of memory */ - ctx->Depth.Test = GL_FALSE; - ctx->NewState |= NEW_RASTER_OPS; - gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" ); + /* allocate new depth buffer, but don't initialize it */ + ctx->DrawBuffer->Depth = (GLdepth *) MALLOC( ctx->DrawBuffer->Width + * ctx->DrawBuffer->Height + * sizeof(GLdepth) ); + if (!ctx->DrawBuffer->Depth) { + /* out of memory */ + ctx->Depth.Test = GL_FALSE; + ctx->NewState |= NEW_RASTER_OPS; + gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" ); + } } } @@ -854,8 +1019,8 @@ void gl_clear_depth_buffer( GLcontext* ctx ) /* clear whole buffer */ if (sizeof(GLdepth)==2 && (clear_value&0xff)==(clear_value>>8)) { /* lower and upper bytes of clear_value are same, use MEMSET */ - MEMSET( ctx->DrawBuffer->Depth, clear_value&0xff, - 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height); + MEMSET( ctx->DrawBuffer->Depth, clear_value & 0xff, + 2*ctx->DrawBuffer->Width * ctx->DrawBuffer->Height); } else { GLdepth *d = ctx->DrawBuffer->Depth; @@ -879,6 +1044,3 @@ void gl_clear_depth_buffer( GLcontext* ctx ) } } } - - - diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h index c579e3d9fb9..f31909ad7be 100644 --- a/src/mesa/main/depth.h +++ b/src/mesa/main/depth.h @@ -1,4 +1,4 @@ -/* $Id: depth.h,v 1.4 1999/11/24 18:48:31 brianp Exp $ */ +/* $Id: depth.h,v 1.5 1999/12/10 19:09:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -33,69 +33,54 @@ /* - * Return the address of the Z-buffer value for window coordinate (x,y): + * Immediate-mode API entrpoints */ -#define Z_ADDRESS( CTX, X, Y ) \ - ((CTX)->DrawBuffer->Depth + (CTX)->DrawBuffer->Width * (Y) + (X)) - - - - -extern GLuint -gl_depth_test_span_generic( GLcontext* ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], GLubyte mask[] ); - -extern GLuint -gl_depth_test_span_less( GLcontext* ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], GLubyte mask[] ); - -extern GLuint -gl_depth_test_span_greater( GLcontext* ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], GLubyte mask[] ); +extern void +_mesa_ClearDepth( GLclampd depth ); extern void -gl_depth_test_pixels_generic( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); +_mesa_DepthFunc( GLenum func ); -extern void -gl_depth_test_pixels_less( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); extern void -gl_depth_test_pixels_greater( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); +_mesa_DepthMask( GLboolean flag ); -extern void gl_read_depth_span_float( GLcontext* ctx, - GLuint n, GLint x, GLint y, - GLfloat depth[] ); -extern void gl_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y, - GLdepth depth[] ); +/* + * Return the address of the Z-buffer value for window coordinate (x,y): + */ +#define Z_ADDRESS( CTX, X, Y ) \ + ((CTX)->DrawBuffer->Depth + (CTX)->DrawBuffer->Width * (Y) + (X)) -extern void gl_alloc_depth_buffer( GLcontext* ctx ); -extern void gl_clear_depth_buffer( GLcontext* ctx ); +extern GLuint +gl_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], GLubyte mask[] ); +extern void +gl_depth_test_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ); extern void -_mesa_ClearDepth( GLclampd depth ); +gl_read_depth_span_float( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLfloat depth[] ); + extern void -_mesa_DepthFunc( GLenum func ); +gl_alloc_depth_buffer( GLcontext* ctx ); extern void -_mesa_DepthMask( GLboolean flag ); +gl_clear_depth_buffer( GLcontext* ctx ); + #endif diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index c4eb1ea442d..2f9ec8aa010 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -1,4 +1,4 @@ -/* $Id: stencil.c,v 1.12 1999/12/10 16:15:04 brianp Exp $ */ +/* $Id: stencil.c,v 1.13 1999/12/10 19:09:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -30,6 +30,7 @@ #else #include "glheader.h" #include "context.h" +#include "depth.h" #include "mem.h" #include "pb.h" #include "stencil.h" @@ -579,8 +580,7 @@ stencil_and_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, MEMCPY(oldmask, mask, n * sizeof(GLubyte)); /* apply the depth test */ - if (ctx->Driver.DepthTestSpan) - (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask ); + gl_depth_test_span(ctx, n, x, y, z, mask); /* Set the stencil pass/fail flags according to result of depth testing. * if oldmask[i] == 0 then @@ -1059,8 +1059,7 @@ gl_stencil_and_depth_test_pixels( GLcontext *ctx, MEMCPY(oldmask, mask, n * sizeof(GLubyte)); - if (ctx->Driver.DepthTestPixels) - (*ctx->Driver.DepthTestPixels)( ctx, n, x, y, z, mask ); + gl_depth_test_pixels(ctx, n, x, y, z, mask); for (i=0;i<n;i++) { ASSERT(mask[i] == 0 || mask[i] == 1); @@ -1100,8 +1099,7 @@ gl_stencil_and_depth_test_pixels( GLcontext *ctx, MEMCPY(oldmask, mask, n * sizeof(GLubyte)); - if (ctx->Driver.DepthTestPixels) - (*ctx->Driver.DepthTestPixels)( ctx, n, x, y, z, mask ); + gl_depth_test_pixels(ctx, n, x, y, z, mask); for (i=0;i<n;i++) { ASSERT(mask[i] == 0 || mask[i] == 1); |