1 /* $Id: depth.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * Depth buffer functions
45 #include "GL/xf86glx.h"
51 /**********************************************************************/
52 /***** API Functions *****/
53 /**********************************************************************/
57 void gl_ClearDepth( GLcontext
* ctx
, GLclampd depth
)
59 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glClearDepth");
60 ctx
->Depth
.Clear
= (GLfloat
) CLAMP( depth
, 0.0, 1.0 );
61 if (ctx
->Driver
.ClearDepth
)
62 (*ctx
->Driver
.ClearDepth
)( ctx
, ctx
->Depth
.Clear
);
67 void gl_DepthFunc( GLcontext
* ctx
, GLenum func
)
69 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthFunc");
71 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
72 fprintf(stderr
, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func
));
77 case GL_LESS
: /* (default) pass if incoming z < stored z */
84 if (ctx
->Depth
.Func
!= func
) {
85 ctx
->Depth
.Func
= func
;
86 ctx
->NewState
|= NEW_RASTER_OPS
;
87 if (ctx
->Driver
.DepthFunc
) {
88 (*ctx
->Driver
.DepthFunc
)( ctx
, func
);
93 gl_error( ctx
, GL_INVALID_ENUM
, "glDepth.Func" );
99 void gl_DepthMask( GLcontext
* ctx
, GLboolean flag
)
101 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthMask");
103 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
104 fprintf(stderr
, "glDepthMask %d\n", flag
);
107 * GL_TRUE indicates depth buffer writing is enabled (default)
108 * GL_FALSE indicates depth buffer writing is disabled
110 if (ctx
->Depth
.Mask
!= flag
) {
111 ctx
->Depth
.Mask
= flag
;
112 ctx
->NewState
|= NEW_RASTER_OPS
;
113 if (ctx
->Driver
.DepthMask
) {
114 (*ctx
->Driver
.DepthMask
)( ctx
, flag
);
121 /**********************************************************************/
122 /***** Depth Testing Functions *****/
123 /**********************************************************************/
127 * Depth test horizontal spans of fragments. These functions are called
128 * via ctx->Driver.depth_test_span only.
130 * Input: n - number of pixels in the span
131 * x, y - location of leftmost pixel in span in window coords
132 * z - array [n] of integer depth values
133 * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
134 * Return: number of pixels which passed depth test
139 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
141 GLuint
gl_depth_test_span_generic( GLcontext
* ctx
,
142 GLuint n
, GLint x
, GLint y
,
146 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
151 /* switch cases ordered from most frequent to less frequent */
152 switch (ctx
->Depth
.Func
) {
154 if (ctx
->Depth
.Mask
) {
155 /* Update Z buffer */
156 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
171 /* Don't update Z buffer */
172 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
186 if (ctx
->Depth
.Mask
) {
187 /* Update Z buffer */
188 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
201 /* Don't update Z buffer */
202 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
216 if (ctx
->Depth
.Mask
) {
217 /* Update Z buffer */
218 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
231 /* Don't update Z buffer */
232 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
246 if (ctx
->Depth
.Mask
) {
247 /* Update Z buffer */
248 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
261 /* Don't update Z buffer */
262 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
276 if (ctx
->Depth
.Mask
) {
277 /* Update Z buffer */
278 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
291 /* Don't update Z buffer */
292 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
306 if (ctx
->Depth
.Mask
) {
307 /* Update Z buffer */
308 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
321 /* Don't update Z buffer */
322 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
336 if (ctx
->Depth
.Mask
) {
337 /* Update Z buffer */
338 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
346 /* Don't update Z buffer or mask */
356 gl_problem(ctx
, "Bad depth func in gl_depth_test_span_generic");
365 * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
367 GLuint
gl_depth_test_span_less( GLcontext
* ctx
,
368 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
371 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
375 for (i
=0; i
<n
; i
++) {
377 if (z
[i
] < zptr
[i
]) {
393 * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
395 GLuint
gl_depth_test_span_greater( GLcontext
* ctx
,
396 GLuint n
, GLint x
, GLint y
,
400 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
404 for (i
=0; i
<n
; i
++) {
406 if (z
[i
] > zptr
[i
]) {
423 * Depth test an array of randomly positioned fragments.
427 #define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \
428 GLint width = ctx->Buffer->Width;
430 #define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) )
435 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
437 void gl_depth_test_pixels_generic( GLcontext
* ctx
,
438 GLuint n
, const GLint x
[], const GLint y
[],
439 const GLdepth z
[], GLubyte mask
[] )
441 register GLdepth
*zptr
;
444 /* switch cases ordered from most frequent to less frequent */
445 switch (ctx
->Depth
.Func
) {
447 if (ctx
->Depth
.Mask
) {
448 /* Update Z buffer */
449 for (i
=0; i
<n
; i
++) {
451 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
464 /* Don't update Z buffer */
465 for (i
=0; i
<n
; i
++) {
467 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
480 if (ctx
->Depth
.Mask
) {
481 /* Update Z buffer */
482 for (i
=0; i
<n
; i
++) {
484 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
497 /* Don't update Z buffer */
498 for (i
=0; i
<n
; i
++) {
500 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
513 if (ctx
->Depth
.Mask
) {
514 /* Update Z buffer */
515 for (i
=0; i
<n
; i
++) {
517 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
530 /* Don't update Z buffer */
531 for (i
=0; i
<n
; i
++) {
533 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
546 if (ctx
->Depth
.Mask
) {
547 /* Update Z buffer */
548 for (i
=0; i
<n
; i
++) {
550 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
563 /* Don't update Z buffer */
564 for (i
=0; i
<n
; i
++) {
566 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
579 if (ctx
->Depth
.Mask
) {
580 /* Update Z buffer */
581 for (i
=0; i
<n
; i
++) {
583 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
596 /* Don't update Z buffer */
597 for (i
=0; i
<n
; i
++) {
599 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
612 if (ctx
->Depth
.Mask
) {
613 /* Update Z buffer */
614 for (i
=0; i
<n
; i
++) {
616 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
629 /* Don't update Z buffer */
630 for (i
=0; i
<n
; i
++) {
632 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
645 if (ctx
->Depth
.Mask
) {
646 /* Update Z buffer */
647 for (i
=0; i
<n
; i
++) {
649 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
655 /* Don't update Z buffer or mask */
659 /* depth test never passes */
665 gl_problem(ctx
, "Bad depth func in gl_depth_test_pixels_generic");
672 * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
674 void gl_depth_test_pixels_less( GLcontext
* ctx
,
675 GLuint n
, const GLint x
[], const GLint y
[],
676 const GLdepth z
[], GLubyte mask
[] )
681 for (i
=0; i
<n
; i
++) {
683 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
698 * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
700 void gl_depth_test_pixels_greater( GLcontext
* ctx
,
701 GLuint n
, const GLint x
[], const GLint y
[],
702 const GLdepth z
[], GLubyte mask
[] )
707 for (i
=0; i
<n
; i
++) {
709 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
725 /**********************************************************************/
726 /***** Read Depth Buffer *****/
727 /**********************************************************************/
731 * Return a span of depth values from the depth buffer as floats in [0,1].
732 * This function is only called through Driver.read_depth_span_float()
733 * Input: n - how many pixels
734 * x,y - location of first pixel
735 * Output: depth - the array of depth values
737 void gl_read_depth_span_float( GLcontext
* ctx
,
738 GLuint n
, GLint x
, GLint y
, GLfloat depth
[] )
744 scale
= 1.0F
/ DEPTH_SCALE
;
746 if (ctx
->Buffer
->Depth
) {
747 zptr
= Z_ADDRESS( ctx
, x
, y
);
749 depth
[i
] = (GLfloat
) zptr
[i
] * scale
;
761 * Return a span of depth values from the depth buffer as integers in
763 * This function is only called through Driver.read_depth_span_int()
764 * Input: n - how many pixels
765 * x,y - location of first pixel
766 * Output: depth - the array of depth values
768 void gl_read_depth_span_int( GLcontext
* ctx
,
769 GLuint n
, GLint x
, GLint y
, GLdepth depth
[] )
771 if (ctx
->Buffer
->Depth
) {
772 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
773 MEMCPY( depth
, zptr
, n
* sizeof(GLdepth
) );
785 /**********************************************************************/
786 /***** Allocate and Clear Depth Buffer *****/
787 /**********************************************************************/
792 * Allocate a new depth buffer. If there's already a depth buffer allocated
793 * it will be free()'d. The new depth buffer will be uniniitalized.
794 * This function is only called through Driver.alloc_depth_buffer.
796 void gl_alloc_depth_buffer( GLcontext
* ctx
)
798 /* deallocate current depth buffer if present */
799 if (ctx
->Buffer
->Depth
) {
800 free(ctx
->Buffer
->Depth
);
801 ctx
->Buffer
->Depth
= NULL
;
804 /* allocate new depth buffer, but don't initialize it */
805 ctx
->Buffer
->Depth
= (GLdepth
*) malloc( ctx
->Buffer
->Width
806 * ctx
->Buffer
->Height
808 if (!ctx
->Buffer
->Depth
) {
810 ctx
->Depth
.Test
= GL_FALSE
;
811 gl_error( ctx
, GL_OUT_OF_MEMORY
, "Couldn't allocate depth buffer" );
819 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
821 * This function is only called through Driver.clear_depth_buffer.
823 void gl_clear_depth_buffer( GLcontext
* ctx
)
825 GLdepth clear_value
= (GLdepth
) (ctx
->Depth
.Clear
* DEPTH_SCALE
);
827 if (ctx
->Visual
->DepthBits
==0 || !ctx
->Buffer
->Depth
|| !ctx
->Depth
.Mask
) {
828 /* no depth buffer, or writing to it is disabled */
832 /* The loops in this function have been written so the IRIX 5.3
833 * C compiler can unroll them. Hopefully other compilers can too!
836 if (ctx
->Scissor
.Enabled
) {
837 /* only clear scissor region */
839 for (y
=ctx
->Buffer
->Ymin
; y
<=ctx
->Buffer
->Ymax
; y
++) {
840 GLdepth
*d
= Z_ADDRESS( ctx
, ctx
->Buffer
->Xmin
, y
);
841 GLint n
= ctx
->Buffer
->Xmax
- ctx
->Buffer
->Xmin
+ 1;
849 /* clear whole buffer */
850 if (sizeof(GLdepth
)==2 && (clear_value
&0xff)==(clear_value
>>8)) {
851 /* lower and upper bytes of clear_value are same, use MEMSET */
852 MEMSET( ctx
->Buffer
->Depth
, clear_value
&0xff,
853 2*ctx
->Buffer
->Width
*ctx
->Buffer
->Height
);
856 GLdepth
*d
= ctx
->Buffer
->Depth
;
857 GLint n
= ctx
->Buffer
->Width
* ctx
->Buffer
->Height
;
859 d
[0] = clear_value
; d
[1] = clear_value
;
860 d
[2] = clear_value
; d
[3] = clear_value
;
861 d
[4] = clear_value
; d
[5] = clear_value
;
862 d
[6] = clear_value
; d
[7] = clear_value
;
863 d
[8] = clear_value
; d
[9] = clear_value
;
864 d
[10] = clear_value
; d
[11] = clear_value
;
865 d
[12] = clear_value
; d
[13] = clear_value
;
866 d
[14] = clear_value
; d
[15] = clear_value
;