Moved software rasterizer functionality to new directory.
[mesa.git] / src / mesa / swrast / s_depth.c
1 /* $Id: s_depth.c,v 1.1 2000/10/31 18:00:04 keithw 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_pb.h"
35
36
37
38
39 /*
40 * Return address of depth buffer value for given window coord.
41 */
42 GLvoid *
43 _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
44 {
45 if (ctx->Visual.DepthBits <= 16)
46 return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
47 else
48 return (GLuint *) ctx->DrawBuffer->DepthBuffer + 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, GLint x, GLint y,
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 gl_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, GLint x, GLint y,
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 gl_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 GLuint
537 _mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
538 const GLdepth z[], GLubyte mask[] )
539 {
540 if (ctx->Driver.ReadDepthSpan) {
541 /* hardware-based depth buffer */
542 GLdepth zbuffer[MAX_WIDTH];
543 GLuint passed;
544 (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
545 passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
546 assert(ctx->Driver.WriteDepthSpan);
547 (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
548 return passed;
549 }
550 else {
551 /* software depth buffer */
552 if (ctx->Visual.DepthBits <= 16) {
553 GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
554 GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
555 return passed;
556 }
557 else {
558 GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
559 GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
560 return passed;
561 }
562 }
563 }
564
565
566
567
568 /*
569 * Do depth testing for an array of fragments using software Z buffer.
570 */
571 static void
572 software_depth_test_pixels16( GLcontext *ctx, GLuint n,
573 const GLint x[], const GLint y[],
574 const GLdepth z[], GLubyte mask[] )
575 {
576 /* switch cases ordered from most frequent to less frequent */
577 switch (ctx->Depth.Func) {
578 case GL_LESS:
579 if (ctx->Depth.Mask) {
580 /* Update Z buffer */
581 GLuint i;
582 for (i=0; i<n; i++) {
583 if (mask[i]) {
584 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
585 if (z[i] < *zptr) {
586 /* pass */
587 *zptr = z[i];
588 }
589 else {
590 /* fail */
591 mask[i] = 0;
592 }
593 }
594 }
595 }
596 else {
597 /* Don't update Z buffer */
598 GLuint i;
599 for (i=0; i<n; i++) {
600 if (mask[i]) {
601 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
602 if (z[i] < *zptr) {
603 /* pass */
604 }
605 else {
606 /* fail */
607 mask[i] = 0;
608 }
609 }
610 }
611 }
612 break;
613 case GL_LEQUAL:
614 if (ctx->Depth.Mask) {
615 /* Update Z buffer */
616 GLuint i;
617 for (i=0; i<n; i++) {
618 if (mask[i]) {
619 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
620 if (z[i] <= *zptr) {
621 /* pass */
622 *zptr = z[i];
623 }
624 else {
625 /* fail */
626 mask[i] = 0;
627 }
628 }
629 }
630 }
631 else {
632 /* Don't update Z buffer */
633 GLuint i;
634 for (i=0; i<n; i++) {
635 if (mask[i]) {
636 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
637 if (z[i] <= *zptr) {
638 /* pass */
639 }
640 else {
641 /* fail */
642 mask[i] = 0;
643 }
644 }
645 }
646 }
647 break;
648 case GL_GEQUAL:
649 if (ctx->Depth.Mask) {
650 /* Update Z buffer */
651 GLuint i;
652 for (i=0; i<n; i++) {
653 if (mask[i]) {
654 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
655 if (z[i] >= *zptr) {
656 /* pass */
657 *zptr = z[i];
658 }
659 else {
660 /* fail */
661 mask[i] = 0;
662 }
663 }
664 }
665 }
666 else {
667 /* Don't update Z buffer */
668 GLuint i;
669 for (i=0; i<n; i++) {
670 if (mask[i]) {
671 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
672 if (z[i] >= *zptr) {
673 /* pass */
674 }
675 else {
676 /* fail */
677 mask[i] = 0;
678 }
679 }
680 }
681 }
682 break;
683 case GL_GREATER:
684 if (ctx->Depth.Mask) {
685 /* Update Z buffer */
686 GLuint i;
687 for (i=0; i<n; i++) {
688 if (mask[i]) {
689 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
690 if (z[i] > *zptr) {
691 /* pass */
692 *zptr = z[i];
693 }
694 else {
695 /* fail */
696 mask[i] = 0;
697 }
698 }
699 }
700 }
701 else {
702 /* Don't update Z buffer */
703 GLuint i;
704 for (i=0; i<n; i++) {
705 if (mask[i]) {
706 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
707 if (z[i] > *zptr) {
708 /* pass */
709 }
710 else {
711 /* fail */
712 mask[i] = 0;
713 }
714 }
715 }
716 }
717 break;
718 case GL_NOTEQUAL:
719 if (ctx->Depth.Mask) {
720 /* Update Z buffer */
721 GLuint i;
722 for (i=0; i<n; i++) {
723 if (mask[i]) {
724 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
725 if (z[i] != *zptr) {
726 /* pass */
727 *zptr = z[i];
728 }
729 else {
730 /* fail */
731 mask[i] = 0;
732 }
733 }
734 }
735 }
736 else {
737 /* Don't update Z buffer */
738 GLuint i;
739 for (i=0; i<n; i++) {
740 if (mask[i]) {
741 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
742 if (z[i] != *zptr) {
743 /* pass */
744 }
745 else {
746 /* fail */
747 mask[i] = 0;
748 }
749 }
750 }
751 }
752 break;
753 case GL_EQUAL:
754 if (ctx->Depth.Mask) {
755 /* Update Z buffer */
756 GLuint i;
757 for (i=0; i<n; i++) {
758 if (mask[i]) {
759 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
760 if (z[i] == *zptr) {
761 /* pass */
762 *zptr = z[i];
763 }
764 else {
765 /* fail */
766 mask[i] = 0;
767 }
768 }
769 }
770 }
771 else {
772 /* Don't update Z buffer */
773 GLuint i;
774 for (i=0; i<n; i++) {
775 if (mask[i]) {
776 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
777 if (z[i] == *zptr) {
778 /* pass */
779 }
780 else {
781 /* fail */
782 mask[i] = 0;
783 }
784 }
785 }
786 }
787 break;
788 case GL_ALWAYS:
789 if (ctx->Depth.Mask) {
790 /* Update Z buffer */
791 GLuint i;
792 for (i=0; i<n; i++) {
793 if (mask[i]) {
794 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
795 *zptr = z[i];
796 }
797 }
798 }
799 else {
800 /* Don't update Z buffer or mask */
801 }
802 break;
803 case GL_NEVER:
804 /* depth test never passes */
805 BZERO(mask, n * sizeof(GLubyte));
806 break;
807 default:
808 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
809 }
810 }
811
812
813
814 /*
815 * Do depth testing for an array of fragments using software Z buffer.
816 */
817 static void
818 software_depth_test_pixels32( GLcontext *ctx, GLuint n,
819 const GLint x[], const GLint y[],
820 const GLdepth z[], GLubyte mask[] )
821 {
822 /* switch cases ordered from most frequent to less frequent */
823 switch (ctx->Depth.Func) {
824 case GL_LESS:
825 if (ctx->Depth.Mask) {
826 /* Update Z buffer */
827 GLuint i;
828 for (i=0; i<n; i++) {
829 if (mask[i]) {
830 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
831 if (z[i] < *zptr) {
832 /* pass */
833 *zptr = z[i];
834 }
835 else {
836 /* fail */
837 mask[i] = 0;
838 }
839 }
840 }
841 }
842 else {
843 /* Don't update Z buffer */
844 GLuint i;
845 for (i=0; i<n; i++) {
846 if (mask[i]) {
847 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
848 if (z[i] < *zptr) {
849 /* pass */
850 }
851 else {
852 /* fail */
853 mask[i] = 0;
854 }
855 }
856 }
857 }
858 break;
859 case GL_LEQUAL:
860 if (ctx->Depth.Mask) {
861 /* Update Z buffer */
862 GLuint i;
863 for (i=0; i<n; i++) {
864 if (mask[i]) {
865 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
866 if (z[i] <= *zptr) {
867 /* pass */
868 *zptr = z[i];
869 }
870 else {
871 /* fail */
872 mask[i] = 0;
873 }
874 }
875 }
876 }
877 else {
878 /* Don't update Z buffer */
879 GLuint i;
880 for (i=0; i<n; i++) {
881 if (mask[i]) {
882 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
883 if (z[i] <= *zptr) {
884 /* pass */
885 }
886 else {
887 /* fail */
888 mask[i] = 0;
889 }
890 }
891 }
892 }
893 break;
894 case GL_GEQUAL:
895 if (ctx->Depth.Mask) {
896 /* Update Z buffer */
897 GLuint i;
898 for (i=0; i<n; i++) {
899 if (mask[i]) {
900 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
901 if (z[i] >= *zptr) {
902 /* pass */
903 *zptr = z[i];
904 }
905 else {
906 /* fail */
907 mask[i] = 0;
908 }
909 }
910 }
911 }
912 else {
913 /* Don't update Z buffer */
914 GLuint i;
915 for (i=0; i<n; i++) {
916 if (mask[i]) {
917 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
918 if (z[i] >= *zptr) {
919 /* pass */
920 }
921 else {
922 /* fail */
923 mask[i] = 0;
924 }
925 }
926 }
927 }
928 break;
929 case GL_GREATER:
930 if (ctx->Depth.Mask) {
931 /* Update Z buffer */
932 GLuint i;
933 for (i=0; i<n; i++) {
934 if (mask[i]) {
935 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
936 if (z[i] > *zptr) {
937 /* pass */
938 *zptr = z[i];
939 }
940 else {
941 /* fail */
942 mask[i] = 0;
943 }
944 }
945 }
946 }
947 else {
948 /* Don't update Z buffer */
949 GLuint i;
950 for (i=0; i<n; i++) {
951 if (mask[i]) {
952 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
953 if (z[i] > *zptr) {
954 /* pass */
955 }
956 else {
957 /* fail */
958 mask[i] = 0;
959 }
960 }
961 }
962 }
963 break;
964 case GL_NOTEQUAL:
965 if (ctx->Depth.Mask) {
966 /* Update Z buffer */
967 GLuint i;
968 for (i=0; i<n; i++) {
969 if (mask[i]) {
970 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
971 if (z[i] != *zptr) {
972 /* pass */
973 *zptr = z[i];
974 }
975 else {
976 /* fail */
977 mask[i] = 0;
978 }
979 }
980 }
981 }
982 else {
983 /* Don't update Z buffer */
984 GLuint i;
985 for (i=0; i<n; i++) {
986 if (mask[i]) {
987 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
988 if (z[i] != *zptr) {
989 /* pass */
990 }
991 else {
992 /* fail */
993 mask[i] = 0;
994 }
995 }
996 }
997 }
998 break;
999 case GL_EQUAL:
1000 if (ctx->Depth.Mask) {
1001 /* Update Z buffer */
1002 GLuint i;
1003 for (i=0; i<n; i++) {
1004 if (mask[i]) {
1005 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1006 if (z[i] == *zptr) {
1007 /* pass */
1008 *zptr = z[i];
1009 }
1010 else {
1011 /* fail */
1012 mask[i] = 0;
1013 }
1014 }
1015 }
1016 }
1017 else {
1018 /* Don't update Z buffer */
1019 GLuint i;
1020 for (i=0; i<n; i++) {
1021 if (mask[i]) {
1022 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1023 if (z[i] == *zptr) {
1024 /* pass */
1025 }
1026 else {
1027 /* fail */
1028 mask[i] = 0;
1029 }
1030 }
1031 }
1032 }
1033 break;
1034 case GL_ALWAYS:
1035 if (ctx->Depth.Mask) {
1036 /* Update Z buffer */
1037 GLuint i;
1038 for (i=0; i<n; i++) {
1039 if (mask[i]) {
1040 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1041 *zptr = z[i];
1042 }
1043 }
1044 }
1045 else {
1046 /* Don't update Z buffer or mask */
1047 }
1048 break;
1049 case GL_NEVER:
1050 /* depth test never passes */
1051 BZERO(mask, n * sizeof(GLubyte));
1052 break;
1053 default:
1054 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
1055 }
1056 }
1057
1058
1059
1060 /*
1061 * Do depth testing for an array of pixels using hardware Z buffer.
1062 * Input/output: zbuffer - array of depth values from Z buffer
1063 * Input: z - array of fragment z values.
1064 */
1065 static void
1066 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
1067 const GLdepth z[], GLubyte mask[] )
1068 {
1069 /* switch cases ordered from most frequent to less frequent */
1070 switch (ctx->Depth.Func) {
1071 case GL_LESS:
1072 if (ctx->Depth.Mask) {
1073 /* Update Z buffer */
1074 GLuint i;
1075 for (i=0; i<n; i++) {
1076 if (mask[i]) {
1077 if (z[i] < zbuffer[i]) {
1078 /* pass */
1079 zbuffer[i] = z[i];
1080 }
1081 else {
1082 /* fail */
1083 mask[i] = 0;
1084 }
1085 }
1086 }
1087 }
1088 else {
1089 /* Don't update Z buffer */
1090 GLuint i;
1091 for (i=0; i<n; i++) {
1092 if (mask[i]) {
1093 if (z[i] < zbuffer[i]) {
1094 /* pass */
1095 }
1096 else {
1097 /* fail */
1098 mask[i] = 0;
1099 }
1100 }
1101 }
1102 }
1103 break;
1104 case GL_LEQUAL:
1105 if (ctx->Depth.Mask) {
1106 /* Update Z buffer */
1107 GLuint i;
1108 for (i=0; i<n; i++) {
1109 if (mask[i]) {
1110 if (z[i] <= zbuffer[i]) {
1111 /* pass */
1112 zbuffer[i] = z[i];
1113 }
1114 else {
1115 /* fail */
1116 mask[i] = 0;
1117 }
1118 }
1119 }
1120 }
1121 else {
1122 /* Don't update Z buffer */
1123 GLuint i;
1124 for (i=0; i<n; i++) {
1125 if (mask[i]) {
1126 if (z[i] <= zbuffer[i]) {
1127 /* pass */
1128 }
1129 else {
1130 /* fail */
1131 mask[i] = 0;
1132 }
1133 }
1134 }
1135 }
1136 break;
1137 case GL_GEQUAL:
1138 if (ctx->Depth.Mask) {
1139 /* Update Z buffer */
1140 GLuint i;
1141 for (i=0; i<n; i++) {
1142 if (mask[i]) {
1143 if (z[i] >= zbuffer[i]) {
1144 /* pass */
1145 zbuffer[i] = z[i];
1146 }
1147 else {
1148 /* fail */
1149 mask[i] = 0;
1150 }
1151 }
1152 }
1153 }
1154 else {
1155 /* Don't update Z buffer */
1156 GLuint i;
1157 for (i=0; i<n; i++) {
1158 if (mask[i]) {
1159 if (z[i] >= zbuffer[i]) {
1160 /* pass */
1161 }
1162 else {
1163 /* fail */
1164 mask[i] = 0;
1165 }
1166 }
1167 }
1168 }
1169 break;
1170 case GL_GREATER:
1171 if (ctx->Depth.Mask) {
1172 /* Update Z buffer */
1173 GLuint i;
1174 for (i=0; i<n; i++) {
1175 if (mask[i]) {
1176 if (z[i] > zbuffer[i]) {
1177 /* pass */
1178 zbuffer[i] = z[i];
1179 }
1180 else {
1181 /* fail */
1182 mask[i] = 0;
1183 }
1184 }
1185 }
1186 }
1187 else {
1188 /* Don't update Z buffer */
1189 GLuint i;
1190 for (i=0; i<n; i++) {
1191 if (mask[i]) {
1192 if (z[i] > zbuffer[i]) {
1193 /* pass */
1194 }
1195 else {
1196 /* fail */
1197 mask[i] = 0;
1198 }
1199 }
1200 }
1201 }
1202 break;
1203 case GL_NOTEQUAL:
1204 if (ctx->Depth.Mask) {
1205 /* Update Z buffer */
1206 GLuint i;
1207 for (i=0; i<n; i++) {
1208 if (mask[i]) {
1209 if (z[i] != zbuffer[i]) {
1210 /* pass */
1211 zbuffer[i] = z[i];
1212 }
1213 else {
1214 /* fail */
1215 mask[i] = 0;
1216 }
1217 }
1218 }
1219 }
1220 else {
1221 /* Don't update Z buffer */
1222 GLuint i;
1223 for (i=0; i<n; i++) {
1224 if (mask[i]) {
1225 if (z[i] != zbuffer[i]) {
1226 /* pass */
1227 }
1228 else {
1229 /* fail */
1230 mask[i] = 0;
1231 }
1232 }
1233 }
1234 }
1235 break;
1236 case GL_EQUAL:
1237 if (ctx->Depth.Mask) {
1238 /* Update Z buffer */
1239 GLuint i;
1240 for (i=0; i<n; i++) {
1241 if (mask[i]) {
1242 if (z[i] == zbuffer[i]) {
1243 /* pass */
1244 zbuffer[i] = z[i];
1245 }
1246 else {
1247 /* fail */
1248 mask[i] = 0;
1249 }
1250 }
1251 }
1252 }
1253 else {
1254 /* Don't update Z buffer */
1255 GLuint i;
1256 for (i=0; i<n; i++) {
1257 if (mask[i]) {
1258 if (z[i] == zbuffer[i]) {
1259 /* pass */
1260 }
1261 else {
1262 /* fail */
1263 mask[i] = 0;
1264 }
1265 }
1266 }
1267 }
1268 break;
1269 case GL_ALWAYS:
1270 if (ctx->Depth.Mask) {
1271 /* Update Z buffer */
1272 GLuint i;
1273 for (i=0; i<n; i++) {
1274 if (mask[i]) {
1275 zbuffer[i] = z[i];
1276 }
1277 }
1278 }
1279 else {
1280 /* Don't update Z buffer or mask */
1281 }
1282 break;
1283 case GL_NEVER:
1284 /* depth test never passes */
1285 BZERO(mask, n * sizeof(GLubyte));
1286 break;
1287 default:
1288 gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
1289 }
1290 }
1291
1292
1293
1294 void
1295 _mesa_depth_test_pixels( GLcontext *ctx,
1296 GLuint n, const GLint x[], const GLint y[],
1297 const GLdepth z[], GLubyte mask[] )
1298 {
1299 if (ctx->Driver.ReadDepthPixels) {
1300 /* read depth values from hardware Z buffer */
1301 GLdepth zbuffer[PB_SIZE];
1302 (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
1303
1304 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
1305
1306 /* update hardware Z buffer with new values */
1307 assert(ctx->Driver.WriteDepthPixels);
1308 (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
1309 }
1310 else {
1311 /* software depth testing */
1312 if (ctx->Visual.DepthBits <= 16)
1313 software_depth_test_pixels16(ctx, n, x, y, z, mask);
1314 else
1315 software_depth_test_pixels32(ctx, n, x, y, z, mask);
1316 }
1317 }
1318
1319
1320
1321
1322
1323 /**********************************************************************/
1324 /***** Read Depth Buffer *****/
1325 /**********************************************************************/
1326
1327
1328 /*
1329 * Read a span of depth values from the depth buffer.
1330 * This function does clipping before calling the device driver function.
1331 */
1332 void
1333 _mesa_read_depth_span( GLcontext *ctx,
1334 GLint n, GLint x, GLint y, GLdepth depth[] )
1335 {
1336 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1337 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1338 /* span is completely outside framebuffer */
1339 GLint i;
1340 for (i = 0; i < n; i++)
1341 depth[i] = 0;
1342 return;
1343 }
1344
1345 if (x < 0) {
1346 GLint dx = -x;
1347 GLint i;
1348 for (i = 0; i < dx; i++)
1349 depth[i] = 0;
1350 x = 0;
1351 n -= dx;
1352 depth += dx;
1353 }
1354 if (x + n > ctx->DrawBuffer->Width) {
1355 GLint dx = x + n - ctx->DrawBuffer->Width;
1356 GLint i;
1357 for (i = 0; i < dx; i++)
1358 depth[n - i - 1] = 0;
1359 n -= dx;
1360 }
1361 if (n <= 0) {
1362 return;
1363 }
1364
1365 if (ctx->DrawBuffer->DepthBuffer) {
1366 /* read from software depth buffer */
1367 if (ctx->Visual.DepthBits <= 16) {
1368 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1369 GLuint i;
1370 for (i = 0; i < n; i++) {
1371 depth[i] = zptr[i];
1372 }
1373 }
1374 else {
1375 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1376 GLuint i;
1377 for (i = 0; i < n; i++) {
1378 depth[i] = zptr[i];
1379 }
1380 }
1381 }
1382 else if (ctx->Driver.ReadDepthSpan) {
1383 /* read from hardware depth buffer */
1384 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
1385 }
1386 else {
1387 /* no depth buffer */
1388 BZERO(depth, n * sizeof(GLfloat));
1389 }
1390
1391 }
1392
1393
1394
1395
1396 /*
1397 * Return a span of depth values from the depth buffer as floats in [0,1].
1398 * This is used for both hardware and software depth buffers.
1399 * Input: n - how many pixels
1400 * x,y - location of first pixel
1401 * Output: depth - the array of depth values
1402 */
1403 void
1404 _mesa_read_depth_span_float( GLcontext *ctx,
1405 GLint n, GLint x, GLint y, GLfloat depth[] )
1406 {
1407 const GLfloat scale = 1.0F / ctx->Visual.DepthMaxF;
1408
1409 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1410 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1411 /* span is completely outside framebuffer */
1412 GLint i;
1413 for (i = 0; i < n; i++)
1414 depth[i] = 0.0F;
1415 return;
1416 }
1417
1418 if (x < 0) {
1419 GLint dx = -x;
1420 GLint i;
1421 for (i = 0; i < dx; i++)
1422 depth[i] = 0.0F;
1423 n -= dx;
1424 x = 0;
1425 }
1426 if (x + n > ctx->DrawBuffer->Width) {
1427 GLint dx = x + n - ctx->DrawBuffer->Width;
1428 GLint i;
1429 for (i = 0; i < dx; i++)
1430 depth[n - i - 1] = 0.0F;
1431 n -= dx;
1432 }
1433 if (n <= 0) {
1434 return;
1435 }
1436
1437 if (ctx->DrawBuffer->DepthBuffer) {
1438 /* read from software depth buffer */
1439 if (ctx->Visual.DepthBits <= 16) {
1440 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1441 GLuint i;
1442 for (i = 0; i < n; i++) {
1443 depth[i] = (GLfloat) zptr[i] * scale;
1444 }
1445 }
1446 else {
1447 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1448 GLuint i;
1449 for (i = 0; i < n; i++) {
1450 depth[i] = (GLfloat) zptr[i] * scale;
1451 }
1452 }
1453 }
1454 else if (ctx->Driver.ReadDepthSpan) {
1455 /* read from hardware depth buffer */
1456 GLdepth d[MAX_WIDTH];
1457 GLuint i;
1458 assert(n <= MAX_WIDTH);
1459 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
1460 for (i = 0; i < n; i++) {
1461 depth[i] = d[i] * scale;
1462 }
1463 }
1464 else {
1465 /* no depth buffer */
1466 BZERO(depth, n * sizeof(GLfloat));
1467 }
1468 }
1469
1470
1471
1472 /**********************************************************************/
1473 /***** Allocate and Clear Depth Buffer *****/
1474 /**********************************************************************/
1475
1476
1477
1478 /*
1479 * Allocate a new depth buffer. If there's already a depth buffer allocated
1480 * it will be free()'d. The new depth buffer will be uniniitalized.
1481 * This function is only called through Driver.alloc_depth_buffer.
1482 */
1483 void
1484 _mesa_alloc_depth_buffer( GLcontext *ctx )
1485 {
1486 /* deallocate current depth buffer if present */
1487 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1488 GLint bytesPerValue;
1489
1490 if (ctx->DrawBuffer->DepthBuffer) {
1491 FREE(ctx->DrawBuffer->DepthBuffer);
1492 ctx->DrawBuffer->DepthBuffer = NULL;
1493 }
1494
1495 /* allocate new depth buffer, but don't initialize it */
1496 if (ctx->Visual.DepthBits <= 16)
1497 bytesPerValue = sizeof(GLushort);
1498 else
1499 bytesPerValue = sizeof(GLuint);
1500
1501 ctx->DrawBuffer->DepthBuffer = MALLOC( ctx->DrawBuffer->Width
1502 * ctx->DrawBuffer->Height
1503 * bytesPerValue );
1504
1505 if (!ctx->DrawBuffer->DepthBuffer) {
1506 /* out of memory */
1507 ctx->Depth.Test = GL_FALSE;
1508 ctx->NewState |= _NEW_DEPTH;
1509 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
1510 }
1511 }
1512 }
1513
1514
1515
1516
1517 /*
1518 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
1519 * allocate it now.
1520 * This function is only called through Driver.clear_depth_buffer.
1521 */
1522 void
1523 _mesa_clear_depth_buffer( GLcontext *ctx )
1524 {
1525 if (ctx->Visual.DepthBits == 0
1526 || !ctx->DrawBuffer->DepthBuffer
1527 || !ctx->Depth.Mask) {
1528 /* no depth buffer, or writing to it is disabled */
1529 return;
1530 }
1531
1532 /* The loops in this function have been written so the IRIX 5.3
1533 * C compiler can unroll them. Hopefully other compilers can too!
1534 */
1535
1536 if (ctx->Scissor.Enabled) {
1537 /* only clear scissor region */
1538 if (ctx->Visual.DepthBits <= 16) {
1539 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1540 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
1541 const GLint width = ctx->DrawBuffer->Width;
1542 GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
1543 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1544 GLint i, j;
1545 for (i = 0; i < rows; i++) {
1546 for (j = 0; j < width; j++) {
1547 dRow[j] = clearValue;
1548 }
1549 dRow += width;
1550 }
1551 }
1552 else {
1553 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1554 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
1555 const GLint width = ctx->DrawBuffer->Width;
1556 GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
1557 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1558 GLint i, j;
1559 for (i = 0; i < rows; i++) {
1560 for (j = 0; j < width; j++) {
1561 dRow[j] = clearValue;
1562 }
1563 dRow += width;
1564 }
1565 }
1566 }
1567 else {
1568 /* clear whole buffer */
1569 if (ctx->Visual.DepthBits <= 16) {
1570 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1571 if ((clearValue & 0xff) == (clearValue >> 8)) {
1572 if (clearValue == 0) {
1573 BZERO(ctx->DrawBuffer->DepthBuffer,
1574 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
1575 }
1576 else {
1577 /* lower and upper bytes of clear_value are same, use MEMSET */
1578 MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
1579 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1580 }
1581 }
1582 else {
1583 GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
1584 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1585 while (n >= 16) {
1586 d[0] = clearValue; d[1] = clearValue;
1587 d[2] = clearValue; d[3] = clearValue;
1588 d[4] = clearValue; d[5] = clearValue;
1589 d[6] = clearValue; d[7] = clearValue;
1590 d[8] = clearValue; d[9] = clearValue;
1591 d[10] = clearValue; d[11] = clearValue;
1592 d[12] = clearValue; d[13] = clearValue;
1593 d[14] = clearValue; d[15] = clearValue;
1594 d += 16;
1595 n -= 16;
1596 }
1597 while (n > 0) {
1598 *d++ = clearValue;
1599 n--;
1600 }
1601 }
1602 }
1603 else {
1604 /* >16 bit depth buffer */
1605 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1606 if (clearValue == 0) {
1607 BZERO(ctx->DrawBuffer->DepthBuffer,
1608 ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
1609 }
1610 else {
1611 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1612 GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
1613 while (n >= 16) {
1614 d[0] = clearValue; d[1] = clearValue;
1615 d[2] = clearValue; d[3] = clearValue;
1616 d[4] = clearValue; d[5] = clearValue;
1617 d[6] = clearValue; d[7] = clearValue;
1618 d[8] = clearValue; d[9] = clearValue;
1619 d[10] = clearValue; d[11] = clearValue;
1620 d[12] = clearValue; d[13] = clearValue;
1621 d[14] = clearValue; d[15] = clearValue;
1622 d += 16;
1623 n -= 16;
1624 }
1625 while (n > 0) {
1626 *d++ = clearValue;
1627 n--;
1628 }
1629 }
1630 }
1631 }
1632 }