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