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