b2fa94757e3afd6f5df6bb21f3e939994a93282d
1 /* $Id: depth.c,v 1.11 1999/12/10 19:09:22 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.
42 /**********************************************************************/
43 /***** API Functions *****/
44 /**********************************************************************/
49 _mesa_ClearDepth( GLclampd depth
)
51 GET_CURRENT_CONTEXT(ctx
);
52 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glClearDepth");
53 ctx
->Depth
.Clear
= (GLfloat
) CLAMP( depth
, 0.0, 1.0 );
54 if (ctx
->Driver
.ClearDepth
)
55 (*ctx
->Driver
.ClearDepth
)( ctx
, ctx
->Depth
.Clear
);
61 _mesa_DepthFunc( GLenum func
)
63 GET_CURRENT_CONTEXT(ctx
);
64 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthFunc");
66 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
67 fprintf(stderr
, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func
));
70 case GL_LESS
: /* (default) pass if incoming z < stored z */
77 if (ctx
->Depth
.Func
!= func
) {
78 ctx
->Depth
.Func
= func
;
79 ctx
->NewState
|= NEW_RASTER_OPS
;
80 ctx
->TriangleCaps
&= ~DD_Z_NEVER
;
81 if (ctx
->Driver
.DepthFunc
) {
82 (*ctx
->Driver
.DepthFunc
)( ctx
, func
);
87 if (ctx
->Depth
.Func
!= func
) {
88 ctx
->Depth
.Func
= func
;
89 ctx
->NewState
|= NEW_RASTER_OPS
;
90 ctx
->TriangleCaps
|= DD_Z_NEVER
;
91 if (ctx
->Driver
.DepthFunc
) {
92 (*ctx
->Driver
.DepthFunc
)( ctx
, func
);
97 gl_error( ctx
, GL_INVALID_ENUM
, "glDepth.Func" );
104 _mesa_DepthMask( GLboolean flag
)
106 GET_CURRENT_CONTEXT(ctx
);
107 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDepthMask");
109 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
110 fprintf(stderr
, "glDepthMask %d\n", flag
);
113 * GL_TRUE indicates depth buffer writing is enabled (default)
114 * GL_FALSE indicates depth buffer writing is disabled
116 if (ctx
->Depth
.Mask
!= flag
) {
117 ctx
->Depth
.Mask
= flag
;
118 ctx
->NewState
|= NEW_RASTER_OPS
;
119 if (ctx
->Driver
.DepthMask
) {
120 (*ctx
->Driver
.DepthMask
)( ctx
, flag
);
127 /**********************************************************************/
128 /***** Depth Testing Functions *****/
129 /**********************************************************************/
133 * Do depth test for an array of fragments. This is used both for
134 * software and hardware Z buffers.
135 * Input: zbuffer - array of z values in the zbuffer
136 * z - array of fragment z values
137 * Return: number of fragments which pass the test.
140 depth_test_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
141 GLdepth zbuffer
[], const GLdepth z
[], GLubyte mask
[] )
145 /* switch cases ordered from most frequent to less frequent */
146 switch (ctx
->Depth
.Func
) {
148 if (ctx
->Depth
.Mask
) {
149 /* Update Z buffer */
151 for (i
=0; i
<n
; i
++) {
153 if (z
[i
] < zbuffer
[i
]) {
166 /* Don't update Z buffer */
168 for (i
=0; i
<n
; i
++) {
170 if (z
[i
] < zbuffer
[i
]) {
182 if (ctx
->Depth
.Mask
) {
183 /* Update Z buffer */
187 if (z
[i
] <= zbuffer
[i
]) {
198 /* Don't update Z buffer */
202 if (z
[i
] <= zbuffer
[i
]) {
214 if (ctx
->Depth
.Mask
) {
215 /* Update Z buffer */
219 if (z
[i
] >= zbuffer
[i
]) {
230 /* Don't update Z buffer */
234 if (z
[i
] >= zbuffer
[i
]) {
246 if (ctx
->Depth
.Mask
) {
247 /* Update Z buffer */
251 if (z
[i
] > zbuffer
[i
]) {
262 /* Don't update Z buffer */
266 if (z
[i
] > zbuffer
[i
]) {
278 if (ctx
->Depth
.Mask
) {
279 /* Update Z buffer */
283 if (z
[i
] != zbuffer
[i
]) {
294 /* Don't update Z buffer */
298 if (z
[i
] != zbuffer
[i
]) {
310 if (ctx
->Depth
.Mask
) {
311 /* Update Z buffer */
315 if (z
[i
] == zbuffer
[i
]) {
326 /* Don't update Z buffer */
330 if (z
[i
] == zbuffer
[i
]) {
342 if (ctx
->Depth
.Mask
) {
343 /* Update Z buffer */
353 /* Don't update Z buffer or mask */
358 MEMSET(mask
, 0, n
* sizeof(GLubyte
));
361 gl_problem(ctx
, "Bad depth func in depth_test_span");
370 * Apply depth test to span of fragments. Hardware or software z buffer.
373 gl_depth_test_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
374 const GLdepth z
[], GLubyte mask
[] )
376 GLdepth zbuffer
[MAX_WIDTH
];
380 if (ctx
->Driver
.ReadDepthSpan
) {
381 /* read depth values out of hardware Z buffer */
382 (*ctx
->Driver
.ReadDepthSpan
)(ctx
, n
, x
, y
, zbuffer
);
386 /* test against software depth buffer values */
387 zptr
= Z_ADDRESS( ctx
, x
, y
);
390 passed
= depth_test_span( ctx
, n
, x
, y
, zptr
, z
, mask
);
392 if (ctx
->Driver
.WriteDepthSpan
) {
393 /* write updated depth values into hardware Z buffer */
394 assert(zptr
== zbuffer
);
395 (*ctx
->Driver
.WriteDepthSpan
)(ctx
, n
, x
, y
, zbuffer
, mask
);
405 * Do depth testing for an array of fragments using software Z buffer.
408 software_depth_test_pixels( GLcontext
*ctx
, GLuint n
,
409 const GLint x
[], const GLint y
[],
410 const GLdepth z
[], GLubyte mask
[] )
412 /* switch cases ordered from most frequent to less frequent */
413 switch (ctx
->Depth
.Func
) {
415 if (ctx
->Depth
.Mask
) {
416 /* Update Z buffer */
418 for (i
=0; i
<n
; i
++) {
420 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
433 /* Don't update Z buffer */
435 for (i
=0; i
<n
; i
++) {
437 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
450 if (ctx
->Depth
.Mask
) {
451 /* Update Z buffer */
453 for (i
=0; i
<n
; i
++) {
455 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
468 /* Don't update Z buffer */
470 for (i
=0; i
<n
; i
++) {
472 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
485 if (ctx
->Depth
.Mask
) {
486 /* Update Z buffer */
488 for (i
=0; i
<n
; i
++) {
490 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
503 /* Don't update Z buffer */
505 for (i
=0; i
<n
; i
++) {
507 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
520 if (ctx
->Depth
.Mask
) {
521 /* Update Z buffer */
523 for (i
=0; i
<n
; i
++) {
525 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
538 /* Don't update Z buffer */
540 for (i
=0; i
<n
; i
++) {
542 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
555 if (ctx
->Depth
.Mask
) {
556 /* Update Z buffer */
558 for (i
=0; i
<n
; i
++) {
560 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
573 /* Don't update Z buffer */
575 for (i
=0; i
<n
; i
++) {
577 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
590 if (ctx
->Depth
.Mask
) {
591 /* Update Z buffer */
593 for (i
=0; i
<n
; i
++) {
595 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
608 /* Don't update Z buffer */
610 for (i
=0; i
<n
; i
++) {
612 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
625 if (ctx
->Depth
.Mask
) {
626 /* Update Z buffer */
628 for (i
=0; i
<n
; i
++) {
630 GLdepth
*zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
636 /* Don't update Z buffer or mask */
640 /* depth test never passes */
641 MEMSET(mask
, 0, n
* sizeof(GLubyte
));
644 gl_problem(ctx
, "Bad depth func in software_depth_test_pixels");
651 * Do depth testing for an array of pixels using hardware Z buffer.
652 * Input/output: zbuffer - array of depth values from Z buffer
653 * Input: z - array of fragment z values.
656 hardware_depth_test_pixels( GLcontext
*ctx
, GLuint n
, GLdepth zbuffer
[],
657 const GLdepth z
[], GLubyte mask
[] )
659 /* switch cases ordered from most frequent to less frequent */
660 switch (ctx
->Depth
.Func
) {
662 if (ctx
->Depth
.Mask
) {
663 /* Update Z buffer */
665 for (i
=0; i
<n
; i
++) {
667 if (z
[i
] < zbuffer
[i
]) {
679 /* Don't update Z buffer */
681 for (i
=0; i
<n
; i
++) {
683 if (z
[i
] < zbuffer
[i
]) {
695 if (ctx
->Depth
.Mask
) {
696 /* Update Z buffer */
698 for (i
=0; i
<n
; i
++) {
700 if (z
[i
] <= zbuffer
[i
]) {
712 /* Don't update Z buffer */
714 for (i
=0; i
<n
; i
++) {
716 if (z
[i
] <= zbuffer
[i
]) {
728 if (ctx
->Depth
.Mask
) {
729 /* Update Z buffer */
731 for (i
=0; i
<n
; i
++) {
733 if (z
[i
] >= zbuffer
[i
]) {
745 /* Don't update Z buffer */
747 for (i
=0; i
<n
; i
++) {
749 if (z
[i
] >= zbuffer
[i
]) {
761 if (ctx
->Depth
.Mask
) {
762 /* Update Z buffer */
764 for (i
=0; i
<n
; i
++) {
766 if (z
[i
] > zbuffer
[i
]) {
778 /* Don't update Z buffer */
780 for (i
=0; i
<n
; i
++) {
782 if (z
[i
] > zbuffer
[i
]) {
794 if (ctx
->Depth
.Mask
) {
795 /* Update Z buffer */
797 for (i
=0; i
<n
; i
++) {
799 if (z
[i
] != zbuffer
[i
]) {
811 /* Don't update Z buffer */
813 for (i
=0; i
<n
; i
++) {
815 if (z
[i
] != zbuffer
[i
]) {
827 if (ctx
->Depth
.Mask
) {
828 /* Update Z buffer */
830 for (i
=0; i
<n
; i
++) {
832 if (z
[i
] == zbuffer
[i
]) {
844 /* Don't update Z buffer */
846 for (i
=0; i
<n
; i
++) {
848 if (z
[i
] == zbuffer
[i
]) {
860 if (ctx
->Depth
.Mask
) {
861 /* Update Z buffer */
863 for (i
=0; i
<n
; i
++) {
870 /* Don't update Z buffer or mask */
874 /* depth test never passes */
875 MEMSET(mask
, 0, n
* sizeof(GLubyte
));
878 gl_problem(ctx
, "Bad depth func in hardware_depth_test_pixels");
884 void gl_depth_test_pixels( GLcontext
*ctx
,
885 GLuint n
, const GLint x
[], const GLint y
[],
886 const GLdepth z
[], GLubyte mask
[] )
888 if (ctx
->Driver
.ReadDepthPixels
) {
889 /* read depth values from hardware Z buffer */
890 GLdepth zbuffer
[PB_SIZE
];
891 (*ctx
->Driver
.ReadDepthPixels
)(ctx
, n
, x
, y
, zbuffer
);
893 hardware_depth_test_pixels( ctx
, n
, zbuffer
, z
, mask
);
895 /* update hardware Z buffer with new values */
896 assert(ctx
->Driver
.WriteDepthPixels
);
897 (*ctx
->Driver
.WriteDepthPixels
)(ctx
, n
, x
, y
, z
, mask
);
900 /* software depth testing */
901 software_depth_test_pixels(ctx
, n
, x
, y
, z
, mask
);
909 /**********************************************************************/
910 /***** Read Depth Buffer *****/
911 /**********************************************************************/
915 * Return a span of depth values from the depth buffer as floats in [0,1].
916 * This is used for both hardware and software depth buffers.
917 * Input: n - how many pixels
918 * x,y - location of first pixel
919 * Output: depth - the array of depth values
921 void gl_read_depth_span_float( GLcontext
* ctx
,
922 GLuint n
, GLint x
, GLint y
, GLfloat depth
[] )
924 const GLfloat scale
= 1.0F
/ DEPTH_SCALE
;
926 if (ctx
->DrawBuffer
->Depth
) {
927 /* read from software depth buffer */
928 const GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
930 for (i
= 0; i
< n
; i
++) {
931 depth
[i
] = (GLfloat
) zptr
[i
] * scale
;
934 else if (ctx
->Driver
.ReadDepthSpan
) {
935 /* read from hardware depth buffer */
936 GLdepth d
[MAX_WIDTH
];
938 assert(n
<= MAX_WIDTH
);
939 (*ctx
->Driver
.ReadDepthSpan
)( ctx
, n
, x
, y
, d
);
940 for (i
= 0; i
< n
; i
++) {
941 depth
[i
] = d
[i
] * scale
;
945 /* no depth buffer */
946 MEMSET(depth
, 0, n
* sizeof(GLfloat
));
952 /**********************************************************************/
953 /***** Allocate and Clear Depth Buffer *****/
954 /**********************************************************************/
959 * Allocate a new depth buffer. If there's already a depth buffer allocated
960 * it will be free()'d. The new depth buffer will be uniniitalized.
961 * This function is only called through Driver.alloc_depth_buffer.
963 void gl_alloc_depth_buffer( GLcontext
* ctx
)
965 /* deallocate current depth buffer if present */
966 if (ctx
->DrawBuffer
->UseSoftwareDepthBuffer
) {
967 if (ctx
->DrawBuffer
->Depth
) {
968 FREE(ctx
->DrawBuffer
->Depth
);
969 ctx
->DrawBuffer
->Depth
= NULL
;
972 /* allocate new depth buffer, but don't initialize it */
973 ctx
->DrawBuffer
->Depth
= (GLdepth
*) MALLOC( ctx
->DrawBuffer
->Width
974 * ctx
->DrawBuffer
->Height
976 if (!ctx
->DrawBuffer
->Depth
) {
978 ctx
->Depth
.Test
= GL_FALSE
;
979 ctx
->NewState
|= NEW_RASTER_OPS
;
980 gl_error( ctx
, GL_OUT_OF_MEMORY
, "Couldn't allocate depth buffer" );
989 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
991 * This function is only called through Driver.clear_depth_buffer.
993 void gl_clear_depth_buffer( GLcontext
* ctx
)
995 GLdepth clear_value
= (GLdepth
) (ctx
->Depth
.Clear
* DEPTH_SCALE
);
997 if (ctx
->Visual
->DepthBits
==0 || !ctx
->DrawBuffer
->Depth
|| !ctx
->Depth
.Mask
) {
998 /* no depth buffer, or writing to it is disabled */
1002 /* The loops in this function have been written so the IRIX 5.3
1003 * C compiler can unroll them. Hopefully other compilers can too!
1006 if (ctx
->Scissor
.Enabled
) {
1007 /* only clear scissor region */
1009 for (y
=ctx
->DrawBuffer
->Ymin
; y
<=ctx
->DrawBuffer
->Ymax
; y
++) {
1010 GLdepth
*d
= Z_ADDRESS( ctx
, ctx
->DrawBuffer
->Xmin
, y
);
1011 GLint n
= ctx
->DrawBuffer
->Xmax
- ctx
->DrawBuffer
->Xmin
+ 1;
1019 /* clear whole buffer */
1020 if (sizeof(GLdepth
)==2 && (clear_value
&0xff)==(clear_value
>>8)) {
1021 /* lower and upper bytes of clear_value are same, use MEMSET */
1022 MEMSET( ctx
->DrawBuffer
->Depth
, clear_value
& 0xff,
1023 2*ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
);
1026 GLdepth
*d
= ctx
->DrawBuffer
->Depth
;
1027 GLint n
= ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
;
1029 d
[0] = clear_value
; d
[1] = clear_value
;
1030 d
[2] = clear_value
; d
[3] = clear_value
;
1031 d
[4] = clear_value
; d
[5] = clear_value
;
1032 d
[6] = clear_value
; d
[7] = clear_value
;
1033 d
[8] = clear_value
; d
[9] = clear_value
;
1034 d
[10] = clear_value
; d
[11] = clear_value
;
1035 d
[12] = clear_value
; d
[13] = clear_value
;
1036 d
[14] = clear_value
; d
[15] = clear_value
;