1 /* $Id: depth.c,v 1.9 1999/11/11 01:22:26 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.
40 /**********************************************************************/
41 /***** API Functions *****/
42 /**********************************************************************/
47 _mesa_ClearDepth( GLclampd depth
)
49 GET_CURRENT_CONTEXT(ctx
);
50 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glClearDepth");
51 ctx
->Depth
.Clear
= (GLfloat
) CLAMP( depth
, 0.0, 1.0 );
52 if (ctx
->Driver
.ClearDepth
)
53 (*ctx
->Driver
.ClearDepth
)( ctx
, ctx
->Depth
.Clear
);
59 _mesa_DepthFunc( GLenum func
)
61 GET_CURRENT_CONTEXT(ctx
);
62 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthFunc");
64 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
65 fprintf(stderr
, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func
));
68 case GL_LESS
: /* (default) pass if incoming z < stored z */
75 if (ctx
->Depth
.Func
!= func
) {
76 ctx
->Depth
.Func
= func
;
77 ctx
->NewState
|= NEW_RASTER_OPS
;
78 ctx
->TriangleCaps
&= ~DD_Z_NEVER
;
79 if (ctx
->Driver
.DepthFunc
) {
80 (*ctx
->Driver
.DepthFunc
)( ctx
, func
);
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 gl_error( ctx
, GL_INVALID_ENUM
, "glDepth.Func" );
102 _mesa_DepthMask( GLboolean flag
)
104 GET_CURRENT_CONTEXT(ctx
);
105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthMask");
107 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
108 fprintf(stderr
, "glDepthMask %d\n", flag
);
111 * GL_TRUE indicates depth buffer writing is enabled (default)
112 * GL_FALSE indicates depth buffer writing is disabled
114 if (ctx
->Depth
.Mask
!= flag
) {
115 ctx
->Depth
.Mask
= flag
;
116 ctx
->NewState
|= NEW_RASTER_OPS
;
117 if (ctx
->Driver
.DepthMask
) {
118 (*ctx
->Driver
.DepthMask
)( ctx
, flag
);
125 /**********************************************************************/
126 /***** Depth Testing Functions *****/
127 /**********************************************************************/
131 * Depth test horizontal spans of fragments. These functions are called
132 * via ctx->Driver.depth_test_span only.
134 * Input: n - number of pixels in the span
135 * x, y - location of leftmost pixel in span in window coords
136 * z - array [n] of integer depth values
137 * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
138 * Return: number of pixels which passed depth test
143 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
145 GLuint
gl_depth_test_span_generic( GLcontext
* ctx
,
146 GLuint n
, GLint x
, GLint y
,
150 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
155 /* switch cases ordered from most frequent to less frequent */
156 switch (ctx
->Depth
.Func
) {
158 if (ctx
->Depth
.Mask
) {
159 /* Update Z buffer */
160 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
175 /* Don't update Z buffer */
176 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
190 if (ctx
->Depth
.Mask
) {
191 /* Update Z buffer */
192 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
205 /* Don't update Z buffer */
206 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
220 if (ctx
->Depth
.Mask
) {
221 /* Update Z buffer */
222 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
235 /* Don't update Z buffer */
236 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
250 if (ctx
->Depth
.Mask
) {
251 /* Update Z buffer */
252 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
265 /* Don't update Z buffer */
266 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
280 if (ctx
->Depth
.Mask
) {
281 /* Update Z buffer */
282 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
295 /* Don't update Z buffer */
296 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
310 if (ctx
->Depth
.Mask
) {
311 /* Update Z buffer */
312 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
325 /* Don't update Z buffer */
326 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
340 if (ctx
->Depth
.Mask
) {
341 /* Update Z buffer */
342 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
350 /* Don't update Z buffer or mask */
360 gl_problem(ctx
, "Bad depth func in gl_depth_test_span_generic");
369 * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
371 GLuint
gl_depth_test_span_less( GLcontext
* ctx
,
372 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
375 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
379 for (i
=0; i
<n
; i
++) {
381 if (z
[i
] < zptr
[i
]) {
397 * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
399 GLuint
gl_depth_test_span_greater( GLcontext
* ctx
,
400 GLuint n
, GLint x
, GLint y
,
404 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
408 for (i
=0; i
<n
; i
++) {
410 if (z
[i
] > zptr
[i
]) {
427 * Depth test an array of randomly positioned fragments.
431 #define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \
432 GLint width = ctx->Buffer->Width;
434 #define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) )
439 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
441 void gl_depth_test_pixels_generic( GLcontext
* ctx
,
442 GLuint n
, const GLint x
[], const GLint y
[],
443 const GLdepth z
[], GLubyte mask
[] )
445 register GLdepth
*zptr
;
448 /* switch cases ordered from most frequent to less frequent */
449 switch (ctx
->Depth
.Func
) {
451 if (ctx
->Depth
.Mask
) {
452 /* Update Z buffer */
453 for (i
=0; i
<n
; i
++) {
455 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
468 /* Don't update Z buffer */
469 for (i
=0; i
<n
; i
++) {
471 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
484 if (ctx
->Depth
.Mask
) {
485 /* Update Z buffer */
486 for (i
=0; i
<n
; i
++) {
488 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
501 /* Don't update Z buffer */
502 for (i
=0; i
<n
; i
++) {
504 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
517 if (ctx
->Depth
.Mask
) {
518 /* Update Z buffer */
519 for (i
=0; i
<n
; i
++) {
521 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
534 /* Don't update Z buffer */
535 for (i
=0; i
<n
; i
++) {
537 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
550 if (ctx
->Depth
.Mask
) {
551 /* Update Z buffer */
552 for (i
=0; i
<n
; i
++) {
554 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
567 /* Don't update Z buffer */
568 for (i
=0; i
<n
; i
++) {
570 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
583 if (ctx
->Depth
.Mask
) {
584 /* Update Z buffer */
585 for (i
=0; i
<n
; i
++) {
587 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
600 /* Don't update Z buffer */
601 for (i
=0; i
<n
; i
++) {
603 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
616 if (ctx
->Depth
.Mask
) {
617 /* Update Z buffer */
618 for (i
=0; i
<n
; i
++) {
620 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
633 /* Don't update Z buffer */
634 for (i
=0; i
<n
; i
++) {
636 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
649 if (ctx
->Depth
.Mask
) {
650 /* Update Z buffer */
651 for (i
=0; i
<n
; i
++) {
653 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
659 /* Don't update Z buffer or mask */
663 /* depth test never passes */
669 gl_problem(ctx
, "Bad depth func in gl_depth_test_pixels_generic");
676 * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
678 void gl_depth_test_pixels_less( GLcontext
* ctx
,
679 GLuint n
, const GLint x
[], const GLint y
[],
680 const GLdepth z
[], GLubyte mask
[] )
685 for (i
=0; i
<n
; i
++) {
687 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
702 * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
704 void gl_depth_test_pixels_greater( GLcontext
* ctx
,
705 GLuint n
, const GLint x
[], const GLint y
[],
706 const GLdepth z
[], GLubyte mask
[] )
711 for (i
=0; i
<n
; i
++) {
713 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
729 /**********************************************************************/
730 /***** Read Depth Buffer *****/
731 /**********************************************************************/
735 * Return a span of depth values from the depth buffer as floats in [0,1].
736 * This function is only called through Driver.read_depth_span_float()
737 * Input: n - how many pixels
738 * x,y - location of first pixel
739 * Output: depth - the array of depth values
741 void gl_read_depth_span_float( GLcontext
* ctx
,
742 GLuint n
, GLint x
, GLint y
, GLfloat depth
[] )
748 scale
= 1.0F
/ DEPTH_SCALE
;
750 if (ctx
->Buffer
->Depth
) {
751 zptr
= Z_ADDRESS( ctx
, x
, y
);
753 depth
[i
] = (GLfloat
) zptr
[i
] * scale
;
765 * Return a span of depth values from the depth buffer as integers in
767 * This function is only called through Driver.read_depth_span_int()
768 * Input: n - how many pixels
769 * x,y - location of first pixel
770 * Output: depth - the array of depth values
772 void gl_read_depth_span_int( GLcontext
* ctx
,
773 GLuint n
, GLint x
, GLint y
, GLdepth depth
[] )
775 if (ctx
->Buffer
->Depth
) {
776 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
777 MEMCPY( depth
, zptr
, n
* sizeof(GLdepth
) );
789 /**********************************************************************/
790 /***** Allocate and Clear Depth Buffer *****/
791 /**********************************************************************/
796 * Allocate a new depth buffer. If there's already a depth buffer allocated
797 * it will be free()'d. The new depth buffer will be uniniitalized.
798 * This function is only called through Driver.alloc_depth_buffer.
800 void gl_alloc_depth_buffer( GLcontext
* ctx
)
802 /* deallocate current depth buffer if present */
803 if (ctx
->Buffer
->Depth
) {
804 FREE(ctx
->Buffer
->Depth
);
805 ctx
->Buffer
->Depth
= NULL
;
808 /* allocate new depth buffer, but don't initialize it */
809 ctx
->Buffer
->Depth
= (GLdepth
*) MALLOC( ctx
->Buffer
->Width
810 * ctx
->Buffer
->Height
812 if (!ctx
->Buffer
->Depth
) {
814 ctx
->Depth
.Test
= GL_FALSE
;
815 ctx
->NewState
|= NEW_RASTER_OPS
;
816 gl_error( ctx
, GL_OUT_OF_MEMORY
, "Couldn't allocate depth buffer" );
824 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
826 * This function is only called through Driver.clear_depth_buffer.
828 void gl_clear_depth_buffer( GLcontext
* ctx
)
830 GLdepth clear_value
= (GLdepth
) (ctx
->Depth
.Clear
* DEPTH_SCALE
);
832 if (ctx
->Visual
->DepthBits
==0 || !ctx
->Buffer
->Depth
|| !ctx
->Depth
.Mask
) {
833 /* no depth buffer, or writing to it is disabled */
837 /* The loops in this function have been written so the IRIX 5.3
838 * C compiler can unroll them. Hopefully other compilers can too!
841 if (ctx
->Scissor
.Enabled
) {
842 /* only clear scissor region */
844 for (y
=ctx
->Buffer
->Ymin
; y
<=ctx
->Buffer
->Ymax
; y
++) {
845 GLdepth
*d
= Z_ADDRESS( ctx
, ctx
->Buffer
->Xmin
, y
);
846 GLint n
= ctx
->Buffer
->Xmax
- ctx
->Buffer
->Xmin
+ 1;
854 /* clear whole buffer */
855 if (sizeof(GLdepth
)==2 && (clear_value
&0xff)==(clear_value
>>8)) {
856 /* lower and upper bytes of clear_value are same, use MEMSET */
857 MEMSET( ctx
->Buffer
->Depth
, clear_value
&0xff,
858 2*ctx
->Buffer
->Width
*ctx
->Buffer
->Height
);
861 GLdepth
*d
= ctx
->Buffer
->Depth
;
862 GLint n
= ctx
->Buffer
->Width
* ctx
->Buffer
->Height
;
864 d
[0] = clear_value
; d
[1] = clear_value
;
865 d
[2] = clear_value
; d
[3] = clear_value
;
866 d
[4] = clear_value
; d
[5] = clear_value
;
867 d
[6] = clear_value
; d
[7] = clear_value
;
868 d
[8] = clear_value
; d
[9] = clear_value
;
869 d
[10] = clear_value
; d
[11] = clear_value
;
870 d
[12] = clear_value
; d
[13] = clear_value
;
871 d
[14] = clear_value
; d
[15] = clear_value
;