From 5c3bee503999fbc0d7c65462ff62f9e38fe40e33 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Dec 1999 19:09:21 +0000 Subject: changes in hardware depth buffer support --- src/mesa/main/depth.c | 672 +++++++++++++++++++++++++++++++------------------- 1 file changed, 417 insertions(+), 255 deletions(-) (limited to 'src/mesa/main/depth.c') diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index 746b818..b2fa947 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; iDepth.Mask) { /* Update Z buffer */ - for (i=0;iDepth.Mask) { /* Update Z buffer */ - for (i=0;i= *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i= zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i= *zptr) { + GLuint i; + for (i=0;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 *zptr) { - *zptr = z[i]; + GLuint i; + for (i=0;i zbuffer[i]) { + zbuffer[i] = z[i]; passed++; } else { - *m = 0; + mask[i] = 0; } } } } else { /* Don't update Z buffer */ - for (i=0;i *zptr) { + GLuint i; + for (i=0;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;iDepth.Mask) { /* Update Z buffer */ - for (i=0;iDepth.Mask) { /* Update Z buffer */ - for (i=0;iDriver.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 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; iDepth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; iDepth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; 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= *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 *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 *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; iDepth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; iDepth.Mask) { /* Update Z buffer */ + GLuint i; for (i=0; iDepth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; 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= 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 zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; 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; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; 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;iDriver.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;iDrawBuffer->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 ) } } } - - - -- cgit v1.1