1 /* $Id: depth.c,v 1.8 1999/11/08 07:36:43 brianp 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.
28 /* $XFree86: xc/lib/GL/mesa/src/depth.c,v 1.3 1999/04/04 00:20:22 dawes Exp $ */
31 * Depth buffer functions
43 #include "GL/xf86glx.h"
54 /**********************************************************************/
55 /***** API Functions *****/
56 /**********************************************************************/
60 void gl_ClearDepth( GLcontext
* ctx
, GLclampd depth
)
62 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glClearDepth");
63 ctx
->Depth
.Clear
= (GLfloat
) CLAMP( depth
, 0.0, 1.0 );
64 if (ctx
->Driver
.ClearDepth
)
65 (*ctx
->Driver
.ClearDepth
)( ctx
, ctx
->Depth
.Clear
);
70 void gl_DepthFunc( GLcontext
* ctx
, GLenum func
)
72 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthFunc");
74 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
75 fprintf(stderr
, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func
));
78 case GL_LESS
: /* (default) pass if incoming z < stored z */
85 if (ctx
->Depth
.Func
!= func
) {
86 ctx
->Depth
.Func
= func
;
87 ctx
->NewState
|= NEW_RASTER_OPS
;
88 ctx
->TriangleCaps
&= ~DD_Z_NEVER
;
89 if (ctx
->Driver
.DepthFunc
) {
90 (*ctx
->Driver
.DepthFunc
)( ctx
, func
);
95 if (ctx
->Depth
.Func
!= func
) {
96 ctx
->Depth
.Func
= func
;
97 ctx
->NewState
|= NEW_RASTER_OPS
;
98 ctx
->TriangleCaps
|= DD_Z_NEVER
;
99 if (ctx
->Driver
.DepthFunc
) {
100 (*ctx
->Driver
.DepthFunc
)( ctx
, func
);
105 gl_error( ctx
, GL_INVALID_ENUM
, "glDepth.Func" );
111 void gl_DepthMask( GLcontext
* ctx
, GLboolean flag
)
113 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthMask");
115 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
116 fprintf(stderr
, "glDepthMask %d\n", flag
);
119 * GL_TRUE indicates depth buffer writing is enabled (default)
120 * GL_FALSE indicates depth buffer writing is disabled
122 if (ctx
->Depth
.Mask
!= flag
) {
123 ctx
->Depth
.Mask
= flag
;
124 ctx
->NewState
|= NEW_RASTER_OPS
;
125 if (ctx
->Driver
.DepthMask
) {
126 (*ctx
->Driver
.DepthMask
)( ctx
, flag
);
133 /**********************************************************************/
134 /***** Depth Testing Functions *****/
135 /**********************************************************************/
139 * Depth test horizontal spans of fragments. These functions are called
140 * via ctx->Driver.depth_test_span only.
142 * Input: n - number of pixels in the span
143 * x, y - location of leftmost pixel in span in window coords
144 * z - array [n] of integer depth values
145 * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
146 * Return: number of pixels which passed depth test
151 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
153 GLuint
gl_depth_test_span_generic( GLcontext
* ctx
,
154 GLuint n
, GLint x
, GLint y
,
158 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
163 /* switch cases ordered from most frequent to less frequent */
164 switch (ctx
->Depth
.Func
) {
166 if (ctx
->Depth
.Mask
) {
167 /* Update Z buffer */
168 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
183 /* Don't update Z buffer */
184 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
198 if (ctx
->Depth
.Mask
) {
199 /* Update Z buffer */
200 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
213 /* Don't update Z buffer */
214 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
228 if (ctx
->Depth
.Mask
) {
229 /* Update Z buffer */
230 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
243 /* Don't update Z buffer */
244 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
258 if (ctx
->Depth
.Mask
) {
259 /* Update Z buffer */
260 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
273 /* Don't update Z buffer */
274 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
288 if (ctx
->Depth
.Mask
) {
289 /* Update Z buffer */
290 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
303 /* Don't update Z buffer */
304 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
318 if (ctx
->Depth
.Mask
) {
319 /* Update Z buffer */
320 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
333 /* Don't update Z buffer */
334 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
348 if (ctx
->Depth
.Mask
) {
349 /* Update Z buffer */
350 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
358 /* Don't update Z buffer or mask */
368 gl_problem(ctx
, "Bad depth func in gl_depth_test_span_generic");
377 * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
379 GLuint
gl_depth_test_span_less( GLcontext
* ctx
,
380 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
383 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
387 for (i
=0; i
<n
; i
++) {
389 if (z
[i
] < zptr
[i
]) {
405 * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
407 GLuint
gl_depth_test_span_greater( GLcontext
* ctx
,
408 GLuint n
, GLint x
, GLint y
,
412 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
416 for (i
=0; i
<n
; i
++) {
418 if (z
[i
] > zptr
[i
]) {
435 * Depth test an array of randomly positioned fragments.
439 #define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \
440 GLint width = ctx->Buffer->Width;
442 #define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) )
447 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
449 void gl_depth_test_pixels_generic( GLcontext
* ctx
,
450 GLuint n
, const GLint x
[], const GLint y
[],
451 const GLdepth z
[], GLubyte mask
[] )
453 register GLdepth
*zptr
;
456 /* switch cases ordered from most frequent to less frequent */
457 switch (ctx
->Depth
.Func
) {
459 if (ctx
->Depth
.Mask
) {
460 /* Update Z buffer */
461 for (i
=0; i
<n
; i
++) {
463 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
476 /* Don't update Z buffer */
477 for (i
=0; i
<n
; i
++) {
479 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
492 if (ctx
->Depth
.Mask
) {
493 /* Update Z buffer */
494 for (i
=0; i
<n
; i
++) {
496 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
509 /* Don't update Z buffer */
510 for (i
=0; i
<n
; i
++) {
512 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
525 if (ctx
->Depth
.Mask
) {
526 /* Update Z buffer */
527 for (i
=0; i
<n
; i
++) {
529 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
542 /* Don't update Z buffer */
543 for (i
=0; i
<n
; i
++) {
545 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
558 if (ctx
->Depth
.Mask
) {
559 /* Update Z buffer */
560 for (i
=0; i
<n
; i
++) {
562 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
575 /* Don't update Z buffer */
576 for (i
=0; i
<n
; i
++) {
578 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
591 if (ctx
->Depth
.Mask
) {
592 /* Update Z buffer */
593 for (i
=0; i
<n
; i
++) {
595 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
608 /* Don't update Z buffer */
609 for (i
=0; i
<n
; i
++) {
611 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
624 if (ctx
->Depth
.Mask
) {
625 /* Update Z buffer */
626 for (i
=0; i
<n
; i
++) {
628 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
641 /* Don't update Z buffer */
642 for (i
=0; i
<n
; i
++) {
644 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
657 if (ctx
->Depth
.Mask
) {
658 /* Update Z buffer */
659 for (i
=0; i
<n
; i
++) {
661 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
667 /* Don't update Z buffer or mask */
671 /* depth test never passes */
677 gl_problem(ctx
, "Bad depth func in gl_depth_test_pixels_generic");
684 * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
686 void gl_depth_test_pixels_less( GLcontext
* ctx
,
687 GLuint n
, const GLint x
[], const GLint y
[],
688 const GLdepth z
[], GLubyte mask
[] )
693 for (i
=0; i
<n
; i
++) {
695 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
710 * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
712 void gl_depth_test_pixels_greater( GLcontext
* ctx
,
713 GLuint n
, const GLint x
[], const GLint y
[],
714 const GLdepth z
[], GLubyte mask
[] )
719 for (i
=0; i
<n
; i
++) {
721 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
737 /**********************************************************************/
738 /***** Read Depth Buffer *****/
739 /**********************************************************************/
743 * Return a span of depth values from the depth buffer as floats in [0,1].
744 * This function is only called through Driver.read_depth_span_float()
745 * Input: n - how many pixels
746 * x,y - location of first pixel
747 * Output: depth - the array of depth values
749 void gl_read_depth_span_float( GLcontext
* ctx
,
750 GLuint n
, GLint x
, GLint y
, GLfloat depth
[] )
756 scale
= 1.0F
/ DEPTH_SCALE
;
758 if (ctx
->Buffer
->Depth
) {
759 zptr
= Z_ADDRESS( ctx
, x
, y
);
761 depth
[i
] = (GLfloat
) zptr
[i
] * scale
;
773 * Return a span of depth values from the depth buffer as integers in
775 * This function is only called through Driver.read_depth_span_int()
776 * Input: n - how many pixels
777 * x,y - location of first pixel
778 * Output: depth - the array of depth values
780 void gl_read_depth_span_int( GLcontext
* ctx
,
781 GLuint n
, GLint x
, GLint y
, GLdepth depth
[] )
783 if (ctx
->Buffer
->Depth
) {
784 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
785 MEMCPY( depth
, zptr
, n
* sizeof(GLdepth
) );
797 /**********************************************************************/
798 /***** Allocate and Clear Depth Buffer *****/
799 /**********************************************************************/
804 * Allocate a new depth buffer. If there's already a depth buffer allocated
805 * it will be free()'d. The new depth buffer will be uniniitalized.
806 * This function is only called through Driver.alloc_depth_buffer.
808 void gl_alloc_depth_buffer( GLcontext
* ctx
)
810 /* deallocate current depth buffer if present */
811 if (ctx
->Buffer
->Depth
) {
812 FREE(ctx
->Buffer
->Depth
);
813 ctx
->Buffer
->Depth
= NULL
;
816 /* allocate new depth buffer, but don't initialize it */
817 ctx
->Buffer
->Depth
= (GLdepth
*) MALLOC( ctx
->Buffer
->Width
818 * ctx
->Buffer
->Height
820 if (!ctx
->Buffer
->Depth
) {
822 ctx
->Depth
.Test
= GL_FALSE
;
823 ctx
->NewState
|= NEW_RASTER_OPS
;
824 gl_error( ctx
, GL_OUT_OF_MEMORY
, "Couldn't allocate depth buffer" );
832 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
834 * This function is only called through Driver.clear_depth_buffer.
836 void gl_clear_depth_buffer( GLcontext
* ctx
)
838 GLdepth clear_value
= (GLdepth
) (ctx
->Depth
.Clear
* DEPTH_SCALE
);
840 if (ctx
->Visual
->DepthBits
==0 || !ctx
->Buffer
->Depth
|| !ctx
->Depth
.Mask
) {
841 /* no depth buffer, or writing to it is disabled */
845 /* The loops in this function have been written so the IRIX 5.3
846 * C compiler can unroll them. Hopefully other compilers can too!
849 if (ctx
->Scissor
.Enabled
) {
850 /* only clear scissor region */
852 for (y
=ctx
->Buffer
->Ymin
; y
<=ctx
->Buffer
->Ymax
; y
++) {
853 GLdepth
*d
= Z_ADDRESS( ctx
, ctx
->Buffer
->Xmin
, y
);
854 GLint n
= ctx
->Buffer
->Xmax
- ctx
->Buffer
->Xmin
+ 1;
862 /* clear whole buffer */
863 if (sizeof(GLdepth
)==2 && (clear_value
&0xff)==(clear_value
>>8)) {
864 /* lower and upper bytes of clear_value are same, use MEMSET */
865 MEMSET( ctx
->Buffer
->Depth
, clear_value
&0xff,
866 2*ctx
->Buffer
->Width
*ctx
->Buffer
->Height
);
869 GLdepth
*d
= ctx
->Buffer
->Depth
;
870 GLint n
= ctx
->Buffer
->Width
* ctx
->Buffer
->Height
;
872 d
[0] = clear_value
; d
[1] = clear_value
;
873 d
[2] = clear_value
; d
[3] = clear_value
;
874 d
[4] = clear_value
; d
[5] = clear_value
;
875 d
[6] = clear_value
; d
[7] = clear_value
;
876 d
[8] = clear_value
; d
[9] = clear_value
;
877 d
[10] = clear_value
; d
[11] = clear_value
;
878 d
[12] = clear_value
; d
[13] = clear_value
;
879 d
[14] = clear_value
; d
[15] = clear_value
;