fixed compiler warnings on BeOS R4
[mesa.git] / src / mesa / main / depth.c
1 /* $Id: depth.c,v 1.15 2000/03/19 01:10:11 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "context.h"
33 #include "enums.h"
34 #include "depth.h"
35 #include "mem.h"
36 #include "pb.h"
37 #include "types.h"
38 #endif
39
40
41
42 /**********************************************************************/
43 /***** API Functions *****/
44 /**********************************************************************/
45
46
47
48 void
49 _mesa_ClearDepth( GLclampd depth )
50 {
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 );
56 }
57
58
59
60 void
61 _mesa_DepthFunc( GLenum func )
62 {
63 GET_CURRENT_CONTEXT(ctx);
64 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthFunc");
65
66 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
67 fprintf(stderr, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func));
68
69 switch (func) {
70 case GL_LESS: /* (default) pass if incoming z < stored z */
71 case GL_GEQUAL:
72 case GL_LEQUAL:
73 case GL_GREATER:
74 case GL_NOTEQUAL:
75 case GL_EQUAL:
76 case GL_ALWAYS:
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 );
83 }
84 }
85 break;
86 case GL_NEVER:
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 );
93 }
94 }
95 break;
96 default:
97 gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
98 }
99 }
100
101
102
103 void
104 _mesa_DepthMask( GLboolean flag )
105 {
106 GET_CURRENT_CONTEXT(ctx);
107 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthMask");
108
109 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
110 fprintf(stderr, "glDepthMask %d\n", flag);
111
112 /*
113 * GL_TRUE indicates depth buffer writing is enabled (default)
114 * GL_FALSE indicates depth buffer writing is disabled
115 */
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 );
121 }
122 }
123 }
124
125
126
127 /**********************************************************************/
128 /***** Misc *****/
129 /**********************************************************************/
130
131 /*
132 * Return address of depth buffer value for given window coord.
133 */
134 GLvoid *
135 _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
136 {
137 if (ctx->Visual->DepthBits <= 16)
138 return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
139 else
140 return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
141 }
142
143
144 #define Z_ADDRESS16( CTX, X, Y ) \
145 ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \
146 + (CTX)->DrawBuffer->Width * (Y) + (X) )
147
148 #define Z_ADDRESS32( CTX, X, Y ) \
149 ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \
150 + (CTX)->DrawBuffer->Width * (Y) + (X) )
151
152
153
154 /**********************************************************************/
155 /***** Depth Testing Functions *****/
156 /**********************************************************************/
157
158
159 /*
160 * Do depth test for an array of fragments. This is used both for
161 * software and hardware Z buffers.
162 * Input: zbuffer - array of z values in the zbuffer
163 * z - array of fragment z values
164 * Return: number of fragments which pass the test.
165 */
166 static GLuint
167 depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
168 GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
169 {
170 GLuint passed = 0;
171
172 /* switch cases ordered from most frequent to less frequent */
173 switch (ctx->Depth.Func) {
174 case GL_LESS:
175 if (ctx->Depth.Mask) {
176 /* Update Z buffer */
177 GLuint i;
178 for (i=0; i<n; i++) {
179 if (mask[i]) {
180 if (z[i] < zbuffer[i]) {
181 /* pass */
182 zbuffer[i] = z[i];
183 passed++;
184 }
185 else {
186 /* fail */
187 mask[i] = 0;
188 }
189 }
190 }
191 }
192 else {
193 /* Don't update Z buffer */
194 GLuint i;
195 for (i=0; i<n; i++) {
196 if (mask[i]) {
197 if (z[i] < zbuffer[i]) {
198 /* pass */
199 passed++;
200 }
201 else {
202 mask[i] = 0;
203 }
204 }
205 }
206 }
207 break;
208 case GL_LEQUAL:
209 if (ctx->Depth.Mask) {
210 /* Update Z buffer */
211 GLuint i;
212 for (i=0;i<n;i++) {
213 if (mask[i]) {
214 if (z[i] <= zbuffer[i]) {
215 zbuffer[i] = z[i];
216 passed++;
217 }
218 else {
219 mask[i] = 0;
220 }
221 }
222 }
223 }
224 else {
225 /* Don't update Z buffer */
226 GLuint i;
227 for (i=0;i<n;i++) {
228 if (mask[i]) {
229 if (z[i] <= zbuffer[i]) {
230 /* pass */
231 passed++;
232 }
233 else {
234 mask[i] = 0;
235 }
236 }
237 }
238 }
239 break;
240 case GL_GEQUAL:
241 if (ctx->Depth.Mask) {
242 /* Update Z buffer */
243 GLuint i;
244 for (i=0;i<n;i++) {
245 if (mask[i]) {
246 if (z[i] >= zbuffer[i]) {
247 zbuffer[i] = z[i];
248 passed++;
249 }
250 else {
251 mask[i] = 0;
252 }
253 }
254 }
255 }
256 else {
257 /* Don't update Z buffer */
258 GLuint i;
259 for (i=0;i<n;i++) {
260 if (mask[i]) {
261 if (z[i] >= zbuffer[i]) {
262 /* pass */
263 passed++;
264 }
265 else {
266 mask[i] = 0;
267 }
268 }
269 }
270 }
271 break;
272 case GL_GREATER:
273 if (ctx->Depth.Mask) {
274 /* Update Z buffer */
275 GLuint i;
276 for (i=0;i<n;i++) {
277 if (mask[i]) {
278 if (z[i] > zbuffer[i]) {
279 zbuffer[i] = z[i];
280 passed++;
281 }
282 else {
283 mask[i] = 0;
284 }
285 }
286 }
287 }
288 else {
289 /* Don't update Z buffer */
290 GLuint i;
291 for (i=0;i<n;i++) {
292 if (mask[i]) {
293 if (z[i] > zbuffer[i]) {
294 /* pass */
295 passed++;
296 }
297 else {
298 mask[i] = 0;
299 }
300 }
301 }
302 }
303 break;
304 case GL_NOTEQUAL:
305 if (ctx->Depth.Mask) {
306 /* Update Z buffer */
307 GLuint i;
308 for (i=0;i<n;i++) {
309 if (mask[i]) {
310 if (z[i] != zbuffer[i]) {
311 zbuffer[i] = z[i];
312 passed++;
313 }
314 else {
315 mask[i] = 0;
316 }
317 }
318 }
319 }
320 else {
321 /* Don't update Z buffer */
322 GLuint i;
323 for (i=0;i<n;i++) {
324 if (mask[i]) {
325 if (z[i] != zbuffer[i]) {
326 /* pass */
327 passed++;
328 }
329 else {
330 mask[i] = 0;
331 }
332 }
333 }
334 }
335 break;
336 case GL_EQUAL:
337 if (ctx->Depth.Mask) {
338 /* Update Z buffer */
339 GLuint i;
340 for (i=0;i<n;i++) {
341 if (mask[i]) {
342 if (z[i] == zbuffer[i]) {
343 zbuffer[i] = z[i];
344 passed++;
345 }
346 else {
347 mask[i] = 0;
348 }
349 }
350 }
351 }
352 else {
353 /* Don't update Z buffer */
354 GLuint i;
355 for (i=0;i<n;i++) {
356 if (mask[i]) {
357 if (z[i] == zbuffer[i]) {
358 /* pass */
359 passed++;
360 }
361 else {
362 mask[i] = 0;
363 }
364 }
365 }
366 }
367 break;
368 case GL_ALWAYS:
369 if (ctx->Depth.Mask) {
370 /* Update Z buffer */
371 GLuint i;
372 for (i=0;i<n;i++) {
373 if (mask[i]) {
374 zbuffer[i] = z[i];
375 passed++;
376 }
377 }
378 }
379 else {
380 /* Don't update Z buffer or mask */
381 passed = n;
382 }
383 break;
384 case GL_NEVER:
385 MEMSET(mask, 0, n * sizeof(GLubyte));
386 break;
387 default:
388 gl_problem(ctx, "Bad depth func in depth_test_span16");
389 }
390
391 return passed;
392 }
393
394
395 static GLuint
396 depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
397 GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
398 {
399 GLuint passed = 0;
400
401 /* switch cases ordered from most frequent to less frequent */
402 switch (ctx->Depth.Func) {
403 case GL_LESS:
404 if (ctx->Depth.Mask) {
405 /* Update Z buffer */
406 GLuint i;
407 for (i=0; i<n; i++) {
408 if (mask[i]) {
409 if (z[i] < zbuffer[i]) {
410 /* pass */
411 zbuffer[i] = z[i];
412 passed++;
413 }
414 else {
415 /* fail */
416 mask[i] = 0;
417 }
418 }
419 }
420 }
421 else {
422 /* Don't update Z buffer */
423 GLuint i;
424 for (i=0; i<n; i++) {
425 if (mask[i]) {
426 if (z[i] < zbuffer[i]) {
427 /* pass */
428 passed++;
429 }
430 else {
431 mask[i] = 0;
432 }
433 }
434 }
435 }
436 break;
437 case GL_LEQUAL:
438 if (ctx->Depth.Mask) {
439 /* Update Z buffer */
440 GLuint i;
441 for (i=0;i<n;i++) {
442 if (mask[i]) {
443 if (z[i] <= zbuffer[i]) {
444 zbuffer[i] = z[i];
445 passed++;
446 }
447 else {
448 mask[i] = 0;
449 }
450 }
451 }
452 }
453 else {
454 /* Don't update Z buffer */
455 GLuint i;
456 for (i=0;i<n;i++) {
457 if (mask[i]) {
458 if (z[i] <= zbuffer[i]) {
459 /* pass */
460 passed++;
461 }
462 else {
463 mask[i] = 0;
464 }
465 }
466 }
467 }
468 break;
469 case GL_GEQUAL:
470 if (ctx->Depth.Mask) {
471 /* Update Z buffer */
472 GLuint i;
473 for (i=0;i<n;i++) {
474 if (mask[i]) {
475 if (z[i] >= zbuffer[i]) {
476 zbuffer[i] = z[i];
477 passed++;
478 }
479 else {
480 mask[i] = 0;
481 }
482 }
483 }
484 }
485 else {
486 /* Don't update Z buffer */
487 GLuint i;
488 for (i=0;i<n;i++) {
489 if (mask[i]) {
490 if (z[i] >= zbuffer[i]) {
491 /* pass */
492 passed++;
493 }
494 else {
495 mask[i] = 0;
496 }
497 }
498 }
499 }
500 break;
501 case GL_GREATER:
502 if (ctx->Depth.Mask) {
503 /* Update Z buffer */
504 GLuint i;
505 for (i=0;i<n;i++) {
506 if (mask[i]) {
507 if (z[i] > zbuffer[i]) {
508 zbuffer[i] = z[i];
509 passed++;
510 }
511 else {
512 mask[i] = 0;
513 }
514 }
515 }
516 }
517 else {
518 /* Don't update Z buffer */
519 GLuint i;
520 for (i=0;i<n;i++) {
521 if (mask[i]) {
522 if (z[i] > zbuffer[i]) {
523 /* pass */
524 passed++;
525 }
526 else {
527 mask[i] = 0;
528 }
529 }
530 }
531 }
532 break;
533 case GL_NOTEQUAL:
534 if (ctx->Depth.Mask) {
535 /* Update Z buffer */
536 GLuint i;
537 for (i=0;i<n;i++) {
538 if (mask[i]) {
539 if (z[i] != zbuffer[i]) {
540 zbuffer[i] = z[i];
541 passed++;
542 }
543 else {
544 mask[i] = 0;
545 }
546 }
547 }
548 }
549 else {
550 /* Don't update Z buffer */
551 GLuint i;
552 for (i=0;i<n;i++) {
553 if (mask[i]) {
554 if (z[i] != zbuffer[i]) {
555 /* pass */
556 passed++;
557 }
558 else {
559 mask[i] = 0;
560 }
561 }
562 }
563 }
564 break;
565 case GL_EQUAL:
566 if (ctx->Depth.Mask) {
567 /* Update Z buffer */
568 GLuint i;
569 for (i=0;i<n;i++) {
570 if (mask[i]) {
571 if (z[i] == zbuffer[i]) {
572 zbuffer[i] = z[i];
573 passed++;
574 }
575 else {
576 mask[i] = 0;
577 }
578 }
579 }
580 }
581 else {
582 /* Don't update Z buffer */
583 GLuint i;
584 for (i=0;i<n;i++) {
585 if (mask[i]) {
586 if (z[i] == zbuffer[i]) {
587 /* pass */
588 passed++;
589 }
590 else {
591 mask[i] = 0;
592 }
593 }
594 }
595 }
596 break;
597 case GL_ALWAYS:
598 if (ctx->Depth.Mask) {
599 /* Update Z buffer */
600 GLuint i;
601 for (i=0;i<n;i++) {
602 if (mask[i]) {
603 zbuffer[i] = z[i];
604 passed++;
605 }
606 }
607 }
608 else {
609 /* Don't update Z buffer or mask */
610 passed = n;
611 }
612 break;
613 case GL_NEVER:
614 MEMSET(mask, 0, n * sizeof(GLubyte));
615 break;
616 default:
617 gl_problem(ctx, "Bad depth func in depth_test_span32");
618 }
619
620 return passed;
621 }
622
623
624
625 /*
626 * Apply depth test to span of fragments. Hardware or software z buffer.
627 */
628 GLuint
629 _mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
630 const GLdepth z[], GLubyte mask[] )
631 {
632 if (ctx->Driver.ReadDepthSpan) {
633 /* hardware-based depth buffer */
634 GLdepth zbuffer[MAX_WIDTH];
635 GLuint passed;
636 (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
637 passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
638 assert(ctx->Driver.WriteDepthSpan);
639 (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
640 return passed;
641 }
642 else {
643 /* software depth buffer */
644 if (ctx->Visual->DepthBits <= 16) {
645 GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
646 GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
647 return passed;
648 }
649 else {
650 GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
651 GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
652 return passed;
653 }
654 }
655 }
656
657
658
659
660 /*
661 * Do depth testing for an array of fragments using software Z buffer.
662 */
663 static void
664 software_depth_test_pixels16( GLcontext *ctx, GLuint n,
665 const GLint x[], const GLint y[],
666 const GLdepth z[], GLubyte mask[] )
667 {
668 /* switch cases ordered from most frequent to less frequent */
669 switch (ctx->Depth.Func) {
670 case GL_LESS:
671 if (ctx->Depth.Mask) {
672 /* Update Z buffer */
673 GLuint i;
674 for (i=0; i<n; i++) {
675 if (mask[i]) {
676 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
677 if (z[i] < *zptr) {
678 /* pass */
679 *zptr = z[i];
680 }
681 else {
682 /* fail */
683 mask[i] = 0;
684 }
685 }
686 }
687 }
688 else {
689 /* Don't update Z buffer */
690 GLuint i;
691 for (i=0; i<n; i++) {
692 if (mask[i]) {
693 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
694 if (z[i] < *zptr) {
695 /* pass */
696 }
697 else {
698 /* fail */
699 mask[i] = 0;
700 }
701 }
702 }
703 }
704 break;
705 case GL_LEQUAL:
706 if (ctx->Depth.Mask) {
707 /* Update Z buffer */
708 GLuint i;
709 for (i=0; i<n; i++) {
710 if (mask[i]) {
711 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
712 if (z[i] <= *zptr) {
713 /* pass */
714 *zptr = z[i];
715 }
716 else {
717 /* fail */
718 mask[i] = 0;
719 }
720 }
721 }
722 }
723 else {
724 /* Don't update Z buffer */
725 GLuint i;
726 for (i=0; i<n; i++) {
727 if (mask[i]) {
728 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
729 if (z[i] <= *zptr) {
730 /* pass */
731 }
732 else {
733 /* fail */
734 mask[i] = 0;
735 }
736 }
737 }
738 }
739 break;
740 case GL_GEQUAL:
741 if (ctx->Depth.Mask) {
742 /* Update Z buffer */
743 GLuint i;
744 for (i=0; i<n; i++) {
745 if (mask[i]) {
746 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
747 if (z[i] >= *zptr) {
748 /* pass */
749 *zptr = z[i];
750 }
751 else {
752 /* fail */
753 mask[i] = 0;
754 }
755 }
756 }
757 }
758 else {
759 /* Don't update Z buffer */
760 GLuint i;
761 for (i=0; i<n; i++) {
762 if (mask[i]) {
763 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
764 if (z[i] >= *zptr) {
765 /* pass */
766 }
767 else {
768 /* fail */
769 mask[i] = 0;
770 }
771 }
772 }
773 }
774 break;
775 case GL_GREATER:
776 if (ctx->Depth.Mask) {
777 /* Update Z buffer */
778 GLuint i;
779 for (i=0; i<n; i++) {
780 if (mask[i]) {
781 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
782 if (z[i] > *zptr) {
783 /* pass */
784 *zptr = z[i];
785 }
786 else {
787 /* fail */
788 mask[i] = 0;
789 }
790 }
791 }
792 }
793 else {
794 /* Don't update Z buffer */
795 GLuint i;
796 for (i=0; i<n; i++) {
797 if (mask[i]) {
798 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
799 if (z[i] > *zptr) {
800 /* pass */
801 }
802 else {
803 /* fail */
804 mask[i] = 0;
805 }
806 }
807 }
808 }
809 break;
810 case GL_NOTEQUAL:
811 if (ctx->Depth.Mask) {
812 /* Update Z buffer */
813 GLuint i;
814 for (i=0; i<n; i++) {
815 if (mask[i]) {
816 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
817 if (z[i] != *zptr) {
818 /* pass */
819 *zptr = z[i];
820 }
821 else {
822 /* fail */
823 mask[i] = 0;
824 }
825 }
826 }
827 }
828 else {
829 /* Don't update Z buffer */
830 GLuint i;
831 for (i=0; i<n; i++) {
832 if (mask[i]) {
833 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
834 if (z[i] != *zptr) {
835 /* pass */
836 }
837 else {
838 /* fail */
839 mask[i] = 0;
840 }
841 }
842 }
843 }
844 break;
845 case GL_EQUAL:
846 if (ctx->Depth.Mask) {
847 /* Update Z buffer */
848 GLuint i;
849 for (i=0; i<n; i++) {
850 if (mask[i]) {
851 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
852 if (z[i] == *zptr) {
853 /* pass */
854 *zptr = z[i];
855 }
856 else {
857 /* fail */
858 mask[i] = 0;
859 }
860 }
861 }
862 }
863 else {
864 /* Don't update Z buffer */
865 GLuint i;
866 for (i=0; i<n; i++) {
867 if (mask[i]) {
868 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
869 if (z[i] == *zptr) {
870 /* pass */
871 }
872 else {
873 /* fail */
874 mask[i] = 0;
875 }
876 }
877 }
878 }
879 break;
880 case GL_ALWAYS:
881 if (ctx->Depth.Mask) {
882 /* Update Z buffer */
883 GLuint i;
884 for (i=0; i<n; i++) {
885 if (mask[i]) {
886 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
887 *zptr = z[i];
888 }
889 }
890 }
891 else {
892 /* Don't update Z buffer or mask */
893 }
894 break;
895 case GL_NEVER:
896 /* depth test never passes */
897 MEMSET(mask, 0, n * sizeof(GLubyte));
898 break;
899 default:
900 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
901 }
902 }
903
904
905
906 /*
907 * Do depth testing for an array of fragments using software Z buffer.
908 */
909 static void
910 software_depth_test_pixels32( GLcontext *ctx, GLuint n,
911 const GLint x[], const GLint y[],
912 const GLdepth z[], GLubyte mask[] )
913 {
914 /* switch cases ordered from most frequent to less frequent */
915 switch (ctx->Depth.Func) {
916 case GL_LESS:
917 if (ctx->Depth.Mask) {
918 /* Update Z buffer */
919 GLuint i;
920 for (i=0; i<n; i++) {
921 if (mask[i]) {
922 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
923 if (z[i] < *zptr) {
924 /* pass */
925 *zptr = z[i];
926 }
927 else {
928 /* fail */
929 mask[i] = 0;
930 }
931 }
932 }
933 }
934 else {
935 /* Don't update Z buffer */
936 GLuint i;
937 for (i=0; i<n; i++) {
938 if (mask[i]) {
939 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
940 if (z[i] < *zptr) {
941 /* pass */
942 }
943 else {
944 /* fail */
945 mask[i] = 0;
946 }
947 }
948 }
949 }
950 break;
951 case GL_LEQUAL:
952 if (ctx->Depth.Mask) {
953 /* Update Z buffer */
954 GLuint i;
955 for (i=0; i<n; i++) {
956 if (mask[i]) {
957 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
958 if (z[i] <= *zptr) {
959 /* pass */
960 *zptr = z[i];
961 }
962 else {
963 /* fail */
964 mask[i] = 0;
965 }
966 }
967 }
968 }
969 else {
970 /* Don't update Z buffer */
971 GLuint i;
972 for (i=0; i<n; i++) {
973 if (mask[i]) {
974 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
975 if (z[i] <= *zptr) {
976 /* pass */
977 }
978 else {
979 /* fail */
980 mask[i] = 0;
981 }
982 }
983 }
984 }
985 break;
986 case GL_GEQUAL:
987 if (ctx->Depth.Mask) {
988 /* Update Z buffer */
989 GLuint i;
990 for (i=0; i<n; i++) {
991 if (mask[i]) {
992 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
993 if (z[i] >= *zptr) {
994 /* pass */
995 *zptr = z[i];
996 }
997 else {
998 /* fail */
999 mask[i] = 0;
1000 }
1001 }
1002 }
1003 }
1004 else {
1005 /* Don't update Z buffer */
1006 GLuint i;
1007 for (i=0; i<n; i++) {
1008 if (mask[i]) {
1009 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1010 if (z[i] >= *zptr) {
1011 /* pass */
1012 }
1013 else {
1014 /* fail */
1015 mask[i] = 0;
1016 }
1017 }
1018 }
1019 }
1020 break;
1021 case GL_GREATER:
1022 if (ctx->Depth.Mask) {
1023 /* Update Z buffer */
1024 GLuint i;
1025 for (i=0; i<n; i++) {
1026 if (mask[i]) {
1027 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1028 if (z[i] > *zptr) {
1029 /* pass */
1030 *zptr = z[i];
1031 }
1032 else {
1033 /* fail */
1034 mask[i] = 0;
1035 }
1036 }
1037 }
1038 }
1039 else {
1040 /* Don't update Z buffer */
1041 GLuint i;
1042 for (i=0; i<n; i++) {
1043 if (mask[i]) {
1044 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1045 if (z[i] > *zptr) {
1046 /* pass */
1047 }
1048 else {
1049 /* fail */
1050 mask[i] = 0;
1051 }
1052 }
1053 }
1054 }
1055 break;
1056 case GL_NOTEQUAL:
1057 if (ctx->Depth.Mask) {
1058 /* Update Z buffer */
1059 GLuint i;
1060 for (i=0; i<n; i++) {
1061 if (mask[i]) {
1062 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1063 if (z[i] != *zptr) {
1064 /* pass */
1065 *zptr = z[i];
1066 }
1067 else {
1068 /* fail */
1069 mask[i] = 0;
1070 }
1071 }
1072 }
1073 }
1074 else {
1075 /* Don't update Z buffer */
1076 GLuint i;
1077 for (i=0; i<n; i++) {
1078 if (mask[i]) {
1079 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1080 if (z[i] != *zptr) {
1081 /* pass */
1082 }
1083 else {
1084 /* fail */
1085 mask[i] = 0;
1086 }
1087 }
1088 }
1089 }
1090 break;
1091 case GL_EQUAL:
1092 if (ctx->Depth.Mask) {
1093 /* Update Z buffer */
1094 GLuint i;
1095 for (i=0; i<n; i++) {
1096 if (mask[i]) {
1097 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1098 if (z[i] == *zptr) {
1099 /* pass */
1100 *zptr = z[i];
1101 }
1102 else {
1103 /* fail */
1104 mask[i] = 0;
1105 }
1106 }
1107 }
1108 }
1109 else {
1110 /* Don't update Z buffer */
1111 GLuint i;
1112 for (i=0; i<n; i++) {
1113 if (mask[i]) {
1114 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1115 if (z[i] == *zptr) {
1116 /* pass */
1117 }
1118 else {
1119 /* fail */
1120 mask[i] = 0;
1121 }
1122 }
1123 }
1124 }
1125 break;
1126 case GL_ALWAYS:
1127 if (ctx->Depth.Mask) {
1128 /* Update Z buffer */
1129 GLuint i;
1130 for (i=0; i<n; i++) {
1131 if (mask[i]) {
1132 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1133 *zptr = z[i];
1134 }
1135 }
1136 }
1137 else {
1138 /* Don't update Z buffer or mask */
1139 }
1140 break;
1141 case GL_NEVER:
1142 /* depth test never passes */
1143 MEMSET(mask, 0, n * sizeof(GLubyte));
1144 break;
1145 default:
1146 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
1147 }
1148 }
1149
1150
1151
1152 /*
1153 * Do depth testing for an array of pixels using hardware Z buffer.
1154 * Input/output: zbuffer - array of depth values from Z buffer
1155 * Input: z - array of fragment z values.
1156 */
1157 static void
1158 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
1159 const GLdepth z[], GLubyte mask[] )
1160 {
1161 /* switch cases ordered from most frequent to less frequent */
1162 switch (ctx->Depth.Func) {
1163 case GL_LESS:
1164 if (ctx->Depth.Mask) {
1165 /* Update Z buffer */
1166 GLuint i;
1167 for (i=0; i<n; i++) {
1168 if (mask[i]) {
1169 if (z[i] < zbuffer[i]) {
1170 /* pass */
1171 zbuffer[i] = z[i];
1172 }
1173 else {
1174 /* fail */
1175 mask[i] = 0;
1176 }
1177 }
1178 }
1179 }
1180 else {
1181 /* Don't update Z buffer */
1182 GLuint i;
1183 for (i=0; i<n; i++) {
1184 if (mask[i]) {
1185 if (z[i] < zbuffer[i]) {
1186 /* pass */
1187 }
1188 else {
1189 /* fail */
1190 mask[i] = 0;
1191 }
1192 }
1193 }
1194 }
1195 break;
1196 case GL_LEQUAL:
1197 if (ctx->Depth.Mask) {
1198 /* Update Z buffer */
1199 GLuint i;
1200 for (i=0; i<n; i++) {
1201 if (mask[i]) {
1202 if (z[i] <= zbuffer[i]) {
1203 /* pass */
1204 zbuffer[i] = z[i];
1205 }
1206 else {
1207 /* fail */
1208 mask[i] = 0;
1209 }
1210 }
1211 }
1212 }
1213 else {
1214 /* Don't update Z buffer */
1215 GLuint i;
1216 for (i=0; i<n; i++) {
1217 if (mask[i]) {
1218 if (z[i] <= zbuffer[i]) {
1219 /* pass */
1220 }
1221 else {
1222 /* fail */
1223 mask[i] = 0;
1224 }
1225 }
1226 }
1227 }
1228 break;
1229 case GL_GEQUAL:
1230 if (ctx->Depth.Mask) {
1231 /* Update Z buffer */
1232 GLuint i;
1233 for (i=0; i<n; i++) {
1234 if (mask[i]) {
1235 if (z[i] >= zbuffer[i]) {
1236 /* pass */
1237 zbuffer[i] = z[i];
1238 }
1239 else {
1240 /* fail */
1241 mask[i] = 0;
1242 }
1243 }
1244 }
1245 }
1246 else {
1247 /* Don't update Z buffer */
1248 GLuint i;
1249 for (i=0; i<n; i++) {
1250 if (mask[i]) {
1251 if (z[i] >= zbuffer[i]) {
1252 /* pass */
1253 }
1254 else {
1255 /* fail */
1256 mask[i] = 0;
1257 }
1258 }
1259 }
1260 }
1261 break;
1262 case GL_GREATER:
1263 if (ctx->Depth.Mask) {
1264 /* Update Z buffer */
1265 GLuint i;
1266 for (i=0; i<n; i++) {
1267 if (mask[i]) {
1268 if (z[i] > zbuffer[i]) {
1269 /* pass */
1270 zbuffer[i] = z[i];
1271 }
1272 else {
1273 /* fail */
1274 mask[i] = 0;
1275 }
1276 }
1277 }
1278 }
1279 else {
1280 /* Don't update Z buffer */
1281 GLuint i;
1282 for (i=0; i<n; i++) {
1283 if (mask[i]) {
1284 if (z[i] > zbuffer[i]) {
1285 /* pass */
1286 }
1287 else {
1288 /* fail */
1289 mask[i] = 0;
1290 }
1291 }
1292 }
1293 }
1294 break;
1295 case GL_NOTEQUAL:
1296 if (ctx->Depth.Mask) {
1297 /* Update Z buffer */
1298 GLuint i;
1299 for (i=0; i<n; i++) {
1300 if (mask[i]) {
1301 if (z[i] != zbuffer[i]) {
1302 /* pass */
1303 zbuffer[i] = z[i];
1304 }
1305 else {
1306 /* fail */
1307 mask[i] = 0;
1308 }
1309 }
1310 }
1311 }
1312 else {
1313 /* Don't update Z buffer */
1314 GLuint i;
1315 for (i=0; i<n; i++) {
1316 if (mask[i]) {
1317 if (z[i] != zbuffer[i]) {
1318 /* pass */
1319 }
1320 else {
1321 /* fail */
1322 mask[i] = 0;
1323 }
1324 }
1325 }
1326 }
1327 break;
1328 case GL_EQUAL:
1329 if (ctx->Depth.Mask) {
1330 /* Update Z buffer */
1331 GLuint i;
1332 for (i=0; i<n; i++) {
1333 if (mask[i]) {
1334 if (z[i] == zbuffer[i]) {
1335 /* pass */
1336 zbuffer[i] = z[i];
1337 }
1338 else {
1339 /* fail */
1340 mask[i] = 0;
1341 }
1342 }
1343 }
1344 }
1345 else {
1346 /* Don't update Z buffer */
1347 GLuint i;
1348 for (i=0; i<n; i++) {
1349 if (mask[i]) {
1350 if (z[i] == zbuffer[i]) {
1351 /* pass */
1352 }
1353 else {
1354 /* fail */
1355 mask[i] = 0;
1356 }
1357 }
1358 }
1359 }
1360 break;
1361 case GL_ALWAYS:
1362 if (ctx->Depth.Mask) {
1363 /* Update Z buffer */
1364 GLuint i;
1365 for (i=0; i<n; i++) {
1366 if (mask[i]) {
1367 zbuffer[i] = z[i];
1368 }
1369 }
1370 }
1371 else {
1372 /* Don't update Z buffer or mask */
1373 }
1374 break;
1375 case GL_NEVER:
1376 /* depth test never passes */
1377 MEMSET(mask, 0, n * sizeof(GLubyte));
1378 break;
1379 default:
1380 gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
1381 }
1382 }
1383
1384
1385
1386 void
1387 _mesa_depth_test_pixels( GLcontext *ctx,
1388 GLuint n, const GLint x[], const GLint y[],
1389 const GLdepth z[], GLubyte mask[] )
1390 {
1391 if (ctx->Driver.ReadDepthPixels) {
1392 /* read depth values from hardware Z buffer */
1393 GLdepth zbuffer[PB_SIZE];
1394 (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
1395
1396 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
1397
1398 /* update hardware Z buffer with new values */
1399 assert(ctx->Driver.WriteDepthPixels);
1400 (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
1401 }
1402 else {
1403 /* software depth testing */
1404 if (ctx->Visual->DepthBits <= 16)
1405 software_depth_test_pixels16(ctx, n, x, y, z, mask);
1406 else
1407 software_depth_test_pixels32(ctx, n, x, y, z, mask);
1408 }
1409 }
1410
1411
1412
1413
1414
1415 /**********************************************************************/
1416 /***** Read Depth Buffer *****/
1417 /**********************************************************************/
1418
1419
1420 /*
1421 * Return a span of depth values from the depth buffer as floats in [0,1].
1422 * This is used for both hardware and software depth buffers.
1423 * Input: n - how many pixels
1424 * x,y - location of first pixel
1425 * Output: depth - the array of depth values
1426 */
1427 void
1428 _mesa_read_depth_span_float( GLcontext* ctx,
1429 GLuint n, GLint x, GLint y, GLfloat depth[] )
1430 {
1431 const GLfloat scale = 1.0F / ctx->Visual->DepthMaxF;
1432
1433 if (ctx->DrawBuffer->DepthBuffer) {
1434 /* read from software depth buffer */
1435 if (ctx->Visual->DepthBits <= 16) {
1436 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1437 GLuint i;
1438 for (i = 0; i < n; i++) {
1439 depth[i] = (GLfloat) zptr[i] * scale;
1440 }
1441 }
1442 else {
1443 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1444 GLuint i;
1445 for (i = 0; i < n; i++) {
1446 depth[i] = (GLfloat) zptr[i] * scale;
1447 }
1448 }
1449 }
1450 else if (ctx->Driver.ReadDepthSpan) {
1451 /* read from hardware depth buffer */
1452 GLdepth d[MAX_WIDTH];
1453 GLuint i;
1454 assert(n <= MAX_WIDTH);
1455 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
1456 for (i = 0; i < n; i++) {
1457 depth[i] = d[i] * scale;
1458 }
1459 }
1460 else {
1461 /* no depth buffer */
1462 MEMSET(depth, 0, n * sizeof(GLfloat));
1463 }
1464 }
1465
1466
1467
1468 /**********************************************************************/
1469 /***** Allocate and Clear Depth Buffer *****/
1470 /**********************************************************************/
1471
1472
1473
1474 /*
1475 * Allocate a new depth buffer. If there's already a depth buffer allocated
1476 * it will be free()'d. The new depth buffer will be uniniitalized.
1477 * This function is only called through Driver.alloc_depth_buffer.
1478 */
1479 void
1480 _mesa_alloc_depth_buffer( GLcontext *ctx )
1481 {
1482 /* deallocate current depth buffer if present */
1483 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1484 GLint bytesPerValue;
1485
1486 if (ctx->DrawBuffer->DepthBuffer) {
1487 FREE(ctx->DrawBuffer->DepthBuffer);
1488 ctx->DrawBuffer->DepthBuffer = NULL;
1489 }
1490
1491 /* allocate new depth buffer, but don't initialize it */
1492 if (ctx->Visual->DepthBits <= 16)
1493 bytesPerValue = sizeof(GLushort);
1494 else
1495 bytesPerValue = sizeof(GLuint);
1496
1497 ctx->DrawBuffer->DepthBuffer = MALLOC( ctx->DrawBuffer->Width
1498 * ctx->DrawBuffer->Height
1499 * bytesPerValue );
1500
1501 if (!ctx->DrawBuffer->DepthBuffer) {
1502 /* out of memory */
1503 ctx->Depth.Test = GL_FALSE;
1504 ctx->NewState |= NEW_RASTER_OPS;
1505 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
1506 }
1507 }
1508 }
1509
1510
1511
1512
1513 /*
1514 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
1515 * allocate it now.
1516 * This function is only called through Driver.clear_depth_buffer.
1517 */
1518 void
1519 _mesa_clear_depth_buffer( GLcontext *ctx )
1520 {
1521 if (ctx->Visual->DepthBits == 0
1522 || !ctx->DrawBuffer->DepthBuffer
1523 || !ctx->Depth.Mask) {
1524 /* no depth buffer, or writing to it is disabled */
1525 return;
1526 }
1527
1528 /* The loops in this function have been written so the IRIX 5.3
1529 * C compiler can unroll them. Hopefully other compilers can too!
1530 */
1531
1532 if (ctx->Scissor.Enabled) {
1533 /* only clear scissor region */
1534 if (ctx->Visual->DepthBits <= 16) {
1535 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1536 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin + 1;
1537 const GLint width = ctx->DrawBuffer->Width;
1538 GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
1539 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1540 GLint i, j;
1541 for (i = 0; i < rows; i++) {
1542 for (j = 0; j < width; j++) {
1543 dRow[j] = clearValue;
1544 }
1545 dRow += width;
1546 }
1547 }
1548 else {
1549 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1550 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin + 1;
1551 const GLint width = ctx->DrawBuffer->Width;
1552 GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
1553 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1554 GLint i, j;
1555 for (i = 0; i < rows; i++) {
1556 for (j = 0; j < width; j++) {
1557 dRow[j] = clearValue;
1558 }
1559 dRow += width;
1560 }
1561 }
1562 }
1563 else {
1564 /* clear whole buffer */
1565 if (ctx->Visual->DepthBits <= 16) {
1566 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1567 if ((clearValue & 0xff) == (clearValue >> 8)) {
1568 /* lower and upper bytes of clear_value are same, use MEMSET */
1569 MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
1570 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1571 }
1572 else {
1573 GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
1574 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1575 while (n >= 16) {
1576 d[0] = clearValue; d[1] = clearValue;
1577 d[2] = clearValue; d[3] = clearValue;
1578 d[4] = clearValue; d[5] = clearValue;
1579 d[6] = clearValue; d[7] = clearValue;
1580 d[8] = clearValue; d[9] = clearValue;
1581 d[10] = clearValue; d[11] = clearValue;
1582 d[12] = clearValue; d[13] = clearValue;
1583 d[14] = clearValue; d[15] = clearValue;
1584 d += 16;
1585 n -= 16;
1586 }
1587 while (n > 0) {
1588 *d++ = clearValue;
1589 n--;
1590 }
1591 }
1592 }
1593 else {
1594 /* >16 bit depth buffer */
1595 GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
1596 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1597 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1598 while (n >= 16) {
1599 d[0] = clearValue; d[1] = clearValue;
1600 d[2] = clearValue; d[3] = clearValue;
1601 d[4] = clearValue; d[5] = clearValue;
1602 d[6] = clearValue; d[7] = clearValue;
1603 d[8] = clearValue; d[9] = clearValue;
1604 d[10] = clearValue; d[11] = clearValue;
1605 d[12] = clearValue; d[13] = clearValue;
1606 d[14] = clearValue; d[15] = clearValue;
1607 d += 16;
1608 n -= 16;
1609 }
1610 while (n > 0) {
1611 *d++ = clearValue;
1612 n--;
1613 }
1614 }
1615 }
1616 }