mesa: Prefix main includes with dir to avoid conflicts.
[mesa.git] / src / mesa / swrast / s_depth.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.1
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include "main/glheader.h"
27 #include "main/context.h"
28 #include "main/macros.h"
29 #include "main/imports.h"
30 #include "fbobject.h"
31
32 #include "s_depth.h"
33 #include "s_context.h"
34 #include "s_span.h"
35
36
37 /**
38 * Do depth test for a horizontal span of fragments.
39 * Input: zbuffer - array of z values in the zbuffer
40 * z - array of fragment z values
41 * Return: number of fragments which pass the test.
42 */
43 static GLuint
44 depth_test_span16( GLcontext *ctx, GLuint n,
45 GLushort zbuffer[], const GLuint z[], GLubyte mask[] )
46 {
47 GLuint passed = 0;
48
49 /* switch cases ordered from most frequent to less frequent */
50 switch (ctx->Depth.Func) {
51 case GL_LESS:
52 if (ctx->Depth.Mask) {
53 /* Update Z buffer */
54 GLuint i;
55 for (i=0; i<n; i++) {
56 if (mask[i]) {
57 if (z[i] < zbuffer[i]) {
58 /* pass */
59 zbuffer[i] = z[i];
60 passed++;
61 }
62 else {
63 /* fail */
64 mask[i] = 0;
65 }
66 }
67 }
68 }
69 else {
70 /* Don't update Z buffer */
71 GLuint i;
72 for (i=0; i<n; i++) {
73 if (mask[i]) {
74 if (z[i] < zbuffer[i]) {
75 /* pass */
76 passed++;
77 }
78 else {
79 mask[i] = 0;
80 }
81 }
82 }
83 }
84 break;
85 case GL_LEQUAL:
86 if (ctx->Depth.Mask) {
87 /* Update Z buffer */
88 GLuint i;
89 for (i=0;i<n;i++) {
90 if (mask[i]) {
91 if (z[i] <= zbuffer[i]) {
92 zbuffer[i] = z[i];
93 passed++;
94 }
95 else {
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_GEQUAL:
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_GREATER:
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_NOTEQUAL:
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_EQUAL:
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_ALWAYS:
246 if (ctx->Depth.Mask) {
247 /* Update Z buffer */
248 GLuint i;
249 for (i=0;i<n;i++) {
250 if (mask[i]) {
251 zbuffer[i] = z[i];
252 passed++;
253 }
254 }
255 }
256 else {
257 /* Don't update Z buffer or mask */
258 passed = n;
259 }
260 break;
261 case GL_NEVER:
262 _mesa_bzero(mask, n * sizeof(GLubyte));
263 break;
264 default:
265 _mesa_problem(ctx, "Bad depth func in depth_test_span16");
266 }
267
268 return passed;
269 }
270
271
272 static GLuint
273 depth_test_span32( GLcontext *ctx, GLuint n,
274 GLuint zbuffer[], const GLuint z[], GLubyte mask[] )
275 {
276 GLuint passed = 0;
277
278 /* switch cases ordered from most frequent to less frequent */
279 switch (ctx->Depth.Func) {
280 case GL_LESS:
281 if (ctx->Depth.Mask) {
282 /* Update Z buffer */
283 GLuint i;
284 for (i=0; i<n; i++) {
285 if (mask[i]) {
286 if (z[i] < zbuffer[i]) {
287 /* pass */
288 zbuffer[i] = z[i];
289 passed++;
290 }
291 else {
292 /* fail */
293 mask[i] = 0;
294 }
295 }
296 }
297 }
298 else {
299 /* Don't update Z buffer */
300 GLuint i;
301 for (i=0; i<n; i++) {
302 if (mask[i]) {
303 if (z[i] < zbuffer[i]) {
304 /* pass */
305 passed++;
306 }
307 else {
308 mask[i] = 0;
309 }
310 }
311 }
312 }
313 break;
314 case GL_LEQUAL:
315 if (ctx->Depth.Mask) {
316 /* Update Z buffer */
317 GLuint i;
318 for (i=0;i<n;i++) {
319 if (mask[i]) {
320 if (z[i] <= zbuffer[i]) {
321 zbuffer[i] = z[i];
322 passed++;
323 }
324 else {
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_GEQUAL:
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_GREATER:
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_NOTEQUAL:
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_EQUAL:
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_ALWAYS:
475 if (ctx->Depth.Mask) {
476 /* Update Z buffer */
477 GLuint i;
478 for (i=0;i<n;i++) {
479 if (mask[i]) {
480 zbuffer[i] = z[i];
481 passed++;
482 }
483 }
484 }
485 else {
486 /* Don't update Z buffer or mask */
487 passed = n;
488 }
489 break;
490 case GL_NEVER:
491 _mesa_bzero(mask, n * sizeof(GLubyte));
492 break;
493 default:
494 _mesa_problem(ctx, "Bad depth func in depth_test_span32");
495 }
496
497 return passed;
498 }
499
500
501
502 /*
503 * Apply depth test to span of fragments.
504 */
505 static GLuint
506 depth_test_span( GLcontext *ctx, SWspan *span)
507 {
508 struct gl_framebuffer *fb = ctx->DrawBuffer;
509 struct gl_renderbuffer *rb = fb->_DepthBuffer;
510 const GLint x = span->x;
511 const GLint y = span->y;
512 const GLuint count = span->end;
513 const GLuint *zValues = span->array->z;
514 GLubyte *mask = span->array->mask;
515 GLuint passed;
516
517 ASSERT((span->arrayMask & SPAN_XY) == 0);
518 ASSERT(span->arrayMask & SPAN_Z);
519
520 if (rb->GetPointer(ctx, rb, 0, 0)) {
521 /* Directly access buffer */
522 if (rb->DataType == GL_UNSIGNED_SHORT) {
523 GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y);
524 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
525 }
526 else {
527 GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y);
528 ASSERT(rb->DataType == GL_UNSIGNED_INT);
529 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
530 }
531 }
532 else {
533 /* read depth values from buffer, test, write back */
534 if (rb->DataType == GL_UNSIGNED_SHORT) {
535 GLushort zbuffer[MAX_WIDTH];
536 rb->GetRow(ctx, rb, count, x, y, zbuffer);
537 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask );
538 rb->PutRow(ctx, rb, count, x, y, zbuffer, NULL);
539 }
540 else {
541 GLuint zbuffer[MAX_WIDTH];
542 ASSERT(rb->DataType == GL_UNSIGNED_INT);
543 rb->GetRow(ctx, rb, count, x, y, zbuffer);
544 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask );
545 rb->PutRow(ctx, rb, count, x, y, zbuffer, NULL);
546 }
547 }
548
549 if (passed < count) {
550 span->writeAll = GL_FALSE;
551 }
552 return passed;
553 }
554
555
556
557 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
558
559
560 /*
561 * Do depth testing for an array of fragments at assorted locations.
562 */
563 static void
564 direct_depth_test_pixels16(GLcontext *ctx, GLushort *zStart, GLuint stride,
565 GLuint n, const GLint x[], const GLint y[],
566 const GLuint z[], GLubyte mask[] )
567 {
568 /* switch cases ordered from most frequent to less frequent */
569 switch (ctx->Depth.Func) {
570 case GL_LESS:
571 if (ctx->Depth.Mask) {
572 /* Update Z buffer */
573 GLuint i;
574 for (i=0; i<n; i++) {
575 if (mask[i]) {
576 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
577 if (z[i] < *zptr) {
578 /* pass */
579 *zptr = z[i];
580 }
581 else {
582 /* fail */
583 mask[i] = 0;
584 }
585 }
586 }
587 }
588 else {
589 /* Don't update Z buffer */
590 GLuint i;
591 for (i=0; i<n; i++) {
592 if (mask[i]) {
593 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
594 if (z[i] < *zptr) {
595 /* pass */
596 }
597 else {
598 /* fail */
599 mask[i] = 0;
600 }
601 }
602 }
603 }
604 break;
605 case GL_LEQUAL:
606 if (ctx->Depth.Mask) {
607 /* Update Z buffer */
608 GLuint i;
609 for (i=0; i<n; i++) {
610 if (mask[i]) {
611 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
612 if (z[i] <= *zptr) {
613 /* pass */
614 *zptr = z[i];
615 }
616 else {
617 /* fail */
618 mask[i] = 0;
619 }
620 }
621 }
622 }
623 else {
624 /* Don't update Z buffer */
625 GLuint i;
626 for (i=0; i<n; i++) {
627 if (mask[i]) {
628 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
629 if (z[i] <= *zptr) {
630 /* pass */
631 }
632 else {
633 /* fail */
634 mask[i] = 0;
635 }
636 }
637 }
638 }
639 break;
640 case GL_GEQUAL:
641 if (ctx->Depth.Mask) {
642 /* Update Z buffer */
643 GLuint i;
644 for (i=0; i<n; i++) {
645 if (mask[i]) {
646 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
647 if (z[i] >= *zptr) {
648 /* pass */
649 *zptr = z[i];
650 }
651 else {
652 /* fail */
653 mask[i] = 0;
654 }
655 }
656 }
657 }
658 else {
659 /* Don't update Z buffer */
660 GLuint i;
661 for (i=0; i<n; i++) {
662 if (mask[i]) {
663 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
664 if (z[i] >= *zptr) {
665 /* pass */
666 }
667 else {
668 /* fail */
669 mask[i] = 0;
670 }
671 }
672 }
673 }
674 break;
675 case GL_GREATER:
676 if (ctx->Depth.Mask) {
677 /* Update Z buffer */
678 GLuint i;
679 for (i=0; i<n; i++) {
680 if (mask[i]) {
681 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
682 if (z[i] > *zptr) {
683 /* pass */
684 *zptr = z[i];
685 }
686 else {
687 /* fail */
688 mask[i] = 0;
689 }
690 }
691 }
692 }
693 else {
694 /* Don't update Z buffer */
695 GLuint i;
696 for (i=0; i<n; i++) {
697 if (mask[i]) {
698 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
699 if (z[i] > *zptr) {
700 /* pass */
701 }
702 else {
703 /* fail */
704 mask[i] = 0;
705 }
706 }
707 }
708 }
709 break;
710 case GL_NOTEQUAL:
711 if (ctx->Depth.Mask) {
712 /* Update Z buffer */
713 GLuint i;
714 for (i=0; i<n; i++) {
715 if (mask[i]) {
716 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
717 if (z[i] != *zptr) {
718 /* pass */
719 *zptr = z[i];
720 }
721 else {
722 /* fail */
723 mask[i] = 0;
724 }
725 }
726 }
727 }
728 else {
729 /* Don't update Z buffer */
730 GLuint i;
731 for (i=0; i<n; i++) {
732 if (mask[i]) {
733 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
734 if (z[i] != *zptr) {
735 /* pass */
736 }
737 else {
738 /* fail */
739 mask[i] = 0;
740 }
741 }
742 }
743 }
744 break;
745 case GL_EQUAL:
746 if (ctx->Depth.Mask) {
747 /* Update Z buffer */
748 GLuint i;
749 for (i=0; i<n; i++) {
750 if (mask[i]) {
751 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
752 if (z[i] == *zptr) {
753 /* pass */
754 *zptr = z[i];
755 }
756 else {
757 /* fail */
758 mask[i] = 0;
759 }
760 }
761 }
762 }
763 else {
764 /* Don't update Z buffer */
765 GLuint i;
766 for (i=0; i<n; i++) {
767 if (mask[i]) {
768 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
769 if (z[i] == *zptr) {
770 /* pass */
771 }
772 else {
773 /* fail */
774 mask[i] = 0;
775 }
776 }
777 }
778 }
779 break;
780 case GL_ALWAYS:
781 if (ctx->Depth.Mask) {
782 /* Update Z buffer */
783 GLuint i;
784 for (i=0; i<n; i++) {
785 if (mask[i]) {
786 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
787 *zptr = z[i];
788 }
789 }
790 }
791 else {
792 /* Don't update Z buffer or mask */
793 }
794 break;
795 case GL_NEVER:
796 /* depth test never passes */
797 _mesa_bzero(mask, n * sizeof(GLubyte));
798 break;
799 default:
800 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
801 }
802 }
803
804
805
806 /*
807 * Do depth testing for an array of fragments with direct access to zbuffer.
808 */
809 static void
810 direct_depth_test_pixels32(GLcontext *ctx, GLuint *zStart, GLuint stride,
811 GLuint n, const GLint x[], const GLint y[],
812 const GLuint z[], GLubyte mask[] )
813 {
814 /* switch cases ordered from most frequent to less frequent */
815 switch (ctx->Depth.Func) {
816 case GL_LESS:
817 if (ctx->Depth.Mask) {
818 /* Update Z buffer */
819 GLuint i;
820 for (i=0; i<n; i++) {
821 if (mask[i]) {
822 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
823 if (z[i] < *zptr) {
824 /* pass */
825 *zptr = z[i];
826 }
827 else {
828 /* fail */
829 mask[i] = 0;
830 }
831 }
832 }
833 }
834 else {
835 /* Don't update Z buffer */
836 GLuint i;
837 for (i=0; i<n; i++) {
838 if (mask[i]) {
839 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
840 if (z[i] < *zptr) {
841 /* pass */
842 }
843 else {
844 /* fail */
845 mask[i] = 0;
846 }
847 }
848 }
849 }
850 break;
851 case GL_LEQUAL:
852 if (ctx->Depth.Mask) {
853 /* Update Z buffer */
854 GLuint i;
855 for (i=0; i<n; i++) {
856 if (mask[i]) {
857 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
858 if (z[i] <= *zptr) {
859 /* pass */
860 *zptr = z[i];
861 }
862 else {
863 /* fail */
864 mask[i] = 0;
865 }
866 }
867 }
868 }
869 else {
870 /* Don't update Z buffer */
871 GLuint i;
872 for (i=0; i<n; i++) {
873 if (mask[i]) {
874 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
875 if (z[i] <= *zptr) {
876 /* pass */
877 }
878 else {
879 /* fail */
880 mask[i] = 0;
881 }
882 }
883 }
884 }
885 break;
886 case GL_GEQUAL:
887 if (ctx->Depth.Mask) {
888 /* Update Z buffer */
889 GLuint i;
890 for (i=0; i<n; i++) {
891 if (mask[i]) {
892 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
893 if (z[i] >= *zptr) {
894 /* pass */
895 *zptr = z[i];
896 }
897 else {
898 /* fail */
899 mask[i] = 0;
900 }
901 }
902 }
903 }
904 else {
905 /* Don't update Z buffer */
906 GLuint i;
907 for (i=0; i<n; i++) {
908 if (mask[i]) {
909 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
910 if (z[i] >= *zptr) {
911 /* pass */
912 }
913 else {
914 /* fail */
915 mask[i] = 0;
916 }
917 }
918 }
919 }
920 break;
921 case GL_GREATER:
922 if (ctx->Depth.Mask) {
923 /* Update Z buffer */
924 GLuint i;
925 for (i=0; i<n; i++) {
926 if (mask[i]) {
927 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
928 if (z[i] > *zptr) {
929 /* pass */
930 *zptr = z[i];
931 }
932 else {
933 /* fail */
934 mask[i] = 0;
935 }
936 }
937 }
938 }
939 else {
940 /* Don't update Z buffer */
941 GLuint i;
942 for (i=0; i<n; i++) {
943 if (mask[i]) {
944 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
945 if (z[i] > *zptr) {
946 /* pass */
947 }
948 else {
949 /* fail */
950 mask[i] = 0;
951 }
952 }
953 }
954 }
955 break;
956 case GL_NOTEQUAL:
957 if (ctx->Depth.Mask) {
958 /* Update Z buffer */
959 GLuint i;
960 for (i=0; i<n; i++) {
961 if (mask[i]) {
962 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
963 if (z[i] != *zptr) {
964 /* pass */
965 *zptr = z[i];
966 }
967 else {
968 /* fail */
969 mask[i] = 0;
970 }
971 }
972 }
973 }
974 else {
975 /* Don't update Z buffer */
976 GLuint i;
977 for (i=0; i<n; i++) {
978 if (mask[i]) {
979 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
980 if (z[i] != *zptr) {
981 /* pass */
982 }
983 else {
984 /* fail */
985 mask[i] = 0;
986 }
987 }
988 }
989 }
990 break;
991 case GL_EQUAL:
992 if (ctx->Depth.Mask) {
993 /* Update Z buffer */
994 GLuint i;
995 for (i=0; i<n; i++) {
996 if (mask[i]) {
997 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
998 if (z[i] == *zptr) {
999 /* pass */
1000 *zptr = z[i];
1001 }
1002 else {
1003 /* fail */
1004 mask[i] = 0;
1005 }
1006 }
1007 }
1008 }
1009 else {
1010 /* Don't update Z buffer */
1011 GLuint i;
1012 for (i=0; i<n; i++) {
1013 if (mask[i]) {
1014 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1015 if (z[i] == *zptr) {
1016 /* pass */
1017 }
1018 else {
1019 /* fail */
1020 mask[i] = 0;
1021 }
1022 }
1023 }
1024 }
1025 break;
1026 case GL_ALWAYS:
1027 if (ctx->Depth.Mask) {
1028 /* Update Z buffer */
1029 GLuint i;
1030 for (i=0; i<n; i++) {
1031 if (mask[i]) {
1032 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1033 *zptr = z[i];
1034 }
1035 }
1036 }
1037 else {
1038 /* Don't update Z buffer or mask */
1039 }
1040 break;
1041 case GL_NEVER:
1042 /* depth test never passes */
1043 _mesa_bzero(mask, n * sizeof(GLubyte));
1044 break;
1045 default:
1046 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
1047 }
1048 }
1049
1050
1051
1052
1053 static GLuint
1054 depth_test_pixels( GLcontext *ctx, SWspan *span )
1055 {
1056 struct gl_framebuffer *fb = ctx->DrawBuffer;
1057 struct gl_renderbuffer *rb = fb->_DepthBuffer;
1058 const GLuint count = span->end;
1059 const GLint *x = span->array->x;
1060 const GLint *y = span->array->y;
1061 const GLuint *z = span->array->z;
1062 GLubyte *mask = span->array->mask;
1063
1064 if (rb->GetPointer(ctx, rb, 0, 0)) {
1065 /* Directly access values */
1066 if (rb->DataType == GL_UNSIGNED_SHORT) {
1067 GLushort *zStart = (GLushort *) rb->Data;
1068 GLuint stride = rb->Width;
1069 direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask);
1070 }
1071 else {
1072 GLuint *zStart = (GLuint *) rb->Data;
1073 GLuint stride = rb->Width;
1074 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1075 direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask);
1076 }
1077 }
1078 else {
1079 /* read depth values from buffer, test, write back */
1080 if (rb->DataType == GL_UNSIGNED_SHORT) {
1081 GLushort zbuffer[MAX_WIDTH];
1082 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort));
1083 depth_test_span16(ctx, count, zbuffer, z, mask );
1084 rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
1085 }
1086 else {
1087 GLuint zbuffer[MAX_WIDTH];
1088 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1089 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint));
1090 depth_test_span32(ctx, count, zbuffer, z, mask );
1091 rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
1092 }
1093 }
1094
1095 return count; /* not really correct, but OK */
1096 }
1097
1098
1099 /**
1100 * Apply depth (Z) buffer testing to the span.
1101 * \return approx number of pixels that passed (only zero is reliable)
1102 */
1103 GLuint
1104 _swrast_depth_test_span( GLcontext *ctx, SWspan *span)
1105 {
1106 if (span->arrayMask & SPAN_XY)
1107 return depth_test_pixels(ctx, span);
1108 else
1109 return depth_test_span(ctx, span);
1110 }
1111
1112
1113 /**
1114 * GL_EXT_depth_bounds_test extension.
1115 * Discard fragments depending on whether the corresponding Z-buffer
1116 * values are outside the depth bounds test range.
1117 * Note: we test the Z buffer values, not the fragment Z values!
1118 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1119 */
1120 GLboolean
1121 _swrast_depth_bounds_test( GLcontext *ctx, SWspan *span )
1122 {
1123 struct gl_framebuffer *fb = ctx->DrawBuffer;
1124 struct gl_renderbuffer *rb = fb->_DepthBuffer;
1125 GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
1126 GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
1127 GLubyte *mask = span->array->mask;
1128 const GLuint count = span->end;
1129 GLuint i;
1130 GLboolean anyPass = GL_FALSE;
1131
1132 if (rb->DataType == GL_UNSIGNED_SHORT) {
1133 /* get 16-bit values */
1134 GLushort zbuffer16[MAX_WIDTH], *zbuffer;
1135 if (span->arrayMask & SPAN_XY) {
1136 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
1137 zbuffer16, sizeof(GLushort));
1138 zbuffer = zbuffer16;
1139 }
1140 else {
1141 zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y);
1142 if (!zbuffer) {
1143 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16);
1144 zbuffer = zbuffer16;
1145 }
1146 }
1147 assert(zbuffer);
1148
1149 /* Now do the tests */
1150 for (i = 0; i < count; i++) {
1151 if (mask[i]) {
1152 if (zbuffer[i] < zMin || zbuffer[i] > zMax)
1153 mask[i] = GL_FALSE;
1154 else
1155 anyPass = GL_TRUE;
1156 }
1157 }
1158 }
1159 else {
1160 /* get 32-bit values */
1161 GLuint zbuffer32[MAX_WIDTH], *zbuffer;
1162 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1163 if (span->arrayMask & SPAN_XY) {
1164 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
1165 zbuffer32, sizeof(GLuint));
1166 zbuffer = zbuffer32;
1167 }
1168 else {
1169 zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y);
1170 if (!zbuffer) {
1171 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
1172 zbuffer = zbuffer32;
1173 }
1174 }
1175 assert(zbuffer);
1176
1177 /* Now do the tests */
1178 for (i = 0; i < count; i++) {
1179 if (mask[i]) {
1180 if (zbuffer[i] < zMin || zbuffer[i] > zMax)
1181 mask[i] = GL_FALSE;
1182 else
1183 anyPass = GL_TRUE;
1184 }
1185 }
1186 }
1187
1188 return anyPass;
1189 }
1190
1191
1192
1193 /**********************************************************************/
1194 /***** Read Depth Buffer *****/
1195 /**********************************************************************/
1196
1197
1198 /**
1199 * Read a span of depth values from the given depth renderbuffer, returning
1200 * the values as GLfloats.
1201 * This function does clipping to prevent reading outside the depth buffer's
1202 * bounds. Though the clipping is redundant when we're called from
1203 * _swrast_ReadPixels.
1204 */
1205 void
1206 _swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
1207 GLint n, GLint x, GLint y, GLfloat depth[] )
1208 {
1209 const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1210
1211 if (!rb) {
1212 /* really only doing this to prevent FP exceptions later */
1213 _mesa_bzero(depth, n * sizeof(GLfloat));
1214 }
1215
1216 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1217
1218 if (y < 0 || y >= (GLint) rb->Height ||
1219 x + n <= 0 || x >= (GLint) rb->Width) {
1220 /* span is completely outside framebuffer */
1221 _mesa_bzero(depth, n * sizeof(GLfloat));
1222 return;
1223 }
1224
1225 if (x < 0) {
1226 GLint dx = -x;
1227 GLint i;
1228 for (i = 0; i < dx; i++)
1229 depth[i] = 0.0;
1230 x = 0;
1231 n -= dx;
1232 depth += dx;
1233 }
1234 if (x + n > (GLint) rb->Width) {
1235 GLint dx = x + n - (GLint) rb->Width;
1236 GLint i;
1237 for (i = 0; i < dx; i++)
1238 depth[n - i - 1] = 0.0;
1239 n -= dx;
1240 }
1241 if (n <= 0) {
1242 return;
1243 }
1244
1245 if (rb->DataType == GL_UNSIGNED_INT) {
1246 GLuint temp[MAX_WIDTH];
1247 GLint i;
1248 rb->GetRow(ctx, rb, n, x, y, temp);
1249 for (i = 0; i < n; i++) {
1250 depth[i] = temp[i] * scale;
1251 }
1252 }
1253 else if (rb->DataType == GL_UNSIGNED_SHORT) {
1254 GLushort temp[MAX_WIDTH];
1255 GLint i;
1256 rb->GetRow(ctx, rb, n, x, y, temp);
1257 for (i = 0; i < n; i++) {
1258 depth[i] = temp[i] * scale;
1259 }
1260 }
1261 else {
1262 _mesa_problem(ctx, "Invalid depth renderbuffer data type");
1263 }
1264 }
1265
1266
1267 /**
1268 * As above, but return 32-bit GLuint values.
1269 */
1270 void
1271 _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb,
1272 GLint n, GLint x, GLint y, GLuint depth[] )
1273 {
1274 if (!rb) {
1275 /* really only doing this to prevent FP exceptions later */
1276 _mesa_bzero(depth, n * sizeof(GLfloat));
1277 }
1278
1279 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1280
1281 if (y < 0 || y >= (GLint) rb->Height ||
1282 x + n <= 0 || x >= (GLint) rb->Width) {
1283 /* span is completely outside framebuffer */
1284 _mesa_bzero(depth, n * sizeof(GLfloat));
1285 return;
1286 }
1287
1288 if (x < 0) {
1289 GLint dx = -x;
1290 GLint i;
1291 for (i = 0; i < dx; i++)
1292 depth[i] = 0;
1293 x = 0;
1294 n -= dx;
1295 depth += dx;
1296 }
1297 if (x + n > (GLint) rb->Width) {
1298 GLint dx = x + n - (GLint) rb->Width;
1299 GLint i;
1300 for (i = 0; i < dx; i++)
1301 depth[n - i - 1] = 0;
1302 n -= dx;
1303 }
1304 if (n <= 0) {
1305 return;
1306 }
1307
1308 if (rb->DataType == GL_UNSIGNED_INT) {
1309 rb->GetRow(ctx, rb, n, x, y, depth);
1310 if (rb->DepthBits < 32) {
1311 GLuint shift = 32 - rb->DepthBits;
1312 GLint i;
1313 for (i = 0; i < n; i++) {
1314 GLuint z = depth[i];
1315 depth[i] = z << shift; /* XXX lsb bits? */
1316 }
1317 }
1318 }
1319 else if (rb->DataType == GL_UNSIGNED_SHORT) {
1320 GLushort temp[MAX_WIDTH];
1321 GLint i;
1322 rb->GetRow(ctx, rb, n, x, y, temp);
1323 if (rb->DepthBits == 16) {
1324 for (i = 0; i < n; i++) {
1325 GLuint z = temp[i];
1326 depth[i] = (z << 16) | z;
1327 }
1328 }
1329 else {
1330 GLuint shift = 16 - rb->DepthBits;
1331 for (i = 0; i < n; i++) {
1332 GLuint z = temp[i];
1333 depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */
1334 }
1335 }
1336 }
1337 else {
1338 _mesa_problem(ctx, "Invalid depth renderbuffer data type");
1339 }
1340 }
1341
1342
1343
1344 /**
1345 * Clear the given z/depth renderbuffer.
1346 */
1347 void
1348 _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
1349 {
1350 GLuint clearValue;
1351 GLint x, y, width, height;
1352
1353 if (!rb || !ctx->Depth.Mask) {
1354 /* no depth buffer, or writing to it is disabled */
1355 return;
1356 }
1357
1358 /* compute integer clearing value */
1359 if (ctx->Depth.Clear == 1.0) {
1360 clearValue = ctx->DrawBuffer->_DepthMax;
1361 }
1362 else {
1363 clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
1364 }
1365
1366 assert(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1367
1368 /* compute region to clear */
1369 x = ctx->DrawBuffer->_Xmin;
1370 y = ctx->DrawBuffer->_Ymin;
1371 width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1372 height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1373
1374 if (rb->GetPointer(ctx, rb, 0, 0)) {
1375 /* Direct buffer access is possible. Either this is just malloc'd
1376 * memory, or perhaps the driver mmap'd the zbuffer memory.
1377 */
1378 if (rb->DataType == GL_UNSIGNED_SHORT) {
1379 if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) &&
1380 ((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width ==
1381 (GLushort *) rb->GetPointer(ctx, rb, 0, 1))) {
1382 /* optimized case */
1383 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y);
1384 GLuint len = width * height * sizeof(GLushort);
1385 _mesa_memset(dst, (clearValue & 0xff), len);
1386 }
1387 else {
1388 /* general case */
1389 GLint i, j;
1390 for (i = 0; i < height; i++) {
1391 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i);
1392 for (j = 0; j < width; j++) {
1393 dst[j] = clearValue;
1394 }
1395 }
1396 }
1397 }
1398 else {
1399 GLint i, j;
1400 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1401 for (i = 0; i < height; i++) {
1402 GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i);
1403 for (j = 0; j < width; j++) {
1404 dst[j] = clearValue;
1405 }
1406 }
1407 }
1408 }
1409 else {
1410 /* Direct access not possible. Use PutRow to write new values. */
1411 if (rb->DataType == GL_UNSIGNED_SHORT) {
1412 GLushort clearVal16 = (GLushort) (clearValue & 0xffff);
1413 GLint i;
1414 for (i = 0; i < height; i++) {
1415 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL);
1416 }
1417 }
1418 else if (rb->DataType == GL_UNSIGNED_INT) {
1419 GLint i;
1420 ASSERT(sizeof(clearValue) == sizeof(GLuint));
1421 for (i = 0; i < height; i++) {
1422 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL);
1423 }
1424 }
1425 else {
1426 _mesa_problem(ctx, "bad depth renderbuffer DataType");
1427 }
1428 }
1429 }