X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fdepth.c;h=eb8c8b821b256f4f26aa696cc81090237087b33f;hb=ae0eaf93e092ac8e8b1c98f3e986de96940663fa;hp=dcd84f5848045bb23ce8d87147e18326e797472f;hpb=fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5;p=mesa.git diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index dcd84f58480..eb8c8b821b2 100644 --- a/src/mesa/main/depth.c +++ b/src/mesa/main/depth.c @@ -1,21 +1,19 @@ -/* $Id: depth.c,v 1.9 1999/11/11 01:22:26 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.3 - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * + * Version: 5.1 + * + * 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -24,17 +22,15 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef PC_HEADER -#include "all.h" -#else + #include "glheader.h" +#include "imports.h" #include "context.h" -#include "enums.h" #include "depth.h" -#include "mem.h" -#include "types.h" -#endif - +#include "enums.h" +#include "hash.h" +#include "macros.h" +#include "mtypes.h" /**********************************************************************/ @@ -43,842 +39,148 @@ -void +void GLAPIENTRY _mesa_ClearDepth( GLclampd depth ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearDepth"); - ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 ); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + depth = CLAMP( depth, 0.0, 1.0 ); + + if (ctx->Depth.Clear == depth) + return; + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Clear = depth; if (ctx->Driver.ClearDepth) (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear ); } -void +void GLAPIENTRY _mesa_DepthFunc( GLenum func ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthFunc"); + ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - fprintf(stderr, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func)); + _mesa_debug(ctx, "glDepthFunc %s\n", _mesa_lookup_enum_by_nr(func)); switch (func) { - case GL_LESS: /* (default) pass if incoming z < stored z */ - case GL_GEQUAL: - case GL_LEQUAL: - case GL_GREATER: - case GL_NOTEQUAL: - case GL_EQUAL: - case GL_ALWAYS: - if (ctx->Depth.Func != func) { - ctx->Depth.Func = func; - ctx->NewState |= NEW_RASTER_OPS; - ctx->TriangleCaps &= ~DD_Z_NEVER; - if (ctx->Driver.DepthFunc) { - (*ctx->Driver.DepthFunc)( ctx, func ); - } - } - break; - case GL_NEVER: - if (ctx->Depth.Func != func) { - ctx->Depth.Func = func; - ctx->NewState |= NEW_RASTER_OPS; - ctx->TriangleCaps |= DD_Z_NEVER; - if (ctx->Driver.DepthFunc) { - (*ctx->Driver.DepthFunc)( ctx, func ); - } - } - break; - default: - gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" ); + case GL_LESS: /* (default) pass if incoming z < stored z */ + case GL_GEQUAL: + case GL_LEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + case GL_EQUAL: + case GL_ALWAYS: + case GL_NEVER: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDepth.Func" ); + return; } + + if (ctx->Depth.Func == func) + return; + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Func = func; + + if (ctx->Driver.DepthFunc) + ctx->Driver.DepthFunc( ctx, func ); } -void +void GLAPIENTRY _mesa_DepthMask( GLboolean flag ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthMask"); + ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - fprintf(stderr, "glDepthMask %d\n", flag); + _mesa_debug(ctx, "glDepthMask %d\n", flag); /* * GL_TRUE indicates depth buffer writing is enabled (default) * GL_FALSE indicates depth buffer writing is disabled */ - if (ctx->Depth.Mask != flag) { - ctx->Depth.Mask = flag; - ctx->NewState |= NEW_RASTER_OPS; - if (ctx->Driver.DepthMask) { - (*ctx->Driver.DepthMask)( ctx, flag ); - } - } -} - - - -/**********************************************************************/ -/***** Depth Testing Functions *****/ -/**********************************************************************/ - - -/* - * 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 - */ + if (ctx->Depth.Mask == flag) + return; + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Mask = flag; -/* - * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). - */ -GLuint gl_depth_test_span_generic( GLcontext* ctx, - GLuint n, GLint x, GLint y, - 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 */ - switch (ctx->Depth.Func) { - 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]; - passed++; - } - else { - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i= *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - case GL_GREATER: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i *zptr) { - *zptr = z[i]; - passed++; - } - else { - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - 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.DepthMask) + ctx->Driver.DepthMask( ctx, flag ); } -/* - * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE). - */ -GLuint gl_depth_test_span_less( GLcontext* ctx, - GLuint n, GLint x, GLint y, const GLdepth z[], - GLubyte mask[] ) +/* GL_EXT_depth_bounds_test */ +void GLAPIENTRY +_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ) { - GLdepth *zptr = Z_ADDRESS( ctx, x, y ); - GLuint i; - GLuint passed = 0; - - for (i=0; i zptr[i]) { - /* pass */ - zptr[i] = z[i]; - passed++; - } - else { - /* fail */ - mask[i] = 0; - } - } + if (zmin > zmax) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDepthBoundsEXT(zmin > zmax)"); + return; } - 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 ). - */ -void gl_depth_test_pixels_generic( 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 */ - for (i=0; iDepth.Mask) { - /* Update Z buffer */ - for (i=0; iDepth.Mask) { - /* Update Z buffer */ - for (i=0; i= *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i= *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_GREATER: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - 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; iDepth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax) + return; -/* - * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ). - */ -void gl_depth_test_pixels_less( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) -{ - GLdepth *zptr; - GLuint i; - - for (i=0; i *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.BoundsMin = (GLfloat) zmin; + ctx->Depth.BoundsMax = (GLfloat) zmax; } - - /**********************************************************************/ -/***** Read Depth Buffer *****/ +/***** Initialization *****/ /**********************************************************************/ - -/* - * 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() - * Input: n - how many pixels - * x,y - location of first pixel - * Output: depth - the array of depth values - */ -void gl_read_depth_span_float( GLcontext* ctx, - GLuint n, GLint x, GLint y, GLfloat depth[] ) +void _mesa_init_depth( GLcontext * ctx ) { - GLdepth *zptr; - GLfloat scale; - GLuint i; - - scale = 1.0F / DEPTH_SCALE; - - if (ctx->Buffer->Depth) { - zptr = Z_ADDRESS( ctx, x, y ); - for (i=0;iDepth.Test = GL_FALSE; + ctx->Depth.Clear = 1.0; + ctx->Depth.Func = GL_LESS; + ctx->Depth.Mask = GL_TRUE; + ctx->Depth.OcclusionTest = GL_FALSE; + + /* Z buffer stuff */ + if (ctx->Visual.depthBits == 0) { + /* Special case. Even if we don't have a depth buffer we need + * good values for DepthMax for Z vertex transformation purposes + * and for per-fragment fog computation. + */ + ctx->DepthMax = 1 << 16; + ctx->DepthMaxF = (GLfloat) ctx->DepthMax; } - else { - for (i=0;iBuffer->Depth) { - GLdepth *zptr = Z_ADDRESS( ctx, x, y ); - MEMCPY( depth, zptr, n * sizeof(GLdepth) ); + else if (ctx->Visual.depthBits < 32) { + ctx->DepthMax = (1 << ctx->Visual.depthBits) - 1; + ctx->DepthMaxF = (GLfloat) ctx->DepthMax; } else { - GLuint i; - for (i=0;iDepthMax = 0xffffffff; + ctx->DepthMaxF = (GLfloat) ctx->DepthMax; } -} + ctx->MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */ - - -/**********************************************************************/ -/***** Allocate and Clear Depth Buffer *****/ -/**********************************************************************/ - - - -/* - * Allocate a new depth buffer. If there's already a depth buffer allocated - * it will be free()'d. The new depth buffer will be uniniitalized. - * This function is only called through Driver.alloc_depth_buffer. - */ -void gl_alloc_depth_buffer( GLcontext* ctx ) -{ - /* deallocate current depth buffer if present */ - if (ctx->Buffer->Depth) { - FREE(ctx->Buffer->Depth); - ctx->Buffer->Depth = NULL; - } - - /* allocate new depth buffer, but don't initialize it */ - ctx->Buffer->Depth = (GLdepth *) MALLOC( ctx->Buffer->Width - * ctx->Buffer->Height - * sizeof(GLdepth) ); - if (!ctx->Buffer->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" ); - } -} - - - - -/* - * Clear the depth buffer. If the depth buffer doesn't exist yet we'll - * allocate it now. - * This function is only called through Driver.clear_depth_buffer. - */ -void gl_clear_depth_buffer( GLcontext* ctx ) -{ - GLdepth clear_value = (GLdepth) (ctx->Depth.Clear * DEPTH_SCALE); - - if (ctx->Visual->DepthBits==0 || !ctx->Buffer->Depth || !ctx->Depth.Mask) { - /* no depth buffer, or writing to it is disabled */ - return; - } - - /* The loops in this function have been written so the IRIX 5.3 - * C compiler can unroll them. Hopefully other compilers can too! - */ - - if (ctx->Scissor.Enabled) { - /* only clear scissor region */ - GLint y; - for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) { - GLdepth *d = Z_ADDRESS( ctx, ctx->Buffer->Xmin, y ); - GLint n = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1; - do { - *d++ = clear_value; - n--; - } while (n); - } - } - else { - /* 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->Buffer->Depth, clear_value&0xff, - 2*ctx->Buffer->Width*ctx->Buffer->Height); - } - else { - GLdepth *d = ctx->Buffer->Depth; - GLint n = ctx->Buffer->Width * ctx->Buffer->Height; - while (n>=16) { - d[0] = clear_value; d[1] = clear_value; - d[2] = clear_value; d[3] = clear_value; - d[4] = clear_value; d[5] = clear_value; - d[6] = clear_value; d[7] = clear_value; - d[8] = clear_value; d[9] = clear_value; - d[10] = clear_value; d[11] = clear_value; - d[12] = clear_value; d[13] = clear_value; - d[14] = clear_value; d[15] = clear_value; - d += 16; - n -= 16; - } - while (n>0) { - *d++ = clear_value; - n--; - } - } - } +#if FEATURE_ARB_occlusion_query + ctx->Occlusion.QueryObjects = _mesa_NewHashTable(); +#endif + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; } - - -