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